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