{ config, lib, ... }: let cfg = config.os.srv.vector; in { options.os.srv.vector = { enable = lib.mkEnableOption "Vector observability data framework"; agent.enable = lib.mkEnableOption "local client daemon to pull journals & stream upstream"; aggregator.enable = lib.mkEnableOption "central receiver role to bundle, parse, and push to Loki"; }; config = lib.mkIf cfg.enable { services.vector = { enable = true; journaldAccess = lib.mkIf cfg.agent.enable true; validateConfig = true; settings = lib.mkMerge [ (lib.mkIf cfg.agent.enable { sources.systemd_journal = { type = "journald"; exclude_units = [ "vector.service" ]; }; transforms.filter_logs = { type = "filter"; inputs = [ "systemd_journal" ]; condition = ''.status != "debug" && .status != "trace"''; }; sinks.to_aggregator = { type = "vector"; inputs = [ "filter_logs" ]; address = "${config.os.core.network.ips.vm3-monitor}:9000"; }; }) (lib.mkIf cfg.aggregator.enable { sources.upstream_agents = { type = "vector"; address = "0.0.0.0:9000"; version = "2"; }; sources.opnsense_syslog = { type = "syslog"; address = "${cfg.aggregator.listenAddress}:5140"; mode = "udp"; }; sinks.loki_backend = { type = "loki"; inputs = [ "upstream_agents" "opnsense_syslog" ]; endpoint = "http://127.0.0.1:3100"; labels = { host = "{{ host }}"; unit = "{{`{{_SYSTEMD_UNIT}}`}}"; source_type = "{{ type }}"; }; buffer = { type = "disk"; max_size = 5 * (1024 * 1024 * 1024); when_full = "block"; }; }; encoding.codec = "json"; }) ]; }; networking.firewall = lib.mkIf cfg.aggregator.enable { allowedTCPPorts = [ 9000 ]; allowedUDPPorts = [ 5140 ]; }; }; }