]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - modules/webapps/webstats/default.nix
Move webstats outside of nixops
[perso/Immae/Config/Nix.git] / modules / webapps / webstats / default.nix
diff --git a/modules/webapps/webstats/default.nix b/modules/webapps/webstats/default.nix
new file mode 100644 (file)
index 0000000..f4916bd
--- /dev/null
@@ -0,0 +1,84 @@
+{ lib, pkgs, config, mylibs, ... }:
+let
+  name = "goaccess";
+  cfg = config.services.webstats;
+in {
+  options.services.webstats = {
+    dataDir = lib.mkOption {
+      type = lib.types.path;
+      default = "/var/lib/${name}";
+      description = ''
+        The directory where Goaccess stores its data.
+      '';
+    };
+    sites = lib.mkOption {
+      type = lib.types.listOf (lib.types.submodule {
+        options = {
+          conf = lib.mkOption {
+            type = lib.types.nullOr lib.types.path;
+            default = null;
+            description = ''
+              use custom goaccess configuration file instead of the
+              default one.
+              '';
+          };
+          name = lib.mkOption {
+            type = lib.types.string;
+            description  = ''
+              Domain name. Corresponds to the Apache file name and the
+              folder name in which the state will be saved.
+              '';
+          };
+        };
+      });
+      default = [];
+      description = "Sites to generate stats";
+    };
+  };
+
+  config = lib.mkIf (builtins.length cfg.sites > 0) {
+    users.users.root.packages = [
+      pkgs.goaccess
+    ];
+
+    services.cron = {
+      enable = true;
+      systemCronJobs = let
+        stats = domain: conf: let
+          config = if builtins.isNull conf
+            then pkgs.runCommand "goaccess.conf" {
+                dbPath = "${cfg.dataDir}/${domain}";
+              } "substituteAll ${./goaccess.conf} $out"
+            else conf;
+          d = pkgs.writeScriptBin "stats-${domain}" ''
+            #!${pkgs.stdenv.shell}
+            set -e
+            shopt -s nullglob
+            date_regex=$(LC_ALL=C date -d yesterday +'%d\/%b\/%Y')
+            TMPFILE=$(mktemp)
+            trap "rm -f $TMPFILE" EXIT
+
+            cat /var/log/httpd/access_log-${domain} | sed -n "/\\[$date_regex/ p" > $TMPFILE
+            for i in /var/log/httpd/access_log-${domain}*.gz; do
+              zcat "$i" | sed -n "/\\[$date_regex/ p" >> $TMPFILE
+            done
+            ${pkgs.goaccess}/bin/goaccess $TMPFILE --no-progress -o ${cfg.dataDir}/${domain}/index.html -p ${config}
+            '';
+          in "${d}/bin/stats-${domain}";
+        allStats = sites: pkgs.writeScript "stats" ''
+          #!${pkgs.stdenv.shell}
+
+          ${builtins.concatStringsSep "\n" (map (v: stats v.name v.conf) sites)}
+          '';
+      in
+        [
+          "5 0 * * * root ${allStats cfg.sites}"
+        ];
+    };
+
+    system.activationScripts.goaccess = ''
+      mkdir -p /var/lib/goaccess
+    '' +
+    builtins.concatStringsSep "\n" (map (v: "mkdir -p ${cfg.dataDir}/${v.name}") cfg.sites);
+  };
+}