diff --git a/hosts/common/core/default.nix b/hosts/common/core/default.nix index 36dc1b2..69c8708 100644 --- a/hosts/common/core/default.nix +++ b/hosts/common/core/default.nix @@ -12,9 +12,11 @@ ../../../users/root + ../../../modules/distributed-config.nix ../../../modules/extra.nix ../../../modules/interface-naming.nix ../../../modules/microvms.nix + ../../../modules/promtail.nix ../../../modules/repo.nix ../../../modules/wireguard.nix ]; diff --git a/hosts/ward/promtail.nix b/hosts/ward/promtail.nix deleted file mode 100644 index 2676039..0000000 --- a/hosts/ward/promtail.nix +++ /dev/null @@ -1,129 +0,0 @@ -{ - config, - lib, - nodeName, - nodes, - parentNodeName, - ... -}: let - inherit (nodes.sentinel.config.repo.secrets.local) personalDomain; - lokiDomain = "loki.${personalDomain}"; -in { - age.secrets.loki-basic-auth-password = { - rekeyFile = ./secrets/loki-basic-auth-password.age; - generator = "alnum"; - mode = "440"; - group = "promtail"; - }; - - services.promtail = { - enable = true; - configuration = { - server = { - http_listen_port = 9080; - grpc_listen_port = 0; - log_level = "warn"; - }; - - clients = [ - { - basicAuthUser = nodeName; - basic_auth.password_file = config.age.secrets.loki-basic-auth-password.path; - url = "https://${lokiDomain}/loki/api/v1/push"; - } - ]; - - scrape_configs = [ - { - job_name = "journal"; - journal = { - json = true; - max_age = "24h"; - labels.job = "systemd-journal"; - }; - pipeline_stages = [ - { - json.expressions = { - transport = "_TRANSPORT"; - unit = "_SYSTEMD_UNIT"; - msg = "MESSAGE"; - coredump_cgroup = "COREDUMP_CGROUP"; - coredump_exe = "COREDUMP_EXE"; - coredump_cmdline = "COREDUMP_CMDLINE"; - coredump_uid = "COREDUMP_UID"; - coredump_gid = "COREDUMP_GID"; - }; - } - { - # Set the unit (defaulting to the transport like audit and kernel) - template = { - source = "unit"; - template = "{{if .unit}}{{.unit}}{{else}}{{.transport}}{{end}}"; - }; - } - { - regex = { - expression = "(?P[^/]+)$"; - source = "coredump_cgroup"; - }; - } - { - template = { - source = "msg"; - template = "{{if .coredump_exe}}{{.coredump_exe}} core dumped (user: {{.coredump_uid}}/{{.coredump_gid}}, command: {{.coredump_cmdline}}){{else}}{{.msg}}{{end}}"; - }; - } - { - labels.coredump_unit = "coredump_unit"; - } - { - # Normalize session IDs (session-1234.scope -> session.scope) to limit number of label values - replace = { - source = "unit"; - expression = "^(session-\\d+.scope)$"; - replace = "session.scope"; - }; - } - { - labels.unit = "unit"; - } - { - # Write the proper message instead of JSON - output.source = "msg"; - } - ]; - relabel_configs = [ - { - source_labels = ["__journal__hostname"]; - target_label = "host"; - } - { - source_labels = ["__journal_priority"]; - target_label = "priority"; - } - { - source_labels = ["__journal_priority_keyword"]; - target_label = "level"; - } - #{ - # source_labels = ["__journal__systemd_unit"]; - # target_label = "unit"; - #} - { - source_labels = ["__journal__systemd_user_unit"]; - target_label = "user_unit"; - } - { - source_labels = ["__journal__boot_id"]; - target_label = "boot_id"; - } - { - source_labels = ["__journal__comm"]; - target_label = "command"; - } - ]; - } - ]; - }; - }; -} diff --git a/modules/promtail.nix b/modules/promtail.nix new file mode 100644 index 0000000..791a01c --- /dev/null +++ b/modules/promtail.nix @@ -0,0 +1,151 @@ +{ + config, + lib, + nodeName, + nodePath, + nodes, + ... +}: let + inherit + (lib) + mdDoc + mkEnableOption + mkIf + mkOption + types + ; + + cfg = config.extra.promtail; +in { + options.extra.promtail = { + enable = mkEnableOption (mdDoc "Enable promtail to push logs to a loki instance."); + proxy = mkOption { + type = types.str; + description = mdDoc "The node name of the proxy server which provides the https loki api endpoint."; + }; + }; + + config = mkIf cfg.enable { + age.secrets.promtail-loki-basic-auth-password = { + rekeyFile = nodePath + "/secrets/promtail-loki-basic-auth-password.age"; + generator = "alnum"; + mode = "440"; + group = "promtail"; + }; + + nodes.${cfg.proxy}.age.secrets.loki-basic-auth-hashes.generator.dependencies = [ + config.age.secrets.promtail-loki-basic-auth-password + ]; + + services.promtail = { + enable = true; + configuration = { + server = { + http_listen_port = 9080; + grpc_listen_port = 0; + log_level = "warn"; + }; + + clients = [ + { + basicAuthUser = nodeName; + basic_auth.password_file = config.age.secrets.loki-basic-auth-password.path; + url = "https://${nodes.${cfg.proxy}.config.proxiedDomains.loki}/loki/api/v1/push"; + } + ]; + + scrape_configs = [ + { + job_name = "journal"; + journal = { + json = true; + max_age = "24h"; + labels.job = "systemd-journal"; + }; + pipeline_stages = [ + { + json.expressions = { + transport = "_TRANSPORT"; + unit = "_SYSTEMD_UNIT"; + msg = "MESSAGE"; + coredump_cgroup = "COREDUMP_CGROUP"; + coredump_exe = "COREDUMP_EXE"; + coredump_cmdline = "COREDUMP_CMDLINE"; + coredump_uid = "COREDUMP_UID"; + coredump_gid = "COREDUMP_GID"; + }; + } + { + # Set the unit (defaulting to the transport like audit and kernel) + template = { + source = "unit"; + template = "{{if .unit}}{{.unit}}{{else}}{{.transport}}{{end}}"; + }; + } + { + regex = { + expression = "(?P[^/]+)$"; + source = "coredump_cgroup"; + }; + } + { + template = { + source = "msg"; + template = "{{if .coredump_exe}}{{.coredump_exe}} core dumped (user: {{.coredump_uid}}/{{.coredump_gid}}, command: {{.coredump_cmdline}}){{else}}{{.msg}}{{end}}"; + }; + } + { + labels.coredump_unit = "coredump_unit"; + } + { + # Normalize session IDs (session-1234.scope -> session.scope) to limit number of label values + replace = { + source = "unit"; + expression = "^(session-\\d+.scope)$"; + replace = "session.scope"; + }; + } + { + labels.unit = "unit"; + } + { + # Write the proper message instead of JSON + output.source = "msg"; + } + ]; + relabel_configs = [ + { + source_labels = ["__journal__hostname"]; + target_label = "host"; + } + { + source_labels = ["__journal_priority"]; + target_label = "priority"; + } + { + source_labels = ["__journal_priority_keyword"]; + target_label = "level"; + } + #{ + # source_labels = ["__journal__systemd_unit"]; + # target_label = "unit"; + #} + { + source_labels = ["__journal__systemd_user_unit"]; + target_label = "user_unit"; + } + { + source_labels = ["__journal__boot_id"]; + target_label = "boot_id"; + } + { + source_labels = ["__journal__comm"]; + target_label = "command"; + } + ]; + } + ]; + }; + }; + }; +}