require "luarocks.require" require "md5" require "lfs" home = os.getenv( "HOME" ) os.execute("mkdir -p " .. home .. "/.conky/requests"); os.execute("mkdir -p " .. home .. "/.conky/info"); c_timer_init = -1 do function conky_eval(...) return conky_parse(table.concat(arg, " ")) end function conky_multiply_line(times, ...) local str = table.concat(arg, " ") local tbl = {} for i=1,times,1 do tbl[i] = string.gsub(str,"@i@", i-1) end local res = table.concat(tbl,"\n") return res; end function split(delimiter, text) local list = {} local pos = 1 if string.find("", delimiter, 1) then -- this would result in endless loops error("delimiter matches empty string!") end while 1 do local first, last = string.find(text, delimiter, pos) if first then -- found? table.insert(list, string.sub(text, pos, first-1)) pos = last+1 else table.insert(list, string.sub(text, pos)) break end end return list end function conky_filter_real_ip(iface) local req = string.format('${addrs %s}', iface) local ips = conky_parse(req); --[[ print(ips) --]] local list = split(",", ips) for i, item in ipairs(list) do if (string.match(item, "141\.52\.64")) then return item end end return "Unknown" end user = split('/', home) user = user[#user] result_check_server_status = {} result_check_adei_source = {} result_check_server_ = {} result_check_service_ = {} online = {} status = {} tested = {} c_timer = c_timer_init width = 80 update_time = 0 outdate_time = 0 timeout = 2 function conky_set_width (w) width = tonumber(w) return "" end function conky_set_timeout (t) timeout = tonumber(t) return "" end function cmd_popen(server, port, cmd) if (c_timer_init == 0) then return io.popen(cmd) else local cmd_md5 = md5.sumhexa(cmd) local fn = string.format("%s/.conky/info/%s:%s-%s.srv", home, server, port, cmd_md5) stat = lfs.attributes(fn) if (stat == nil) then return nil end local since = os.difftime(stat['modification'], update_time) if (since < 0) then return nil end since = os.difftime(outdate_time, os.time()) if (since < 0) then return nil end return io.open(fn, "r") end end function conky_check_server_status(server, port, ...) port = port or 22 local name = string.format("%s:%i", server, port); if (c_timer < 0) then if (c_timer == -1) then local fn = string.format("%s/.conky/requests/%s:%i.srv", home, server, port) tested[string.format("%s:%i", server, port)] = false; local f = assert(io.open(fn, "w")) local cmd = string.format("/etc/conky/scripts/ping.pl %s:%i %i", server, port, timeout) f:write(cmd .. "\n") if (arg[1] ~= "-") then cmd = string.format("ssh -x -p %i -o ConnectTimeout=%i root@%s /opt/scripts/check_server_status.sh 2>&1 | fold -w %i", port, timeout, server, width) f:write(cmd .. "\n") for i, service in ipairs(arg) do cmd = string.format("ssh -x -p %i -o ConnectTimeout=%i root@%s /opt/scripts/check_%s_status.sh 2>&1 | fold -w %i", port, timeout, server, service, width) f:write(cmd .. "\n") end end f:close() end if (result_check_server_status[name] == nil) then local res if (math.abs(c_timer)%2 > 0) then res = "${color yellow}?${color}" else res = "${color yellow}.${color}" end if (arg[1] ~= "-") then res = res .. " " for i, service in ipairs(arg) do res = res .. " " end end --result_check_server_status[server] = res --status[server] = false return res end elseif (c_timer == 0) then result_check_server_status[name] = check_server_status(server, port, arg) end return result_check_server_status[name]; end function check_server_status(server, port, additional) port = port or 22 local res local cmd = string.format("/etc/conky/scripts/ping.pl %s:%i %i", server, port, timeout) local cmdf = cmd_popen(server, port, cmd) if (cmdf == nil) then res = -1 else local data = cmdf:read("*a") res = tonumber(data) cmdf:close() end if (additional[1] == "-") then if (res > 0) then online[server] = true return "${color green}*" elseif (res < 0) then return "${color red}?" else online[server] = false return "${color red}*" end end if (res > 0) then online[server] = true local output cmd = string.format("ssh -x -p %i -o ConnectTimeout=%i root@%s /opt/scripts/check_server_status.sh 2>&1 | fold -w %i", port, timeout, server, width) cmdf = cmd_popen(server, port, cmd) if (cmdf == nil) then output = string.format("${color green}* ${color red}?") else local res = {} local line = cmdf:read("*l") while line do local m1 = string.match(line, "^\(.*[^%s]\)%s*$") if (m1) then table.insert(res, m1) end line = cmdf:read("*l") end -- res = cmdf:read("*a") cmdf:close() res = table.concat(res, "\n") if (string.match(res, "[%a%d]")) then table.insert(status, string.format("${color yellow}%s:%i${color gray}\n%s", server, port, res)) output = string.format("${color green}* ${color red}*") else output = string.format("${color green}* *") end end for i, service in ipairs(additional) do cmd = string.format("ssh -x -p %i -o ConnectTimeout=%i root@%s /opt/scripts/check_%s_status.sh 2>&1 | fold -w %i", port, timeout, server, service, width) cmdf = cmd_popen(server, port, cmd) if (cmdf == nil) then output = output .. string.format(" ${color red}?") else local res = {} local line = cmdf:read("*l") while line do local m1 = string.match(line, "^\(.*[^%s]\)%s*$") if (m1) then table.insert(res, m1) end line = cmdf:read("*l") end cmdf:close() if (res[1]) then local info = table.remove(res) local s = 0 local extra = "" local m1, m2 = string.match(info, "^\(%d+\)\(%s.+\)$") if (m1 == nil) then m1 = string.match(info, "^\%d+$"); end if (m1 == nil) then table.insert(res, info) else s = tonumber(m1) if (m2 ~= nil) then extra = string.sub(m2,2) end end if (res[1]) then res = table.concat(res, "\n") table.insert(status, string.format("${color yellow}%s:%i:%s${color gray}\n%s", server, port, service, res)) end if (s == 0) then output = output .. string.format(" ${color red}*") elseif (s == 1) then output = output .. string.format(" ${color green}*") else output = output .. string.format(" ${color yellow}*") end output=output .. " ${color white}" .. extra; else output = output .. string.format(" ${color green}*") end end end return output else if (res < 0) then res = string.format("${color red}? ") else online[server] = false res = string.format("${color red}* ") end for i, service in ipairs(additional) do res = res .. " " end return res end end function conky_check_adei_source(server, port, config, setup, db_server, db_name, ignore_list) port = port or 22 local name = string.format("%s:%i__%s__%s", server, port, db_server, db_name) if (c_timer < 0) then if (c_timer == -1) then ignore_list = ignore_list or "" local fn = string.format("%s/.conky/requests/%s:%i.srv", home, server, port) local f = assert(io.open(fn, "a+")) local cmd = string.format('ssh -x -p %i -o ConnectTimeout=%i root@%s /opt/scripts/check_adei_source.sh %s %s %s %s "%s" 2>&1', port, timeout, server, config, setup, db_server, db_name, ignore_list) f:write(cmd .. "\n") f:close() end if (result_check_adei_source[name] == nil) then return "${color yellow}?${color}" else if (online[server]) then return result_check_adei_source[name]; else return "${color red}?${color}" end end elseif (online[server]) then if (c_timer == 0) then result_check_adei_source[name] = check_adei_source(server, port, config, setup, db_server, db_name, ignore_list) end return result_check_adei_source[name]; else return "${color red}?${color}" end end function check_adei_source(server, port, config, setup, db_server, db_name, ignore_list) ignore_list = ignore_list or "" cmd = string.format('ssh -x -p %i -o ConnectTimeout=%i root@%s /opt/scripts/check_adei_source.sh %s %s %s %s "%s" 2>&1', port, timeout, server, config, setup, db_server, db_name, ignore_list) cmdf = cmd_popen(server, port, cmd) if (cmdf == nil) then return "${color red}?" end local res = {} line = cmdf:read("*l") while line do local m1 = string.match(line, "^\(.*[^%s]\)%s*$") if (m1) then table.insert(res, m1) end line = cmdf:read("*l") end cmdf:close() local info = table.remove(res) local t1, t2, t3 = string.match(info, "^\(%d+\)%s+\(%d+\)%s+\(%d+\)") local s = tonumber(t1) if (s == nil) then table.insert(res, info) s = 0 end res = table.concat(res, "\n") local output if (s == 1) then output="${color green}*" else --[[ table.insert(status, string.format("${color yellow}%s -- %s${color gray}\n%s\n", db_server, db_name, res)) --]] if (s == 0) then output="${color red}*" else output="${color yellow}*" end end -- if (s ~= 0) then local groups = tonumber(t2) if (groups) then output = output .. string.format("${color white} %i groups", groups); else output = output .. string.format("${color red} ? groups"); end local size = tonumber(t3) if (groups and size) then output = output .. string.format("${color white}, %i GB", size); else output = output .. string.format("${color red}, ? GB"); end -- end if (string.match(res, "[%a%d]")) then output = output .. "${color gray}\n ${font Bitstream Vera Sans Mono:size=7}" .. string.gsub(res,"\n", "${font}\n ${font Bitstream Vera Sans Mono:size=7}") .. "${font}${color white}" end return output end function conky_check_server_(service, server, port, ...) port = port or 22 local name = string.format("%s:%i:%s", server, port, service) if (c_timer < 0) then if (c_timer == -1) then ignore_list = ignore_list or "" local fn = string.format("%s/.conky/requests/%s:%i.srv", home, server, port) local f = assert(io.open(fn, "a+")) local cmd = string.format("ssh -x -p %i -o ConnectTimeout=%i root@%s /opt/scripts/check_server_%s.sh 2>&1", port, timeout, server, service) f:write(cmd .. "\n") f:close() end if (result_check_server_[name] == nil) then return "${color yellow}?${color}" else if (online[server]) then return result_check_server_[name]; else return "${color red}?${color}" end end elseif (online[server]) then if (c_timer == 0) then result_check_server_[name] = check_server_(service, server, port, arg) end return result_check_server_[name]; else return "${color red}?${color}" end end function conky_check_service_(service, id, ...) local name = string.format("%s:%s", service, id) if (c_timer < 0) then if (c_timer == -1) then ignore_list = ignore_list or "" tested[string.format("%s:%s", service, id)] = false; local fn = string.format("%s/.conky/requests/%s:%s.srv", home, service, id) local f = assert(io.open(fn, "a+")) local cmd = string.format("/etc/conky/service/check_%s.sh %s %s 2>&1", service, id, table.concat(arg, " ")) f:write(cmd .. "\n") f:close() end if (result_check_server_[name] == nil) then return "${color yellow}?${color}" else return result_check_server_[name]; end else if (c_timer == 0) then result_check_server_[name] = check_service_(service, id, arg) end return result_check_server_[name]; end end function format_traffic(value, yellow, red) yellow = yellow or 100 red = red or 1000 local value = math.floor(tonumber(value) / 1073741824) local res if (value > red) then res="${color red}" elseif (value > yellow) then res="${color yellow}" else res="${color white}" end if (value < 10) then res = res .. " " .. value elseif (value < 100) then res = res .. " " .. value else res = res .. value end return res .. " GB${color gray}" end function check_server_(service, server, port, opts) port = port or 22 local cmd = string.format("ssh -x -p %i -o ConnectTimeout=%i root@%s /opt/scripts/check_server_%s.sh 2>&1", port, timeout, server, service) cmdf = cmd_popen(server, port, cmd) if (cmdf == nil) then return "${color red}?" end local res = {} line = cmdf:read("*l") while line do local m1 = string.match(line, "^\(.*[^%s]\)%s*$") if (m1) then table.insert(res, m1) end line = cmdf:read("*l") end cmdf:close() if (service == "traffic") then if (res[1]) then local t1, t2, t3 = string.match(res[1], "^\(%d+\)%s+\(%d+\)%s+\(%d+\)") if (t1 and t2 and t3) then if ((opts) and (opts[1])) then yellow = tonumber(opts[1]) else yellow = nil end if ((opts) and (opts[2])) then red = tonumber(opts[2]) else red = nil end t1=format_traffic(t1,yellow,red) t2=format_traffic(t2,yellow,red) t3=format_traffic(t3,yellow,red) return string.format("${color gray}i: %s, o: %s, f: %s", t1, t2, t3) else return "${color red}" .. res[1] end end end return "" end function check_service_(service, id, opts) local cmd = string.format("/etc/conky/service/check_%s.sh %s %s 2>&1", service, id, table.concat(opts, " ")) cmdf = cmd_popen(service, id, cmd) if (cmdf == nil) then return "${color red}?" end local res = {} local local_res = {} line = cmdf:read("*l") while line do local t, m1 = string.match(line, "^\(\*?\)\(.*[^%s]\)%s*$") if (m1) then if (t == nil) or (t == '') then table.insert(res, m1) else table.insert(local_res, string.sub(m1,1)) end end line = cmdf:read("*l") end cmdf:close() local output local info = table.remove(res) local t1 = 0 local t2 = nil local msg = '' if (info) then t1, t2, msg = string.match(info, "^\(%d+\)%s+\(%d+\)\(.*\)") end local s = tonumber(t1) if (s == nil) then table.insert(res, info) s = 0 end if (s == 1) then output="${color green}*" else if (s == 0) then output="${color red}*" else output="${color yellow}*" end end s = tonumber(t2) if (s == nil) then s = 0 else if (s == 1) then output=output .. " ${color green}*" else if (s == 0) then output=output .. " ${color red}*" else output=output .. " ${color yellow}*" end end end output = output .. " ${color white}" .. msg res = table.concat(res, "\n") local_res = table.concat(local_res, "\n") if (string.match(res, "[%a%d]")) then table.insert(status, string.format("${color yellow}%s:%s${color gray}\n%s", service, id, res)) end if (string.match(local_res, "[%a%d]")) then output = output .. "${color gray}\n ${font Bitstream Vera Sans Mono:size=7}" .. string.gsub(local_res,"\n", "${font}\n ${font Bitstream Vera Sans Mono:size=7}") .. "${font}${color white}" end return output end function conky_print_server_errors(interval, tag) local res = table.concat(status, "\n") if (c_timer < 0) then tag = user .. "_" .. tag if (c_timer == -1) then update_time = os.time() local result = 0; while (result == 0) do result = os.execute("ps x | grep conky_process_requests | grep " .. tag .. " | grep -v grep > /dev/null") end for item, s in pairs(tested) do os.execute("/etc/conky/scripts/conky_process_requests.pl \"" .. item .. ".srv\" " .. tag .. " &") end end local result=os.execute("ps x | grep conky_process_requests | grep " .. tag .. " | grep -v grep > /dev/null") if (result == 0) then c_timer = c_timer - 1; local since = os.difftime(os.time(), update_time) if (since > tonumber(interval)) then result_check_server_status = {} result_check_adei_source = {} result_check_server_ = {} end else outdate_time = os.time() + 2 * tonumber(interval) c_timer = 0 end return "" else c_timer = c_timer + conky_info.update_interval if (c_timer > tonumber(interval)) then status = {} tested = {} c_timer = c_timer_init end end if (string.match(res, "[%a%d]")) then return string.format("\n\n%s", res) else return "" end end function conky_outcon(pos1, pos2) local n = tonumber(conky_parse('${tcp_portmon 32768 65535 count}')) local res = {} local str = "" for i=1,n do local val = tostring(conky_parse(string.format('${tcp_portmon 32768 65535 rhost %i}:${tcp_portmon 32768 65535 rport %i}',i - 1,i - 1))) if (res[val] == nil) then res[val] = 1 else res[val] = res[val] + 1 end end local names = {} for addr,num in pairs(res) do table.insert(names, addr) end table.sort(names, function(a,b) return res[a]>res[b] end) for i=1,#names do local name = names[i] str = str .. string.format("${goto %i}%s${goto %i}cnt %3i\n",pos1,name,pos2,res[name]) end return str end end