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.
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

2
TODO
View File

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

View File

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

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.batpmu")
require("vicious.contrib.batproc")
require("vicious.contrib.dio")
require("vicious.contrib.mpc")
require("vicious.contrib.netcfg")
require("vicious.contrib.net")

View File

@ -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 function worker(format)
local disk_lines = {}
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
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
while #disk_total[disk] < #disk_lines[disk] do
table.insert(disk_total[disk], 0)
end
for device, stats in pairs(disk_lines) do
-- 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
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
-- * 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[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]+)%]")
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
return disk_usage[disk]
disk_time = time
disk_stats = disk_lines
return disk_usage
end
-- }}}