{ config, lib, ... }: with lib; let cfg = config.modules.services.metrics; in { options.modules.services.metrics = { enable = mkEnableOption "metrics"; realHost = mkOption { type = types.str; }; tls.acmeHost = mkOption { type = types.str; default = cfg.realHost; }; secrets.adminPassword = mkOption { type = types.path; description = "path to the admin password"; }; }; config = mkIf cfg.enable { services.prometheus = { enable = true; port = 9001; exporters = { node = { enable = true; enabledCollectors = [ "systemd" ]; port = 9002; }; }; scrapeConfigs = [ { job_name = "node"; static_configs = [{ targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ]; }]; } ]; }; services.loki = { enable = true; configuration = { auth_enabled = false; server.http_listen_port = 3100; ingester = { lifecycler = { address = "127.0.0.1"; ring.kvstore.store = "inmemory"; ring.replication_factor = 1; final_sleep = "0s"; }; chunk_idle_period = "1h"; max_chunk_age = "1h"; chunk_target_size = 1048576; # 1.5M chunk_retain_period = "30s"; max_transfer_retries = 0; }; schema_config.configs = [ { from = "2023-02-24"; store = "boltdb-shipper"; object_store = "filesystem"; schema = "v11"; index = { prefix = "index_"; period = "24h"; }; } ]; storage_config = { boltdb_shipper = { active_index_directory = "/var/lib/loki/boltdb-shipper-active"; cache_location = "/var/lib/loki/boltdb-shipper-cache"; cache_ttl = "24h"; shared_store = "filesystem"; }; filesystem.directory = "/var/lib/loki/chunks"; }; limits_config = { reject_old_samples = true; reject_old_samples_max_age = "168h"; retention_period = "120h"; }; chunk_store_config = { max_look_back_period = "0s"; }; table_manager = { retention_deletes_enabled = true; retention_period = "120h"; }; compactor = { working_directory = "/var/lib/loki"; shared_store = "filesystem"; compactor_ring.kvstore.store = "inmemory"; }; }; }; services.promtail = { enable = true; configuration = { server = { http_listen_port = 3031; grpc_listen_port = 0; }; positions.filename = "/tmp/positions.yaml"; clients = [ { url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push"; } ]; scrape_configs = [ { job_name = "journal"; journal = { max_age = "12h"; labels = { job = "systemd-journal"; host = config.networking.hostName; }; }; relabel_configs = [ { source_labels = [ "__journal__systemd_unit" ]; target_label = "unit"; } ]; } ]; }; }; services.grafana = { enable = true; settings.server.http_addr = "127.0.0.1"; settings.server.http_port = 2342; settings.server.domain = cfg.realHost; settings.security.admin_password = "$__file{${cfg.secrets.adminPassword}}"; }; services.nginx.virtualHosts.${cfg.realHost} = { forceSSL = true; useACMEHost = cfg.tls.acmeHost; locations."/" = { proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}"; proxyWebsockets = true; extraConfig = '' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header Host $host; ''; }; }; modules.persistence.directories = [ "/var/lib/prometheus2" "/var/lib/loki" "/var/lib/grafana" ]; }; }