1 { config, lib, pkgs, ... }:
6 cfg = config.services.longview;
8 runDir = "/run/longview";
9 configsDir = "${runDir}/longview.d";
20 If enabled, system metrics will be sent to Linode LongView.
27 example = "01234567-89AB-CDEF-0123456789ABCDEF";
29 Longview API key. To get this, look in Longview settings which
30 are found at https://manager.linode.com/longview/.
32 Warning: this secret is stored in the world-readable Nix store!
33 Use {option}`apiKeyFile` instead.
37 apiKeyFile = mkOption {
38 type = types.nullOr types.path;
40 example = "/run/keys/longview-api-key";
42 A file containing the Longview API key.
43 To get this, look in Longview settings which
44 are found at https://manager.linode.com/longview/.
46 {option}`apiKeyFile` takes precedence over {option}`apiKey`.
50 apacheStatusUrl = mkOption {
53 example = "http://127.0.0.1/server-status";
55 The Apache status page URL. If provided, Longview will
56 gather statistics from this location. This requires Apache
57 mod_status to be loaded and enabled.
61 nginxStatusUrl = mkOption {
64 example = "http://127.0.0.1/nginx_status";
66 The Nginx status page URL. Longview will gather statistics
67 from this URL. This requires the Nginx stub_status module to
68 be enabled and configured at the given location.
72 mysqlUser = mkOption {
76 The user for connecting to the MySQL database. If provided,
77 Longview will connect to MySQL and collect statistics about
78 queries, etc. This user does not need to have been granted
83 mysqlPassword = mkOption {
87 The password corresponding to {option}`mysqlUser`.
88 Warning: this is stored in cleartext in the Nix store!
89 Use {option}`mysqlPasswordFile` instead.
93 mysqlPasswordFile = mkOption {
94 type = types.nullOr types.path;
96 example = "/run/keys/dbpassword";
98 A file containing the password corresponding to {option}`mysqlUser`.
106 config = mkIf cfg.enable {
107 systemd.services.longview =
108 { description = "Longview Metrics Collection";
109 after = [ "network.target" ];
110 wantedBy = [ "multi-user.target" ];
111 serviceConfig.Type = "forking";
112 serviceConfig.ExecStop = "-${pkgs.coreutils}/bin/kill -TERM $MAINPID";
113 serviceConfig.ExecReload = "-${pkgs.coreutils}/bin/kill -HUP $MAINPID";
114 serviceConfig.PIDFile = "${runDir}/longview.pid";
115 serviceConfig.ExecStart = "${pkgs.longview}/bin/longview";
118 mkdir -p ${configsDir}
119 '' + (optionalString (cfg.apiKeyFile != null) ''
120 cp --no-preserve=all "${cfg.apiKeyFile}" ${runDir}/longview.key
121 '') + (optionalString (cfg.apacheStatusUrl != "") ''
122 cat > ${configsDir}/Apache.conf <<EOF
123 location ${cfg.apacheStatusUrl}?auto
125 '') + (optionalString (cfg.mysqlUser != "" && cfg.mysqlPasswordFile != null) ''
126 cat > ${configsDir}/MySQL.conf <<EOF
127 username ${cfg.mysqlUser}
128 password `head -n1 "${cfg.mysqlPasswordFile}"`
130 '') + (optionalString (cfg.nginxStatusUrl != "") ''
131 cat > ${configsDir}/Nginx.conf <<EOF
132 location ${cfg.nginxStatusUrl}
137 warnings = let warn = k: optional (cfg.${k} != "")
138 "config.services.longview.${k} is insecure. Use ${k}File instead.";
139 in concatMap warn [ "apiKey" "mysqlPassword" ];
142 { assertion = cfg.apiKeyFile != null;
143 message = "Longview needs an API key configured";
147 # Create API key file if not configured.
148 services.longview.apiKeyFile = mkIf (cfg.apiKey != "")
149 (mkDefault (toString (pkgs.writeTextFile {
150 name = "longview.key";
154 # Create MySQL password file if not configured.
155 services.longview.mysqlPasswordFile = mkDefault (toString (pkgs.writeTextFile {
156 name = "mysql-password-file";
157 text = cfg.mysqlPassword;