217 lines
6.1 KiB
Nix
217 lines
6.1 KiB
Nix
|
{ config, pkgs, ... }:
|
||
|
|
||
|
# TODO: support munin-async
|
||
|
# TODO: LWP/Pg perl libs aren't recognized
|
||
|
|
||
|
# TODO: support fastcgi
|
||
|
# http://munin-monitoring.org/wiki/CgiHowto2
|
||
|
# spawn-fcgi -s /var/run/munin/fastcgi-graph.sock -U www-data -u munin -g munin /usr/lib/munin/cgi/munin-cgi-graph
|
||
|
# spawn-fcgi -s /var/run/munin/fastcgi-html.sock -U www-data -u munin -g munin /usr/lib/munin/cgi/munin-cgi-html
|
||
|
# https://paste.sh/vofcctHP#-KbDSXVeWoifYncZmLfZzgum
|
||
|
# nginx http://munin.readthedocs.org/en/latest/example/webserver/nginx.html
|
||
|
|
||
|
|
||
|
with pkgs.lib;
|
||
|
|
||
|
let
|
||
|
nodeCfg = config.services.munin-node;
|
||
|
cronCfg = config.services.munin-cron;
|
||
|
|
||
|
muninPlugins = pkgs.stdenv.mkDerivation {
|
||
|
name = "munin-available-plugins";
|
||
|
buildCommand = ''
|
||
|
mkdir -p $out
|
||
|
|
||
|
cp --preserve=mode ${pkgs.munin}/lib/plugins/* $out/
|
||
|
|
||
|
for file in $out/*; do
|
||
|
case "$file" in
|
||
|
plugin.sh) continue;;
|
||
|
esac
|
||
|
|
||
|
# read magic makers from the file
|
||
|
family=$(sed -nr 's/.*#%#\s+family\s*=\s*(\S+)\s*/\1/p' $file)
|
||
|
cap=$(sed -nr 's/.*#%#\s+capabilities\s*=\s*(.+)/\1/p' $file)
|
||
|
|
||
|
wrapProgram $file \
|
||
|
--set PATH "/run/current-system/sw/bin:/run/current-system/sw/sbin" \
|
||
|
--set MUNIN_LIBDIR "${pkgs.munin}/lib" \
|
||
|
--set MUNIN_PLUGSTATE "/var/run/munin"
|
||
|
|
||
|
# munin uses markers to tell munin-node-configure what a plugin can do
|
||
|
echo "#%# family=$family" >> $file
|
||
|
echo "#%# capabilities=$cap" >> $file
|
||
|
done
|
||
|
|
||
|
# NOTE: we disable disktstats because plugin seems to fail and it hangs html generation (100% CPU + memory leak)
|
||
|
rm -f $out/diskstats
|
||
|
'';
|
||
|
buildInputs = [ pkgs.makeWrapper ];
|
||
|
};
|
||
|
|
||
|
muninConf = pkgs.writeText "munin.conf"
|
||
|
''
|
||
|
dbdir /var/lib/munin
|
||
|
htmldir /var/www/munin
|
||
|
logdir /var/log/munin
|
||
|
rundir /var/run/munin
|
||
|
|
||
|
${cronCfg.extraGlobalConfig}
|
||
|
|
||
|
${cronCfg.hosts}
|
||
|
'';
|
||
|
|
||
|
nodeConf = pkgs.writeText "munin-node.conf"
|
||
|
''
|
||
|
log_level 3
|
||
|
log_file Sys::Syslog
|
||
|
port 4949
|
||
|
host *
|
||
|
background 0
|
||
|
user root
|
||
|
group root
|
||
|
host_name ${config.networking.hostName}
|
||
|
setsid 0
|
||
|
|
||
|
# wrapped plugins by makeWrapper being with dots
|
||
|
ignore_file ^\.
|
||
|
|
||
|
allow ^127\.0\.0\.1$
|
||
|
|
||
|
${nodeCfg.extraConfig}
|
||
|
'';
|
||
|
in
|
||
|
|
||
|
{
|
||
|
|
||
|
options = {
|
||
|
|
||
|
services.munin-node = {
|
||
|
|
||
|
enable = mkOption {
|
||
|
default = false;
|
||
|
description = ''
|
||
|
Enable Munin Node agent. Munin node listens on 0.0.0.0 and
|
||
|
by default accepts connections only from 127.0.0.1 for security reasons.
|
||
|
|
||
|
See <link xlink:href='http://munin-monitoring.org/wiki/munin-node' />.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
extraConfig = mkOption {
|
||
|
default = "";
|
||
|
description = ''
|
||
|
<filename>munin-node.conf</filename> extra configuration. See
|
||
|
<link xlink:href='http://munin-monitoring.org/wiki/munin-node.conf' />
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
# TODO: add option to add additional plugins
|
||
|
|
||
|
};
|
||
|
|
||
|
services.munin-cron = {
|
||
|
|
||
|
enable = mkOption {
|
||
|
default = false;
|
||
|
description = ''
|
||
|
Enable munin-cron. Takes care of all heavy lifting to collect data from
|
||
|
nodes and draws graphs to html. Runs munin-update, munin-limits,
|
||
|
munin-graphs and munin-html in that order.
|
||
|
|
||
|
HTML output is in <filename>/var/www/munin/</filename>, configure your
|
||
|
favourite webserver to serve static files.
|
||
|
'';
|
||
|
example = literalExample ''
|
||
|
services = {
|
||
|
munin-node.enable = true;
|
||
|
munin-cron = {
|
||
|
enable = true;
|
||
|
hosts = '''
|
||
|
[''${config.networking.hostName}]
|
||
|
address localhost
|
||
|
''';
|
||
|
extraGlobalConfig = '''
|
||
|
contact.email.command mail -s "Munin notification for ''${var:host}" someone@example.com
|
||
|
''';
|
||
|
};
|
||
|
};
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
extraGlobalConfig = mkOption {
|
||
|
default = "";
|
||
|
description = ''
|
||
|
<filename>munin.conf</filename> extra global configuration.
|
||
|
See <link xlink:href='http://munin-monitoring.org/wiki/munin-node' />.
|
||
|
Useful to setup notifications, see
|
||
|
<link xlink:href='http://munin-monitoring.org/wiki/HowToContact' />
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
hosts = mkOption {
|
||
|
example = ''
|
||
|
[''${config.networking.hostName}]
|
||
|
address localhost
|
||
|
'';
|
||
|
description = ''
|
||
|
Definitions of hosts of nodes to collect data from. Needs at least one
|
||
|
hosts for cron to succeed. See
|
||
|
<link xlink:href='http://munin-monitoring.org/wiki/munin.conf' />
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
};
|
||
|
|
||
|
};
|
||
|
|
||
|
config = mkMerge [ (mkIf (nodeCfg.enable || cronCfg.enable) {
|
||
|
|
||
|
environment.systemPackages = [ pkgs.munin ];
|
||
|
|
||
|
users.extraUsers = [{
|
||
|
name = "munin";
|
||
|
description = "Munin monitoring user";
|
||
|
group = "munin";
|
||
|
}];
|
||
|
|
||
|
users.extraGroups = [{
|
||
|
name = "munin";
|
||
|
}];
|
||
|
|
||
|
}) (mkIf nodeCfg.enable {
|
||
|
|
||
|
systemd.services.munin-node = {
|
||
|
description = "Munin node, the agent process";
|
||
|
after = [ "network.target" ];
|
||
|
wantedBy = [ "multi-user.target" ];
|
||
|
path = [ pkgs.munin ];
|
||
|
environment.MUNIN_PLUGSTATE = "/var/run/munin";
|
||
|
serviceConfig = {
|
||
|
ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
system.activationScripts.munin-node = ''
|
||
|
echo "updating munin plugins..."
|
||
|
|
||
|
export PATH="/run/current-system/sw/bin:/run/current-system/sw/sbin";
|
||
|
mkdir -p /etc/munin/plugins
|
||
|
rm -rf /etc/munin/plugins/*
|
||
|
${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash
|
||
|
'';
|
||
|
|
||
|
}) (mkIf cronCfg.enable {
|
||
|
|
||
|
services.cron.systemCronJobs = [
|
||
|
"*/5 * * * * munin ${pkgs.munin}/bin/munin-cron --config ${muninConf}"
|
||
|
];
|
||
|
|
||
|
system.activationScripts.munin-cron = stringAfter [ "users" "groups" ] ''
|
||
|
mkdir -p /var/{run,log,www,lib}/munin
|
||
|
chown -R munin:munin /var/{run,log,www,lib}/munin
|
||
|
'';
|
||
|
|
||
|
})];
|
||
|
}
|