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.
This commit is contained in:
Adrian C. (anrxc) 2011-03-29 02:21:53 +02:00
parent 6522f58011
commit c2f7fbcf23
6 changed files with 122 additions and 46 deletions

10
README
View File

@ -166,12 +166,10 @@ vicious.widgets.fs
{/ avail_mb}, {/ avail_gb}, {/ avail_p}, {/home size_mb} etc. {/ avail_mb}, {/ avail_gb}, {/ avail_p}, {/home size_mb} etc.
vicious.widgets.dio vicious.widgets.dio
- provides I/O statistics for requested storage devices - provides I/O statistics for all available storage devices
- takes the disk as an argument, i.e. "sda" (or a specific - returns a table with string keys: {sda total_s}, {sda total_kb},
partition, i.e. "sda/sda2") {sda total_mb}, {sda read_s}, {sda read_kb}, {sda read_mb},
- returns a table with string keys: {total_s}, {total_kb}, {total_mb}, {sda write_s}, {sda write_kb}, {sda write_mb}, {sdb1 total_s} etc.
{read_s}, {read_kb}, {read_mb}, {write_s}, {write_kb}, {write_mb}
and {sched}
vicious.widgets.raid vicious.widgets.raid
- provides state information for a requested RAID array - provides state information for a requested RAID array

2
TODO
View File

@ -6,8 +6,6 @@
* Vicious * Vicious
** TODO Consider commiting power drain support to bat.lua ** 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 Document contrib widgets in contrib/README
** TODO Consider multigraph, graph stacking, support ** TODO Consider multigraph, graph stacking, support
** TODO Complete the hddtemp fix ** TODO Complete the hddtemp fix

View File

@ -27,6 +27,14 @@ vicious.contrib.batpmu
vicious.contrib.batproc 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 vicious.contrib.mpc
- -

72
contrib/dio.lua Normal file
View File

@ -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 })

View File

@ -9,6 +9,7 @@
require("vicious.contrib.batacpi") require("vicious.contrib.batacpi")
require("vicious.contrib.batpmu") require("vicious.contrib.batpmu")
require("vicious.contrib.batproc") require("vicious.contrib.batproc")
require("vicious.contrib.dio")
require("vicious.contrib.mpc") require("vicious.contrib.mpc")
require("vicious.contrib.netcfg") require("vicious.contrib.netcfg")
require("vicious.contrib.net") require("vicious.contrib.net")

View File

@ -1,14 +1,17 @@
--------------------------------------------------- ---------------------------------------------------
-- Licensed under the GNU General Public License v2 -- 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 -- {{{ Grab environment
local ipairs = ipairs local pairs = pairs
local io = { lines = io.lines }
local setmetatable = setmetatable local setmetatable = setmetatable
local table = { insert = table.insert }
local string = { gmatch = string.gmatch }
local helpers = require("vicious.helpers") local helpers = require("vicious.helpers")
local os = {
time = os.time,
difftime = os.difftime
}
-- }}} -- }}}
@ -18,54 +21,50 @@ module("vicious.widgets.dio")
-- Initialize function tables -- Initialize function tables
local disk_usage = {} local disk_usage = {}
local disk_total = {} local disk_stats = {}
-- Variable definitions local disk_time = 0
-- Constant definitions
local unit = { ["s"] = 1, ["kb"] = 2, ["mb"] = 2048 } local unit = { ["s"] = 1, ["kb"] = 2, ["mb"] = 2048 }
-- {{{ Disk I/O widget type -- {{{ Disk I/O widget type
local function worker(format, disk) local function worker(format)
if not disk then return end local disk_lines = {}
local disk_lines = { [disk] = {} } for line in io.lines("/proc/diskstats") do
local disk_stats = helpers.pathtotable("/sys/block/" .. disk) local device, read, write =
-- Linux kernel docs: Documentation/iostats.txt
if disk_stats.stat then line:match("([^%s]+) %d+ %d+ (%d+) %d+ %d+ %d+ (%d+)")
local match = string.gmatch(disk_stats.stat, "[%s]+([%d]+)") disk_lines[device] = { read, write }
for i = 1, 11 do -- Store disk stats
table.insert(disk_lines[disk], match())
end
end end
-- Ensure tables are initialized correctly local time = os.time()
local diff_total = { [disk] = {} } local interval = os.difftime(time, disk_time)
if not disk_total[disk] then if interval == 0 then interval = 1 end
disk_usage[disk] = {}
disk_total[disk] = {}
while #disk_total[disk] < #disk_lines[disk] do for device, stats in pairs(disk_lines) do
table.insert(disk_total[disk], 0) -- Avoid insane values on startup
local last_stats = disk_stats[device] or stats
-- 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
end
for i, v in ipairs(disk_lines[disk]) do
-- Diskstats are absolute, substract our last reading -- Diskstats are absolute, substract our last reading
diff_total[disk][i] = v - disk_total[disk][i] -- * 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
-- Store totals -- Calculate and store I/O
disk_total[disk][i] = v 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 end
-- Calculate and store I/O disk_time = time
helpers.uformat(disk_usage[disk], "read", diff_total[disk][3], unit) disk_stats = disk_lines
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 return disk_usage
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 end
-- }}} -- }}}