diff options
Diffstat (limited to 'krebs/5pkgs/simple/logf')
-rw-r--r-- | krebs/5pkgs/simple/logf/default.nix | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/krebs/5pkgs/simple/logf/default.nix b/krebs/5pkgs/simple/logf/default.nix new file mode 100644 index 000000000..ac95acb33 --- /dev/null +++ b/krebs/5pkgs/simple/logf/default.nix @@ -0,0 +1,114 @@ +{ lib, pkgs, ... }: + +with import <stockholm/lib>; + +let + default-host-colors = pkgs.writeJSON "logf.default-host-colors.json" { + }; + default-prio-colors = pkgs.writeJSON "logf.default-prio-colors.json" { + "0" = 196; # emerg + "1" = 160; # alert + "2" = 124; # crit + "3" = 009; # err + "4" = 011; # warning + "5" = 255; # notice + "6" = 250; # info + "7" = 139; # debug + "-" = 005; # undefined priority + }; + default-urgent = pkgs.writeJSON "logf.default-urgent.json" [ + ]; +in + +pkgs.writeDashBin "logf" '' + export LOGF_HOST_COLORS LOGF_PRIO_COLORS LOGF_URGENT + LOGF_HOST_COLORS=$(cat "''${LOGF_HOST_COLORS-${default-host-colors}}") + LOGF_PRIO_COLORS=$(cat "''${LOGF_PRIO_COLORS-${default-prio-colors}}") + LOGF_URGENT=$(cat "''${LOGF_URGENT-${default-urgent}}") + printf '%s\0' "$@" \ + | ${pkgs.findutils}/bin/xargs -0 -P 0 -n 1 ${pkgs.writeDash "logf-remote" '' + target=$1 + target_host=$(echo "$1" | sed 's/^.*@//;s/\..*//') + exec 3>&1 + 2>&1 1>&3 ssh "$target" -T \ + -o PreferredAuthentications=publickey \ + -o StrictHostKeyChecking=yes \ + exec journalctl -af -n 0 -o json \ + | stdbuf -oL jq -Rcf ${pkgs.writeJq "logf-remote-error.jq" '' + { + PRIORITY: "4", + MESSAGE: ., + SYSLOG_IDENTIFIER: env.target_host, + } + ''} + sleep 10m + exec "$0" "$@" + ''} \ + | ${pkgs.jq}/bin/jq -Rrf ${pkgs.writeJq "logf-filter.jq" '' + (env.LOGF_HOST_COLORS | fromjson) as $host_colors | + (env.LOGF_PRIO_COLORS | fromjson) as $prio_colors | + (env.LOGF_URGENT | fromjson | map("(\(.))") | join("|")) + as $urgent_regex | + + def when(c; f): if c then f else . end; + + # anaphoric gsub + def agsub(re; f): + # Don't try empty regex: https://github.com/stedolan/jq/issues/1206 + when(re != ""; gsub("(?<it>\(re))"; .it | f)); + + # :: [int] -> sgr + def sgr: "\u001b[\(map(tostring) | join(";"))m"; + + # :: sgr + def rst: [] | sgr; + + # :: int -> sgr + def fg(i): [38,5,i]|sgr; + # TODO def fg(r;g;b): [38,2,r,g,b]|sgr; + # http://cvs.schmorp.de/rxvt-unicode/src/command.C?revision=1.570&view=markup&sortby=log&sortdir=down + + # (sgr; sgr) | (null; any) :: str -> str + def col(a; b): when(a != null; a + . + b); + def col(a): col(a; rst); + + + def p_time: + ._SOURCE_REALTIME_TIMESTAMP + | if . != null then . | fromjson | . / 1000000 else now end + | gmtime + | todateiso8601 + | col(fg(237)); + + def p_host: + ._HOSTNAME + | if . != null then . else "-" end + | col($host_colors[.]|when(. != null; fg(.))); + + def p_ident: + if .SYSLOG_IDENTIFIER != null then .SYSLOG_IDENTIFIER + else ._COMM end + | col(fg(244)); + + def p_message: + fg($prio_colors[if has("PRIORITY") then .PRIORITY else "-" end]) + as $prio_c | + .MESSAGE + | sub("\r$"; "") + | agsub($urgent_regex; "\(.)\u0007" | col(fg(219); $prio_c)) + | col($prio_c); + + try fromjson catch { + _SOURCE_REALTIME_TIMESTAMP: now | tostring | sub("[.]"; ""), + SYSLOG_IDENTIFIER: "logf/journalctl", + MESSAGE: ., + } | + + [ p_time + , p_host + , p_ident + , p_message + ] + | join(" ") + ''} +'' |