summary refs log tree commit diff
path: root/nixos/modules/services/monitoring/systemhealth.nix
blob: b0e59595e1337256aedb6f74f9b180b9cf6284a6 (plain) (blame)
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
{ config, lib, pkgs, ... }:

with lib;

let
  cfg = config.services.systemhealth;

  systemhealth = with pkgs; stdenv.mkDerivation {
    name = "systemhealth-1.0";
    src = fetchurl {
      url = "http://www.brianlane.com/static/downloads/systemhealth/systemhealth-1.0.tar.bz2";
      sha256 = "1q69lz7hmpbdpbz36zb06nzfkj651413n9icx0njmyr3xzq1j9qy";
    };
    buildInputs = [ python ];
    installPhase = ''
      ensureDir $out/bin
      # Make it work for kernels 3.x, not so different than 2.6
      sed -i 's/2\.6/4.0/' system_health.py
      cp system_health.py $out/bin
    '';
  };

  rrdDir = "/var/lib/health/rrd";
  htmlDir = "/var/lib/health/html";

  configFile = rrdDir + "/.syshealthrc";
  # The program will try to read $HOME/.syshealthrc, so we set the proper home.
  command = "HOME=${rrdDir} ${systemhealth}/bin/system_health.py";

  cronJob = ''
    */5 * * * * wwwrun ${command} --log
    5 * * * * wwwrun ${command} --graph
  '';

  nameEqualName = s: "${s} = ${s}";
  interfacesSection = concatStringsSep "\n" (map nameEqualName cfg.interfaces);

  driveLine = d: "${d.path} = ${d.name}";
  drivesSection = concatStringsSep "\n" (map driveLine cfg.drives);

in
{
  options = {
    services.systemhealth = {
      enable = mkOption {
        default = false;
        description = ''
          Enable the system health monitor and its generation of graphs.
        '';
      };

      urlPrefix = mkOption {
        default = "/health";
        description = ''
          The URL prefix under which the System Health web pages appear in httpd.
        '';
      };

      interfaces = mkOption {
        default = [ "lo" ];
        example = [ "lo" "eth0" "eth1" ];
        description = ''
          Interfaces to monitor (minimum one).
        '';
      };

      drives = mkOption {
        default = [ ];
        example = [ { name = "root"; path = "/"; } ];
        description = ''
          Drives to monitor.
        '';
      };
    };
  };

  config = mkIf cfg.enable {
    services.cron.systemCronJobs = [ cronJob ];

    system.activationScripts.systemhealth = stringAfter [ "var" ]
      ''
        mkdir -p ${rrdDir} ${htmlDir}
        chown wwwrun:wwwrun ${rrdDir} ${htmlDir}

        cat >${configFile} << EOF
        [paths]
        rrdtool = ${pkgs.rrdtool}/bin/rrdtool
        loadavg_rrd = loadavg
        ps = /run/current-system/sw/bin/ps
        df = /run/current-system/sw/bin/df
        meminfo_rrd = meminfo
        uptime_rrd = uptime
        rrd_path = ${rrdDir}
        png_path = ${htmlDir}

        [processes]

        [interfaces]
        ${interfacesSection}

        [drives]
        ${drivesSection}

        [graphs]
        width = 400
        time = ['-3hours', '-32hours', '-8days', '-5weeks', '-13months']
        height = 100

        [external]

        EOF

        chown wwwrun:wwwrun ${configFile}

        ${pkgs.su}/bin/su -s "/bin/sh" -c "${command} --check" wwwrun
        ${pkgs.su}/bin/su -s "/bin/sh" -c "${command} --html" wwwrun
      '';

    services.httpd.extraSubservices = [
      { function = f: {
          extraConfig = ''
            Alias ${cfg.urlPrefix} ${htmlDir}

            <Directory ${htmlDir}>
                Order allow,deny
                Allow from all
            </Directory>
          '';
        };
      }
    ];
  };
}