1 { config, lib, pkgs, ... }:
3 cfg = config.services.awstats;
4 package = pkgs.awstats;
5 configOpts = {name, config, ...}: {
8 type = lib.types.enum [ "mail" "web" ];
12 The type of log being collected.
15 domain = lib.mkOption {
18 description = "The domain name to collect stats for.";
19 example = "example.com";
22 logFile = lib.mkOption {
24 example = "/var/log/nginx/access.log";
26 The log file to be scanned.
30 journalctl $OLD_CURSOR -u postfix.service | ''${pkgs.perl}/bin/perl ''${pkgs.awstats.out}/share/awstats/tools/maillogconvert.pl standard |
35 logFormat = lib.mkOption {
39 The log format being used.
43 %time2 %email %email_r %host %host_r %method %url %code %bytesd
48 hostAliases = lib.mkOption {
49 type = lib.types.listOf lib.types.str;
51 example = [ "www.example.org" ];
53 List of aliases the site has.
57 extraConfig = lib.mkOption {
58 type = lib.types.attrsOf lib.types.str;
60 example = lib.literalExpression ''
62 "ValidHTTPCodes" = "404";
65 description = "Extra configuration to be appended to awstats.\${name}.conf.";
69 enable = lib.mkEnableOption "awstats web service";
71 hostname = lib.mkOption {
73 default = config.domain;
74 description = "The hostname the web service appears under.";
77 urlPrefix = lib.mkOption {
80 description = "The URL prefix under which the awstats pages appear.";
85 webServices = lib.filterAttrs (name: value: value.webService.enable) cfg.configs;
89 (lib.mkRemovedOptionModule [ "services" "awstats" "service" "enable" ] "Please enable per domain with `services.awstats.configs.<name>.webService.enable`")
90 (lib.mkRemovedOptionModule [ "services" "awstats" "service" "urlPrefix" ] "Please set per domain with `services.awstats.configs.<name>.webService.urlPrefix`")
91 (lib.mkRenamedOptionModule [ "services" "awstats" "vardir" ] [ "services" "awstats" "dataDir" ])
94 options.services.awstats = {
95 enable = lib.mkEnableOption "awstats, a real-time logfile analyzer";
97 dataDir = lib.mkOption {
98 type = lib.types.path;
99 default = "/var/lib/awstats";
100 description = "The directory where awstats data will be stored.";
103 configs = lib.mkOption {
104 type = lib.types.attrsOf (lib.types.submodule configOpts);
106 example = lib.literalExpression ''
109 domain = "example.com";
110 logFile = "/var/log/nginx/access.log";
114 description = "Attribute set of domains to collect stats for.";
117 updateAt = lib.mkOption {
118 type = lib.types.nullOr lib.types.str;
122 Specification of the time at which awstats will get updated.
123 (in the format described by {manpage}`systemd.time(7)`)
129 config = lib.mkIf cfg.enable {
130 environment.systemPackages = [ package.bin ];
132 environment.etc = lib.mapAttrs' (name: opts:
133 lib.nameValuePair "awstats/awstats.${name}.conf" {
134 source = pkgs.runCommand "awstats.${name}.conf"
135 { preferLocalBuild = true; }
140 + lib.optionalString (opts.type == "mail")
142 -e 's|^\(LogType\)=.*$|\1=M|' \
143 -e 's|^\(LevelForBrowsersDetection\)=.*$|\1=0|' \
144 -e 's|^\(LevelForOSDetection\)=.*$|\1=0|' \
145 -e 's|^\(LevelForRefererAnalyze\)=.*$|\1=0|' \
146 -e 's|^\(LevelForRobotsDetection\)=.*$|\1=0|' \
147 -e 's|^\(LevelForSearchEnginesDetection\)=.*$|\1=0|' \
148 -e 's|^\(LevelForFileTypesDetection\)=.*$|\1=0|' \
149 -e 's|^\(LevelForWormsDetection\)=.*$|\1=0|' \
150 -e 's|^\(ShowMenu\)=.*$|\1=1|' \
151 -e 's|^\(ShowSummary\)=.*$|\1=HB|' \
152 -e 's|^\(ShowMonthStats\)=.*$|\1=HB|' \
153 -e 's|^\(ShowDaysOfMonthStats\)=.*$|\1=HB|' \
154 -e 's|^\(ShowDaysOfWeekStats\)=.*$|\1=HB|' \
155 -e 's|^\(ShowHoursStats\)=.*$|\1=HB|' \
156 -e 's|^\(ShowDomainsStats\)=.*$|\1=0|' \
157 -e 's|^\(ShowHostsStats\)=.*$|\1=HB|' \
158 -e 's|^\(ShowAuthenticatedUsers\)=.*$|\1=0|' \
159 -e 's|^\(ShowRobotsStats\)=.*$|\1=0|' \
160 -e 's|^\(ShowEMailSenders\)=.*$|\1=HBML|' \
161 -e 's|^\(ShowEMailReceivers\)=.*$|\1=HBML|' \
162 -e 's|^\(ShowSessionsStats\)=.*$|\1=0|' \
163 -e 's|^\(ShowPagesStats\)=.*$|\1=0|' \
164 -e 's|^\(ShowFileTypesStats\)=.*$|\1=0|' \
165 -e 's|^\(ShowFileSizesStats\)=.*$|\1=0|' \
166 -e 's|^\(ShowBrowsersStats\)=.*$|\1=0|' \
167 -e 's|^\(ShowOSStats\)=.*$|\1=0|' \
168 -e 's|^\(ShowOriginStats\)=.*$|\1=0|' \
169 -e 's|^\(ShowKeyphrasesStats\)=.*$|\1=0|' \
170 -e 's|^\(ShowKeywordsStats\)=.*$|\1=0|' \
171 -e 's|^\(ShowMiscStats\)=.*$|\1=0|' \
172 -e 's|^\(ShowHTTPErrorsStats\)=.*$|\1=0|' \
173 -e 's|^\(ShowSMTPErrorsStats\)=.*$|\1=1|' \
178 -e 's|^\(DirData\)=.*$|\1="${cfg.dataDir}/${name}"|' \
179 -e 's|^\(DirIcons\)=.*$|\1="icons"|' \
180 -e 's|^\(CreateDirDataIfNotExists\)=.*$|\1=1|' \
181 -e 's|^\(SiteDomain\)=.*$|\1="${name}"|' \
182 -e 's|^\(LogFile\)=.*$|\1="${opts.logFile}"|' \
183 -e 's|^\(LogFormat\)=.*$|\1="${opts.logFormat}"|' \
187 lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: ''
188 -e 's|^\(${n}\)=.*$|\1="${v}"|' \
189 '') opts.extraConfig)
192 < '${package.out}/wwwroot/cgi-bin/awstats.model.conf' > "$out"
196 # create data directory with the correct permissions
197 systemd.tmpfiles.rules =
198 [ "d '${cfg.dataDir}' 755 root root - -" ] ++
199 lib.mapAttrsToList (name: opts: "d '${cfg.dataDir}/${name}' 755 root root - -") cfg.configs ++
200 [ "Z '${cfg.dataDir}' 755 root root - -" ];
203 services.nginx.virtualHosts = lib.mapAttrs'(name: opts: {
204 name = opts.webService.hostname;
207 "${opts.webService.urlPrefix}/css/" = {
208 alias = "${package.out}/wwwroot/css/";
210 "${opts.webService.urlPrefix}/icons/" = {
211 alias = "${package.out}/wwwroot/icon/";
213 "${opts.webService.urlPrefix}/" = {
214 alias = "${cfg.dataDir}/${name}/";
224 systemd.services = lib.mkIf (cfg.updateAt != null) (lib.mapAttrs' (name: opts:
225 lib.nameValuePair "awstats-${name}-update" {
226 description = "update awstats for ${name}";
227 script = lib.optionalString (opts.type == "mail")
229 if [[ -f "${cfg.dataDir}/${name}-cursor" ]]; then
230 CURSOR="$(cat "${cfg.dataDir}/${name}-cursor" | tr -d '\n')"
231 if [[ -n "$CURSOR" ]]; then
232 echo "Using cursor: $CURSOR"
233 export OLD_CURSOR="--cursor $CURSOR"
236 NEW_CURSOR="$(journalctl $OLD_CURSOR -u postfix.service --show-cursor | tail -n 1 | tr -d '\n' | sed -e 's#^-- cursor: \(.*\)#\1#')"
237 echo "New cursor: $NEW_CURSOR"
238 ${package.bin}/bin/awstats -update -config=${name}
239 if [ -n "$NEW_CURSOR" ]; then
240 echo -n "$NEW_CURSOR" > ${cfg.dataDir}/${name}-cursor
243 ${package.out}/share/awstats/tools/awstats_buildstaticpages.pl \
244 -config=${name} -update -dir=${cfg.dataDir}/${name} \
245 -awstatsprog=${package.bin}/bin/awstats
247 startAt = cfg.updateAt;