{ config, lib, this, ... }: with lib; let cfg = config.nixfiles.modules.promtail; in { options.nixfiles.modules.promtail = { enable = mkEnableOption "Promtail"; loki = { url = mkOption { description = "Address of a listening Loki service."; type = with types; str; default = "https://${config.nixfiles.modules.loki.domain}"; }; }; }; config = mkIf cfg.enable { services.promtail = { enable = true; configuration = { server = rec { http_listen_address = this.wireguard.ipv4.address; http_listen_port = 30181; grpc_listen_address = this.wireguard.ipv4.address; grpc_listen_port = http_listen_port + 1; log_level = "warn"; }; clients = [ { url = "${cfg.loki.url}/loki/api/v1/push"; external_labels.host_id = config.networking.hostId; } ]; positions.filename = "/tmp/positions.yaml"; scrape_configs = [ { job_name = "journal"; journal.max_age = "24h"; relabel_configs = map (n: let label = toLower n; in { source_labels = ["__journal_${label}"]; target_label = if hasPrefix "_" label then substring 1 (stringLength label - 1) label else label; }) [ # Derived from systemd.journal fields[1][2]. # # [1]: https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html # [2]: https://github.com/coreos/go-systemd/blob/main/sdjournal/journal.go#L335 "MESSAGE" "MESSAGE_ID" "PRIORITY" # "CODE_FILE" # "CODE_LINE" # "CODE_FUNC" "ERRNO" "SYSLOG_FACILITY" "SYSLOG_IDENTIFIER" "SYSLOG_PID" "_PID" "_UID" "_GID" # "_COMM" # "_EXE" "_CMDLINE" # "_CAP_EFFECTIVE" # "_AUDIT_SESSION" # "_AUDIT_LOGINUID" # "_SYSTEMD_CGROUP" # "_SYSTEMD_SESSION" "_SYSTEMD_UNIT" "_SYSTEMD_USER_UNIT" # "_SYSTEMD_OWNER_UID" # "_SYSTEMD_SLICE" # "_SELINUX_CONTEXT" # "_SOURCE_REALTIME_TIMESTAMP" "_BOOT_ID" "_MACHINE_ID" "_HOSTNAME" "_TRANSPORT" # "__CURSOR" # "__REALTIME_TIMESTAMP" # "__MONOTONIC_TIMESTAMP" ]; } ]; }; }; }; }