at 22.05-pre 8.5 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.awstats; 7 package = pkgs.awstats; 8 configOpts = {name, config, ...}: { 9 options = { 10 type = mkOption{ 11 type = types.enum [ "mail" "web" ]; 12 default = "web"; 13 example = "mail"; 14 description = '' 15 The type of log being collected. 16 ''; 17 }; 18 domain = mkOption { 19 type = types.str; 20 default = name; 21 description = "The domain name to collect stats for."; 22 example = "example.com"; 23 }; 24 25 logFile = mkOption { 26 type = types.str; 27 example = "/var/log/nginx/access.log"; 28 description = '' 29 The log file to be scanned. 30 31 For mail, set this to 32 <literal> 33 journalctl $OLD_CURSOR -u postfix.service | ''${pkgs.perl}/bin/perl ''${pkgs.awstats.out}/share/awstats/tools/maillogconvert.pl standard | 34 </literal> 35 ''; 36 }; 37 38 logFormat = mkOption { 39 type = types.str; 40 default = "1"; 41 description = '' 42 The log format being used. 43 44 For mail, set this to 45 <literal> 46 %time2 %email %email_r %host %host_r %method %url %code %bytesd 47 </literal> 48 ''; 49 }; 50 51 hostAliases = mkOption { 52 type = types.listOf types.str; 53 default = []; 54 example = [ "www.example.org" ]; 55 description = '' 56 List of aliases the site has. 57 ''; 58 }; 59 60 extraConfig = mkOption { 61 type = types.attrsOf types.str; 62 default = {}; 63 example = literalExpression '' 64 { 65 "ValidHTTPCodes" = "404"; 66 } 67 ''; 68 description = "Extra configuration to be appended to awstats.\${name}.conf."; 69 }; 70 71 webService = { 72 enable = mkEnableOption "awstats web service"; 73 74 hostname = mkOption { 75 type = types.str; 76 default = config.domain; 77 description = "The hostname the web service appears under."; 78 }; 79 80 urlPrefix = mkOption { 81 type = types.str; 82 default = "/awstats"; 83 description = "The URL prefix under which the awstats pages appear."; 84 }; 85 }; 86 }; 87 }; 88 webServices = filterAttrs (name: value: value.webService.enable) cfg.configs; 89in 90{ 91 imports = [ 92 (mkRemovedOptionModule [ "services" "awstats" "service" "enable" ] "Please enable per domain with `services.awstats.configs.<name>.webService.enable`") 93 (mkRemovedOptionModule [ "services" "awstats" "service" "urlPrefix" ] "Please set per domain with `services.awstats.configs.<name>.webService.urlPrefix`") 94 (mkRenamedOptionModule [ "services" "awstats" "vardir" ] [ "services" "awstats" "dataDir" ]) 95 ]; 96 97 options.services.awstats = { 98 enable = mkEnableOption "awstats"; 99 100 dataDir = mkOption { 101 type = types.path; 102 default = "/var/lib/awstats"; 103 description = "The directory where awstats data will be stored."; 104 }; 105 106 configs = mkOption { 107 type = types.attrsOf (types.submodule configOpts); 108 default = {}; 109 example = literalExpression '' 110 { 111 "mysite" = { 112 domain = "example.com"; 113 logFile = "/var/log/nginx/access.log"; 114 }; 115 } 116 ''; 117 description = "Attribute set of domains to collect stats for."; 118 }; 119 120 updateAt = mkOption { 121 type = types.nullOr types.str; 122 default = null; 123 example = "hourly"; 124 description = '' 125 Specification of the time at which awstats will get updated. 126 (in the format described by <citerefentry> 127 <refentrytitle>systemd.time</refentrytitle> 128 <manvolnum>7</manvolnum></citerefentry>) 129 ''; 130 }; 131 }; 132 133 134 config = mkIf cfg.enable { 135 environment.systemPackages = [ package.bin ]; 136 137 environment.etc = mapAttrs' (name: opts: 138 nameValuePair "awstats/awstats.${name}.conf" { 139 source = pkgs.runCommand "awstats.${name}.conf" 140 { preferLocalBuild = true; } 141 ('' 142 sed \ 143 '' 144 # set up mail stats 145 + optionalString (opts.type == "mail") 146 '' 147 -e 's|^\(LogType\)=.*$|\1=M|' \ 148 -e 's|^\(LevelForBrowsersDetection\)=.*$|\1=0|' \ 149 -e 's|^\(LevelForOSDetection\)=.*$|\1=0|' \ 150 -e 's|^\(LevelForRefererAnalyze\)=.*$|\1=0|' \ 151 -e 's|^\(LevelForRobotsDetection\)=.*$|\1=0|' \ 152 -e 's|^\(LevelForSearchEnginesDetection\)=.*$|\1=0|' \ 153 -e 's|^\(LevelForFileTypesDetection\)=.*$|\1=0|' \ 154 -e 's|^\(LevelForWormsDetection\)=.*$|\1=0|' \ 155 -e 's|^\(ShowMenu\)=.*$|\1=1|' \ 156 -e 's|^\(ShowSummary\)=.*$|\1=HB|' \ 157 -e 's|^\(ShowMonthStats\)=.*$|\1=HB|' \ 158 -e 's|^\(ShowDaysOfMonthStats\)=.*$|\1=HB|' \ 159 -e 's|^\(ShowDaysOfWeekStats\)=.*$|\1=HB|' \ 160 -e 's|^\(ShowHoursStats\)=.*$|\1=HB|' \ 161 -e 's|^\(ShowDomainsStats\)=.*$|\1=0|' \ 162 -e 's|^\(ShowHostsStats\)=.*$|\1=HB|' \ 163 -e 's|^\(ShowAuthenticatedUsers\)=.*$|\1=0|' \ 164 -e 's|^\(ShowRobotsStats\)=.*$|\1=0|' \ 165 -e 's|^\(ShowEMailSenders\)=.*$|\1=HBML|' \ 166 -e 's|^\(ShowEMailReceivers\)=.*$|\1=HBML|' \ 167 -e 's|^\(ShowSessionsStats\)=.*$|\1=0|' \ 168 -e 's|^\(ShowPagesStats\)=.*$|\1=0|' \ 169 -e 's|^\(ShowFileTypesStats\)=.*$|\1=0|' \ 170 -e 's|^\(ShowFileSizesStats\)=.*$|\1=0|' \ 171 -e 's|^\(ShowBrowsersStats\)=.*$|\1=0|' \ 172 -e 's|^\(ShowOSStats\)=.*$|\1=0|' \ 173 -e 's|^\(ShowOriginStats\)=.*$|\1=0|' \ 174 -e 's|^\(ShowKeyphrasesStats\)=.*$|\1=0|' \ 175 -e 's|^\(ShowKeywordsStats\)=.*$|\1=0|' \ 176 -e 's|^\(ShowMiscStats\)=.*$|\1=0|' \ 177 -e 's|^\(ShowHTTPErrorsStats\)=.*$|\1=0|' \ 178 -e 's|^\(ShowSMTPErrorsStats\)=.*$|\1=1|' \ 179 '' 180 + 181 # common options 182 '' 183 -e 's|^\(DirData\)=.*$|\1="${cfg.dataDir}/${name}"|' \ 184 -e 's|^\(DirIcons\)=.*$|\1="icons"|' \ 185 -e 's|^\(CreateDirDataIfNotExists\)=.*$|\1=1|' \ 186 -e 's|^\(SiteDomain\)=.*$|\1="${name}"|' \ 187 -e 's|^\(LogFile\)=.*$|\1="${opts.logFile}"|' \ 188 -e 's|^\(LogFormat\)=.*$|\1="${opts.logFormat}"|' \ 189 '' 190 + 191 # extra config 192 concatStringsSep "\n" (mapAttrsToList (n: v: '' 193 -e 's|^\(${n}\)=.*$|\1="${v}"|' \ 194 '') opts.extraConfig) 195 + 196 '' 197 < '${package.out}/wwwroot/cgi-bin/awstats.model.conf' > "$out" 198 ''); 199 }) cfg.configs; 200 201 # create data directory with the correct permissions 202 systemd.tmpfiles.rules = 203 [ "d '${cfg.dataDir}' 755 root root - -" ] ++ 204 mapAttrsToList (name: opts: "d '${cfg.dataDir}/${name}' 755 root root - -") cfg.configs ++ 205 [ "Z '${cfg.dataDir}' 755 root root - -" ]; 206 207 # nginx options 208 services.nginx.virtualHosts = mapAttrs'(name: opts: { 209 name = opts.webService.hostname; 210 value = { 211 locations = { 212 "${opts.webService.urlPrefix}/css/" = { 213 alias = "${package.out}/wwwroot/css/"; 214 }; 215 "${opts.webService.urlPrefix}/icons/" = { 216 alias = "${package.out}/wwwroot/icon/"; 217 }; 218 "${opts.webService.urlPrefix}/" = { 219 alias = "${cfg.dataDir}/${name}/"; 220 extraConfig = '' 221 autoindex on; 222 ''; 223 }; 224 }; 225 }; 226 }) webServices; 227 228 # update awstats 229 systemd.services = mkIf (cfg.updateAt != null) (mapAttrs' (name: opts: 230 nameValuePair "awstats-${name}-update" { 231 description = "update awstats for ${name}"; 232 script = optionalString (opts.type == "mail") 233 '' 234 if [[ -f "${cfg.dataDir}/${name}-cursor" ]]; then 235 CURSOR="$(cat "${cfg.dataDir}/${name}-cursor" | tr -d '\n')" 236 if [[ -n "$CURSOR" ]]; then 237 echo "Using cursor: $CURSOR" 238 export OLD_CURSOR="--cursor $CURSOR" 239 fi 240 fi 241 NEW_CURSOR="$(journalctl $OLD_CURSOR -u postfix.service --show-cursor | tail -n 1 | tr -d '\n' | sed -e 's#^-- cursor: \(.*\)#\1#')" 242 echo "New cursor: $NEW_CURSOR" 243 ${package.bin}/bin/awstats -update -config=${name} 244 if [ -n "$NEW_CURSOR" ]; then 245 echo -n "$NEW_CURSOR" > ${cfg.dataDir}/${name}-cursor 246 fi 247 '' + '' 248 ${package.out}/share/awstats/tools/awstats_buildstaticpages.pl \ 249 -config=${name} -update -dir=${cfg.dataDir}/${name} \ 250 -awstatsprog=${package.bin}/bin/awstats 251 ''; 252 startAt = cfg.updateAt; 253 }) cfg.configs); 254 }; 255 256} 257