1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
-- filename : statusd_sysmon.lua
-- version : 2.0
-- date : 2005-03-29
--
-- system monitor for Ion3 WM statusbar
-- Written by Vladimir Chizhov < jagoterr *at* gmail *dot* com >
-- I'll apreciate any comments, bug reports and feature requests :)
--
-- Shows memory, swap and filesystem statistics, based on 'free' and 'df' commands output.
-- Allows lua-expression evaluation with the values.
--
-- This script can work not only as a Ion3 statusd monitor, but also as a standalone script.
-- If it works as a Ion statusd monitor, it reads user settings from statusd.
local defaults = {
-- UPDATE INTERVAL
--
interval=10*1000,
-- TEMPLATE STRING
--
-- COMMON:
-- %% - percents symbol (%)
-- ${expression} - evaluates lua expression
-- Shortly about expressions:
-- - may contain all macroses (of format %macros_name or
-- %{macros_name macros_params*})
-- - may contain global function calls
-- - may contain arithmetic, logical operations etc.
-- - there is a global function 'dpr' defined in this script
-- for decreasing double numbers' precision (see this
-- function comments for more information and the example templates)
--
-- RAM:
-- %mem_total - total available memory
-- %mem_used - used memory
-- %mem_free - free memory
-- %mem_buffers - buffered memory
-- %mem_cached - cached memory
-- %mem_shared - shared memory
--
-- SWAP:
-- %swap_total - total available swap space
-- %swap_used - used swap space
-- %swap_free - free swap space
--
-- FS (FileSystem):
-- %{fs_total mount_point} - total available space on filesystem
-- %{fs_used mount_point} - used space on filesystem
-- %{fs_free mount_point} - free space on filesystem
--
-- TEMPLATE EXAMPLES:
--
-- simple swap statistics
-- template = "swap used %swap_used of %swap_total"
--
-- used swap in percents with one sign after comma!
-- how? so... try to understand, I think it's not very hard, if you read the previous comments
-- template = "swap used by ${dpr (%swap_used / %swap_total * 100)}%%"
--
-- RAM used, excluding buffers and cached memory
-- template = "RAM used: ${%mem_used - %mem_buffers - %mem_cached}"
--
-- root filesystem simple info
-- note, that you should specify the actual mount point for filesystem, accordingly to /etc/mtab
-- template = "/ used by %{fs_used /} of %{fs_total /}"
--
-- DEFAULT TEMPLATE:
--
template = "RAM: %mem_used / %mem_total MB (${dpr (%mem_used / %mem_total * 100, 1)} %%) * SWAP: %swap_used / %swap_total MB (${dpr (%swap_used / %swap_total * 100, 1)} %%) * /: %{fs_used /} / %{fs_total /} (${dpr (%{fs_used /} / %{fs_total /} * 100, 1)} %%)",
-- DIMENSION for monitors
--
-- b - bytes
-- k - kilobytes
-- m - megabytes
-- g - gigabytes
--
-- dimension for RAM and SWAP
--
mem_dimension = "m",
-- dimension for filesystems
--
fs_dimension = "g",
}
local settings
if statusd ~= nil then
settings = table.join (statusd.get_config ("sysmon"), defaults)
else
settings = defaults
end
local factors = {
b = 1,
k = 1024,
m = 1024^2,
g = 1024^3,
}
local metrics = {}
-- --------------------------------------------------------------------------
-- Decreases the precision of the floating number
-- @param number the number to decrease it's precision
-- @param signs_q the quantity of signs after the comma to be left
function dpr (number, signs_q)
local pattern = "%d+"
if signs_q == nil then
signs_q = 2
end
if signs_q ~= 0 then
pattern = pattern.."%."
end
for i = 1, tonumber (signs_q) do
pattern = pattern.."%d"
end
return string.gsub (number, "("..pattern..")(.*)", "%1")
end
-- --------------------------------------------------------------------------
-- Retrieves information from 'free' command output
local function parse_free_command ()
local f = io.popen ('free -'..settings.mem_dimension, 'r')
local s = f:read('*a')
f:close()
local st, en
st, en,
metrics.mem_total,
metrics.mem_used,
metrics.mem_free,
metrics.mem_shared,
metrics.mem_buffers,
metrics.mem_cached
= string.find(s, 'Mem:%s*(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)')
st, en,
metrics.swap_total,
metrics.swap_used,
metrics.swap_free
= string.find(s, 'Swap:%s*(%d+)%s+(%d+)%s+(%d+)')
end
-- --------------------------------------------------------------------------
-- Retrieves information from 'df' command output
local function parse_df_command ()
local factor = factors[settings.fs_dimension]
local f = io.popen ('df --block-size=1 -P | tail +2', 'r')
-- local s = f:read ("*l")
for line in f:lines () do
local st, en, fs, total, used, free, mount_point =
string.find (line, '(%S+)%s+(%d+)%s+(%d+)%s+(%d+)%s+[%-%d]-%%?%s+(.*)')
if fs ~= nil then
metrics["fs_total->"..mount_point] = string.gsub (total / factor, '(%d+%.%d%d)(.*)', "%1")
metrics["fs_used->"..mount_point] = string.gsub (used / factor, '(%d+%.%d%d)(.*)', "%1")
metrics["fs_free->"..mount_point] = string.gsub (free / factor, '(%d+%.%d%d)(.*)', "%1")
end
end
f:close ()
end
local sysmon_timer
-- --------------------------------------------------------------------------
-- Main calculating of values, template parsing and Ion statusd updating
local function update_sysmon ()
local sysmon_st = settings.template
parse_free_command ()
parse_df_command ()
-- filling the template by actual values
sysmon_st = string.gsub (sysmon_st, "%%%{([%w%_]+)%s+(%S-)%}", function (arg1, arg2)
return metrics[arg1.."->"..arg2]
end)
sysmon_st = string.gsub (sysmon_st, "%%([%w%_]+)", function (arg1)
return metrics[arg1]
end)
sysmon_st = string.gsub (sysmon_st, "%$%{(.-)%}", function (arg1)
return loadstring ("return "..arg1) ()
end)
-- replacing the '%%' macros with the '%' symbol
sysmon_st = string.gsub (sysmon_st, "%%%%", "%%")
if statusd ~= nil then
statusd.inform ("sysmon_template", sysmon_st)
statusd.inform ("sysmon", sysmon_st)
sysmon_timer:set (settings.interval, update_sysmon)
else
io.stdout:write (sysmon_st.."\n")
end
end
-- --------------------------------------------------------------------------
-- Init
if statusd ~= nil then
sysmon_timer = statusd.create_timer ()
end
update_sysmon ()
|