Mercurial > prosody-modules
comparison mod_munin/mod_munin.lua @ 1624:0f20390f6fa5
mod_munin: Implementation of the Munin collection protocol
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Tue, 10 Mar 2015 16:39:08 +0100 |
| parents | |
| children | 648ce9087902 |
comparison
equal
deleted
inserted
replaced
| 1623:2c39af0fb93b | 1624:0f20390f6fa5 |
|---|---|
| 1 module:set_global(); | |
| 2 | |
| 3 local s_format = string.format; | |
| 4 local array = require"util.array"; | |
| 5 local it = require"util.iterators"; | |
| 6 local mt = require"util.multitable"; | |
| 7 local set = require"util.set"; | |
| 8 | |
| 9 local meta = mt.new(); meta.data = module:shared"meta"; | |
| 10 local data = mt.new(); data.data = module:shared"data"; | |
| 11 | |
| 12 local munin_listener = {}; | |
| 13 local munin_commands = {}; | |
| 14 | |
| 15 local node_name = module:get_option_string("munin_node_name", "localhost"); | |
| 16 local ignore_stats = module:get_option_set("munin_ignored_stats", { }); | |
| 17 | |
| 18 local function clean_fieldname(name) | |
| 19 return (name:gsub("[^A-Za-z0-9_]", "_"):gsub("^[^A-Za-z_]", "_%1")); | |
| 20 end | |
| 21 | |
| 22 function munin_listener.onconnect(conn) | |
| 23 -- require"core.statsmanager".collect(); | |
| 24 conn:write("# munin node at "..node_name.."\n"); | |
| 25 end | |
| 26 | |
| 27 function munin_listener.onincoming(conn, line) | |
| 28 line = line and line:match("^[^\r\n]+"); | |
| 29 if type(line) ~= "string" then return end | |
| 30 -- module:log("debug", "incoming: %q", line); | |
| 31 local command = line:match"^%w+"; | |
| 32 command = munin_commands[command]; | |
| 33 if not command then | |
| 34 conn:write("# Unknown command.\n"); | |
| 35 return; | |
| 36 end | |
| 37 local ok, err = pcall(command, conn, line); | |
| 38 if not ok then | |
| 39 module:log("error", "Error running %q: %s", line, err); | |
| 40 conn:close(); | |
| 41 end | |
| 42 end | |
| 43 | |
| 44 function munin_listener.ondisconnect() end | |
| 45 | |
| 46 function munin_commands.cap(conn) | |
| 47 conn:write("cap\n"); | |
| 48 end | |
| 49 | |
| 50 function munin_commands.list(conn, line) | |
| 51 conn:write(array(it.keys(data.data)):concat(" ") .. "\n"); | |
| 52 end | |
| 53 | |
| 54 function munin_commands.config(conn, line) | |
| 55 -- TODO what exactly? | |
| 56 local stat = line:match("%s(%S+)"); | |
| 57 if not stat then conn:write("# Unknown service\n.\n"); return end | |
| 58 for key, name, k, value in meta:iter(stat, "", nil) do | |
| 59 conn:write(s_format("%s %s\n", k, value)); | |
| 60 end | |
| 61 for key, name, k, value in meta:iter(stat, nil, nil) do | |
| 62 if name ~= "" then | |
| 63 conn:write(s_format("%s.%s %s\n", name, k, value)); | |
| 64 end | |
| 65 end | |
| 66 conn:write(".\n"); | |
| 67 end | |
| 68 | |
| 69 function munin_commands.fetch(conn, line) | |
| 70 local stat = line:match("%s(%S+)"); | |
| 71 if not stat then conn:write("# Unknown service\n.\n"); return end | |
| 72 for key, name, value in data:iter(stat, nil) do | |
| 73 conn:write(s_format("%s.value %s\n", name, tostring(value))); | |
| 74 end | |
| 75 conn:write(".\n"); | |
| 76 end | |
| 77 | |
| 78 function munin_commands.quit(conn) | |
| 79 conn:close(); | |
| 80 end | |
| 81 | |
| 82 module:hook("stats-updated", function (event) | |
| 83 local all_stats, this = event.stats_extra; | |
| 84 local host, sect, name, typ, key; | |
| 85 for stat, value in pairs(event.changed_stats) do | |
| 86 if not ignore_stats:contains(stat) then | |
| 87 this = all_stats[stat]; | |
| 88 -- module:log("debug", "changed_stats[%q] = %s", stat, tostring(value)); | |
| 89 host, sect, name, typ = stat:match("^/([^/]+)/([^/]+)/(.+):(%a+)$"); | |
| 90 if host == nil then | |
| 91 sect, name, typ, host = stat:match("^([^.]+)%.([^:]+):(%a+)$"); | |
| 92 elseif host == "*" then | |
| 93 host = nil; | |
| 94 end | |
| 95 key = clean_fieldname(s_format("%s_%s_%s", host or "global", sect, typ)); | |
| 96 | |
| 97 if not meta:get(key) then | |
| 98 if host then | |
| 99 meta:set(key, "", "graph_title", s_format("%s %s on %s", sect, typ, host)); | |
| 100 else | |
| 101 meta:set(key, "", "graph_title", s_format("Global %s %s", sect, typ, host)); | |
| 102 end | |
| 103 meta:set(key, "", "graph_vlabel", this and this.units or typ); | |
| 104 meta:set(key, "", "graph_category", sect); | |
| 105 | |
| 106 meta:set(key, name, "label", name); | |
| 107 elseif not meta:get(key, name, "label") then | |
| 108 meta:set(key, name, "label", name); | |
| 109 end | |
| 110 | |
| 111 data:set(key, name, value); | |
| 112 else | |
| 113 -- module:log("debug", "Ignoring stat %q", stat); | |
| 114 end | |
| 115 end | |
| 116 end); | |
| 117 | |
| 118 module:provides("net", { | |
| 119 listener = munin_listener; | |
| 120 default_mode = "*l"; | |
| 121 default_port = 4949; | |
| 122 }); | |
| 123 |
