aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian C. (anrxc) <anrxc@sysphere.org>2011-03-29 02:21:53 +0200
committerAdrian C. (anrxc) <anrxc@sysphere.org>2011-03-29 02:21:53 +0200
commitc2f7fbcf2358cf83b103954ec0dc579aea39e3cb (patch)
treeecc4ad88c3e28f6e3307d1c6425adfad439ca19a
parent6522f580110e25c5f030c65f830fda430ccc0f47 (diff)
downloadvicious-legacy-c2f7fbcf2358cf83b103954ec0dc579aea39e3cb.tar.xz
dio: provide stats for all devices, rewritten by Joerg
Old dio.lua was moved to contrib. New one is used like CPU widget is, request the device or parition in the format argument, {sda read_mb} as an example. New widget doesn't provide scheduler information, but I don't know anyone who used that. If you think this is wrong let me know.
-rw-r--r--README10
-rw-r--r--TODO2
-rw-r--r--contrib/README8
-rw-r--r--contrib/dio.lua72
-rw-r--r--contrib/init.lua1
-rw-r--r--widgets/dio.lua79
6 files changed, 124 insertions, 48 deletions
diff --git a/README b/README
index ef7d666..8f3b877 100644
--- a/README
+++ b/README
@@ -166,12 +166,10 @@ vicious.widgets.fs
{/ avail_mb}, {/ avail_gb}, {/ avail_p}, {/home size_mb} etc.
vicious.widgets.dio
- - provides I/O statistics for requested storage devices
- - takes the disk as an argument, i.e. "sda" (or a specific
- partition, i.e. "sda/sda2")
- - returns a table with string keys: {total_s}, {total_kb}, {total_mb},
- {read_s}, {read_kb}, {read_mb}, {write_s}, {write_kb}, {write_mb}
- and {sched}
+ - provides I/O statistics for all available storage devices
+ - returns a table with string keys: {sda total_s}, {sda total_kb},
+ {sda total_mb}, {sda read_s}, {sda read_kb}, {sda read_mb},
+ {sda write_s}, {sda write_kb}, {sda write_mb}, {sdb1 total_s} etc.
vicious.widgets.raid
- provides state information for a requested RAID array
diff --git a/TODO b/TODO
index 5c125f0..5572be5 100644
--- a/TODO
+++ b/TODO
@@ -6,8 +6,6 @@
* Vicious
** TODO Consider commiting power drain support to bat.lua
-** TODO Try replacing dio.lua with io.lua
-*** TODO First io.lua should grab data for all devices
** TODO Document contrib widgets in contrib/README
** TODO Consider multigraph, graph stacking, support
** TODO Complete the hddtemp fix
diff --git a/contrib/README b/contrib/README
index 20b000e..16716ac 100644
--- a/contrib/README
+++ b/contrib/README
@@ -27,6 +27,14 @@ vicious.contrib.batpmu
vicious.contrib.batproc
-
+vicious.contrib.dio
+ - provides I/O statistics for requested storage devices
+ - takes the disk as an argument, i.e. "sda" (or a specific
+ partition, i.e. "sda/sda2")
+ - returns a table with string keys: {total_s}, {total_kb}, {total_mb},
+ {read_s}, {read_kb}, {read_mb}, {write_s}, {write_kb}, {write_mb}
+ and {sched}
+
vicious.contrib.mpc
-
diff --git a/contrib/dio.lua b/contrib/dio.lua
new file mode 100644
index 0000000..40c4cad
--- /dev/null
+++ b/contrib/dio.lua
@@ -0,0 +1,72 @@
+---------------------------------------------------
+-- Licensed under the GNU General Public License v2
+-- * (c) 2010, Adrian C. <anrxc@sysphere.org>
+---------------------------------------------------
+
+-- {{{ Grab environment
+local ipairs = ipairs
+local setmetatable = setmetatable
+local table = { insert = table.insert }
+local string = { gmatch = string.gmatch }
+local helpers = require("vicious.helpers")
+-- }}}
+
+
+-- Disk I/O: provides I/O statistics for requested storage devices
+module("vicious.contrib.dio")
+
+
+-- Initialize function tables
+local disk_usage = {}
+local disk_total = {}
+-- Variable definitions
+local unit = { ["s"] = 1, ["kb"] = 2, ["mb"] = 2048 }
+
+-- {{{ Disk I/O widget type
+local function worker(format, disk)
+ if not disk then return end
+
+ local disk_lines = { [disk] = {} }
+ local disk_stats = helpers.pathtotable("/sys/block/" .. disk)
+
+ if disk_stats.stat then
+ local match = string.gmatch(disk_stats.stat, "[%s]+([%d]+)")
+ for i = 1, 11 do -- Store disk stats
+ table.insert(disk_lines[disk], match())
+ end
+ end
+
+ -- Ensure tables are initialized correctly
+ local diff_total = { [disk] = {} }
+ if not disk_total[disk] then
+ disk_usage[disk] = {}
+ disk_total[disk] = {}
+
+ while #disk_total[disk] < #disk_lines[disk] do
+ table.insert(disk_total[disk], 0)
+ end
+ end
+
+ for i, v in ipairs(disk_lines[disk]) do
+ -- Diskstats are absolute, substract our last reading
+ diff_total[disk][i] = v - disk_total[disk][i]
+
+ -- Store totals
+ disk_total[disk][i] = v
+ end
+
+ -- Calculate and store I/O
+ helpers.uformat(disk_usage[disk], "read", diff_total[disk][3], unit)
+ helpers.uformat(disk_usage[disk], "write", diff_total[disk][7], unit)
+ helpers.uformat(disk_usage[disk], "total", diff_total[disk][7] + diff_total[disk][3], unit)
+
+ -- Store I/O scheduler
+ if disk_stats.queue and disk_stats.queue.scheduler then
+ disk_usage[disk]["{sched}"] = string.gmatch(disk_stats.queue.scheduler, "%[([%a]+)%]")
+ end
+
+ return disk_usage[disk]
+end
+-- }}}
+
+setmetatable(_M, { __call = function(_, ...) return worker(...) end })
diff --git a/contrib/init.lua b/contrib/init.lua
index e0f681a..a8c5ee6 100644
--- a/contrib/init.lua
+++ b/contrib/init.lua
@@ -9,6 +9,7 @@
require("vicious.contrib.batacpi")
require("vicious.contrib.batpmu")
require("vicious.contrib.batproc")
+require("vicious.contrib.dio")
require("vicious.contrib.mpc")
require("vicious.contrib.netcfg")
require("vicious.contrib.net")
diff --git a/widgets/dio.lua b/widgets/dio.lua
index edf4638..db6ba39 100644
--- a/widgets/dio.lua
+++ b/widgets/dio.lua
@@ -1,14 +1,17 @@
---------------------------------------------------
-- Licensed under the GNU General Public License v2
--- * (c) 2010, Adrian C. <anrxc@sysphere.org>
+-- * (c) 2011, Jörg T. <jthalheim@gmail.com>
---------------------------------------------------
-- {{{ Grab environment
-local ipairs = ipairs
+local pairs = pairs
+local io = { lines = io.lines }
local setmetatable = setmetatable
-local table = { insert = table.insert }
-local string = { gmatch = string.gmatch }
local helpers = require("vicious.helpers")
+local os = {
+ time = os.time,
+ difftime = os.difftime
+}
-- }}}
@@ -18,54 +21,50 @@ module("vicious.widgets.dio")
-- Initialize function tables
local disk_usage = {}
-local disk_total = {}
--- Variable definitions
+local disk_stats = {}
+local disk_time = 0
+-- Constant definitions
local unit = { ["s"] = 1, ["kb"] = 2, ["mb"] = 2048 }
-- {{{ Disk I/O widget type
-local function worker(format, disk)
- if not disk then return end
-
- local disk_lines = { [disk] = {} }
- local disk_stats = helpers.pathtotable("/sys/block/" .. disk)
-
- if disk_stats.stat then
- local match = string.gmatch(disk_stats.stat, "[%s]+([%d]+)")
- for i = 1, 11 do -- Store disk stats
- table.insert(disk_lines[disk], match())
- end
+local function worker(format)
+ local disk_lines = {}
+
+ for line in io.lines("/proc/diskstats") do
+ local device, read, write =
+ -- Linux kernel docs: Documentation/iostats.txt
+ line:match("([^%s]+) %d+ %d+ (%d+) %d+ %d+ %d+ (%d+)")
+ disk_lines[device] = { read, write }
end
- -- Ensure tables are initialized correctly
- local diff_total = { [disk] = {} }
- if not disk_total[disk] then
- disk_usage[disk] = {}
- disk_total[disk] = {}
+ local time = os.time()
+ local interval = os.difftime(time, disk_time)
+ if interval == 0 then interval = 1 end
+
+ for device, stats in pairs(disk_lines) do
+ -- Avoid insane values on startup
+ local last_stats = disk_stats[device] or stats
- while #disk_total[disk] < #disk_lines[disk] do
- table.insert(disk_total[disk], 0)
+ -- Check for overflows and counter resets (> 2^32)
+ if stats[1] < last_stats[1] or stats[2] < last_stats[2] then
+ last_stats[1], last_stats[2] = stats[1], stats[2]
end
- end
- for i, v in ipairs(disk_lines[disk]) do
-- Diskstats are absolute, substract our last reading
- diff_total[disk][i] = v - disk_total[disk][i]
-
- -- Store totals
- disk_total[disk][i] = v
+ -- * divide by timediff because we don't know the timer value
+ local read = (stats[1] - last_stats[1]) / interval
+ local write = (stats[2] - last_stats[2]) / interval
+
+ -- Calculate and store I/O
+ helpers.uformat(disk_usage, device.." read", read, unit)
+ helpers.uformat(disk_usage, device.." write", write, unit)
+ helpers.uformat(disk_usage, device.." total", read + write, unit)
end
- -- Calculate and store I/O
- helpers.uformat(disk_usage[disk], "read", diff_total[disk][3], unit)
- helpers.uformat(disk_usage[disk], "write", diff_total[disk][7], unit)
- helpers.uformat(disk_usage[disk], "total", diff_total[disk][7] + diff_total[disk][3], unit)
-
- -- Store I/O scheduler
- if disk_stats.queue and disk_stats.queue.scheduler then
- disk_usage[disk]["{sched}"] = string.gmatch(disk_stats.queue.scheduler, "%[([%a]+)%]")
- end
+ disk_time = time
+ disk_stats = disk_lines
- return disk_usage[disk]
+ return disk_usage
end
-- }}}