diff options
Diffstat (limited to 'nixos/modules/services/logging/logstash.nix')
-rw-r--r-- | nixos/modules/services/logging/logstash.nix | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/nixos/modules/services/logging/logstash.nix b/nixos/modules/services/logging/logstash.nix new file mode 100644 index 00000000000..2f0eea50526 --- /dev/null +++ b/nixos/modules/services/logging/logstash.nix @@ -0,0 +1,161 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfg = config.services.logstash; + + listToConfig = list: "[ " + (concatStringsSep ", " (map exprToConfig list)) + " ]"; + + hashToConfig = attrs: + let + attrNameToConfigList = name: + [ (exprToConfig name) (exprToConfig (getAttr name attrs)) ]; + in + "[ " + + (concatStringsSep ", " (map attrNameToConfigList (attrNames attrs))) + + " ]"; + + valueToConfig = nvpair: let name = nvpair.name; value = nvpair.value; in + if (isAttrs value) && ((!(value ? __type)) || value.__type == "repeated") + then '' + ${name} { + ${exprToConfig value} + } + '' + else "${name} => ${exprToConfig value}"; + + repeatedAttrsToConfig = values: + concatStringsSep "\n" (map valueToConfig values); + + attrsToConfig = attrs: + let + attrToConfig = name: valueToConfig { + inherit name; + value = (getAttr name attrs); + }; + in + concatStringsSep "\n" (map attrToConfig (attrNames attrs)); + + exprToConfig = expr: + let + isCustomType = expr: (isAttrs expr) && (expr ? __type); + + isFloat = expr: (isCustomType expr) && (expr.__type == "float"); + + isHash = expr: (isCustomType expr) && (expr.__type == "hash"); + + isRepeatedAttrs = expr: (isCustomType expr) && (expr.__type == "repeated"); + in + if builtins.isBool expr then (if expr then "true" else "false") else + if builtins.isString expr then ''"${expr}"'' else + if builtins.isInt expr then toString expr else + if isFloat expr then expr.value else + if isList expr then listToConfig expr else + if isHash expr then hashToConfig expr.value else + if isRepeatedAttrs expr then repeatedAttrsToConfig expr.values + else attrsToConfig expr; + + mergeConfigs = configs: + let + op = attrs: newAttrs: + let + isRepeated = newAttrs ? __type && newAttrs.__type == "repeated"; + in { + values = attrs.values ++ (if isRepeated then newAttrs.values else + map (name: { inherit name; value = getAttr name newAttrs; }) + (attrNames newAttrs)); + }; + in (foldl op { values = []; } configs) // { __type = "repeated"; }; + +in + +{ + ###### interface + + options = { + services.logstash = { + enable = mkOption { + default = false; + description = '' + Enable logstash. + ''; + }; + + inputConfig = mkOption { + default = {}; + description = '' + An attribute set (or an expression generated by mkNameValuePairs) + representing a logstash configuration's input section. + Logstash configs are name-value pairs, where values can be bools, + strings, numbers, arrays, hashes, or other name-value pairs, + and names are strings that can be repeated. Name-value pairs with no + repeats are represented by attr sets. Bools, strings, ints, and + arrays are mapped directly. Name-value pairs with repeats can be + generated by the config.lib.logstash.mkNameValuePairs function, which + takes a list of attrsets and combines them while preserving attribute + name duplicates if they occur. Similarly, there are the mkFloat and + mkHash functions, which take a string representation of a float and an + attrset, respectively. + ''; + merge = mergeConfigs; + }; + + filterConfig = mkOption { + default = {}; + description = '' + An attribute set (or an expression generated by mkNameValuePairs) + representing a logstash configuration's filter section. + See inputConfig description for details. + ''; + merge = mergeConfigs; + }; + + outputConfig = mkOption { + default = {}; + description = '' + An attribute set (or an expression generated by mkNameValuePairs) + representing a logstash configuration's output section. + See inputConfig description for details. + ''; + merge = mergeConfigs; + }; + }; + }; + + + ###### implementation + + config = mkMerge [ { + lib.logstash = { + mkFloat = stringRep: { __type = "float"; value = stringRep; }; + + mkHash = attrs: { __type = "hash"; value = attrs; }; + + mkNameValuePairs = mergeConfigs; + }; + } ( mkIf cfg.enable { + systemd.services.logstash = with pkgs; { + description = "Logstash daemon"; + + wantedBy = [ "multi-user.target" ]; + + path = [ jre ]; + + script = "cd /tmp && exec java -jar ${logstash} agent -f ${writeText "logstash.conf" '' + input { + ${exprToConfig cfg.inputConfig} + } + + filter { + ${exprToConfig cfg.filterConfig} + } + + output { + ${exprToConfig cfg.outputConfig} + } + ''} &> /var/log/logstash.log"; + }; + })]; +} |