From e6ed60548397627bf10f561f9438201dbba0a36e Mon Sep 17 00:00:00 2001 From: Azat Bahawi Date: Sun, 21 Apr 2024 02:15:42 +0300 Subject: 2024-04-21 --- modules/promtail.nix | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 modules/promtail.nix (limited to 'modules/promtail.nix') diff --git a/modules/promtail.nix b/modules/promtail.nix new file mode 100644 index 0000000..65d88d4 --- /dev/null +++ b/modules/promtail.nix @@ -0,0 +1,135 @@ +{ + config, + lib, + this, + ... +}: +with lib; +let + cfg = config.nixfiles.modules.promtail; +in +{ + options.nixfiles.modules.promtail = { + enable = mkEnableOption "Promtail"; + + port = mkOption { + description = "Port."; + type = with types; port; + default = 30181; + }; + + loki.url = mkOption { + description = "Address of a listening Loki service."; + type = with types; str; + default = "https://${config.nixfiles.modules.loki.domain}"; + }; + + filters = mkOption { + description = ''Filters to use with "scrape_config.pipeline_stages".''; + type = with types; listOf attrs; + default = [ ]; + }; + }; + + config = mkIf cfg.enable { + services.promtail = { + enable = true; + + configuration = { + server = rec { + http_listen_address = this.wireguard.ipv4.address; + http_listen_port = cfg.port; + + 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"; + batchwait = "30s"; + batchsize = 100000; + external_labels.host_id = config.networking.hostId; + } + ]; + + positions = { + filename = "/tmp/positions.yaml"; + sync_period = "30s"; + ignore_invalid_yaml = true; + }; + + 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]. + # + # [1]: https://github.com/coreos/go-systemd/blob/main/sdjournal/journal.go#L335 + # [1]: https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html + + "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" + ] + ++ [ + { + # This is weird. I can't find where is this defined in the + # source code but apparently it exists. + source_labels = [ "__journal_priority_keyword" ]; + target_label = "level"; + } + ]; + pipeline_stages = cfg.filters; + } + ]; + }; + }; + }; +} -- cgit v1.2.3