diff options
Diffstat (limited to 'modules/by-name/mo/monitoring/components')
| -rw-r--r-- | modules/by-name/mo/monitoring/components/grafana.nix | 309 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/components/loki.nix | 170 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/components/perses.nix | 17 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/components/prometheus.nix | 272 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/components/scrutiny.nix | 100 |
5 files changed, 0 insertions, 868 deletions
diff --git a/modules/by-name/mo/monitoring/components/grafana.nix b/modules/by-name/mo/monitoring/components/grafana.nix deleted file mode 100644 index 6fe5b70..0000000 --- a/modules/by-name/mo/monitoring/components/grafana.nix +++ /dev/null @@ -1,309 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - cfg = config.vhack.monitoring.grafana; -in { - options.vhack.monitoring.grafana = { - enable = lib.mkEnableOption "grafana"; - - orgId = lib.mkOption { - type = lib.types.int; - description = "Org ID where all vhack related config will be stored."; - default = 1; - }; - - contactPoints = lib.mkOption { - type = lib.types.listOf lib.types.str; - description = "List of email addresses to send alerts to"; - default = []; - }; - - dashboards = lib.mkOption { - type = lib.types.listOf lib.types.path; - description = "dashboards to provision under 'Vhack' folder."; - default = []; - }; - - fqdn = lib.mkOption { - type = lib.types.str; - description = "Domain under which Grafana will be served."; - example = "grafana.example.org"; - }; - - adminPassword = lib.mkOption { - type = lib.types.path; - description = "The age-encrypted initial admin password; passed to agenix"; - }; - - secretKey = lib.mkOption { - type = lib.types.path; - description = "The age-encrypted secret key, used for signing; passed to agenix"; - }; - - port = lib.mkOption { - type = lib.types.port; - description = "Port where Grafana listens to HTTP requests."; - default = 3000; - }; - - debugLog = lib.mkOption { - type = lib.types.bool; - description = "Set to true to enable debug logging of the infrastructure serving Grafana."; - default = false; - example = true; - }; - - smtp = lib.mkOption { - description = "SMTP options."; - default = null; - type = lib.types.nullOr ( - lib.types.submodule { - options = { - from_address = lib.mkOption { - type = lib.types.str; - description = "SMTP address from which the emails originate."; - example = "vaultwarden@mydomain.com"; - }; - from_name = lib.mkOption { - type = lib.types.str; - description = "SMTP name from which the emails originate."; - default = "Grafana"; - }; - host = lib.mkOption { - type = lib.types.str; - description = "SMTP host to send the emails to."; - }; - port = lib.mkOption { - type = lib.types.port; - description = "SMTP port to send the emails to."; - default = 25; - }; - username = lib.mkOption { - type = lib.types.str; - description = "Username to connect to the SMTP host."; - }; - passwordFile = lib.mkOption { - type = lib.types.str; - description = "File containing the password to connect to the SMTP host."; - }; - }; - } - ); - }; - }; - - config = lib.mkIf cfg.enable { - assertions = [ - { - assertion = builtins.length cfg.contactPoints > 0; - message = "Must have at least one contact point for alerting"; - } - ]; - - age.secrets = { - grafanaInitialAdminPw = { - file = cfg.adminPassword; - mode = "0700"; - owner = "grafana"; - group = "grafana"; - }; - grafanaSecretKey = { - file = cfg.secretKey; - mode = "0700"; - owner = "grafana"; - group = "grafana"; - }; - }; - - users = { - groups = { - grafana = { - gid = config.vhack.constants.ids.gids.grafana; - }; - }; - users = { - grafana = { - isSystemUser = true; - group = "grafana"; - uid = lib.mkForce config.vhack.constants.ids.uids.grafana; - }; - }; - }; - - vhack = { - postgresql.enable = true; - - persist.directories = [ - { - directory = "/var/lib/grafana/"; - user = "grafana"; - group = "grafana"; - mode = "0700"; - } - ]; - - monitoring.grafana.dashboards = [ - ../dashboards/node_exporter.json - ../dashboards/performance.json - ../dashboards/scraping_jobs.json - ../dashboards/systemd_exporter.json - ]; - - anubis.instances."${cfg.fqdn}".target = "http://${config.services.grafana.settings.server.http_addr}:${toString cfg.port}"; - }; - - services = { - postgresql = { - ensureUsers = [ - { - name = "grafana"; - ensureDBOwnership = true; - } - ]; - ensureDatabases = [ - "grafana" - ]; - }; - - grafana = { - enable = true; - - settings = { - database = { - host = "/run/postgresql"; - user = "grafana"; - name = "grafana"; - type = "postgres"; - }; - - security = { - secret_key = "$__file{${config.age.secrets.grafanaSecretKey.path}}"; - - disable_initial_admin_creation = false; - admin_password = "$__file{${config.age.secrets.grafanaInitialAdminPw.path}}"; - }; - - server = { - http_addr = "127.0.0.1"; - http_port = cfg.port; - domain = cfg.fqdn; - root_url = "https://${cfg.fqdn}"; - router_logging = cfg.debugLog; - }; - - smtp = lib.mkIf (!(isNull cfg.smtp)) { - enabled = true; - inherit (cfg.smtp) from_address from_name; - host = "${cfg.smtp.host}:${toString cfg.smtp.port}"; - user = cfg.smtp.username; - password = "$__file{${cfg.smtp.passwordFile}}"; - }; - }; - - provision = { - dashboards.settings = lib.mkIf (cfg.dashboards != []) { - apiVersion = 1; - providers = [ - { - folder = "Vhack"; - options.path = pkgs.symlinkJoin { - name = "dashboards"; - paths = map (p: pkgs.runCommand "dashoard" {} "mkdir $out; cp ${p} $out") cfg.dashboards; - }; - allowUiUpdates = true; - disableDeletion = true; - } - ]; - }; - datasources.settings = { - apiVersion = 1; - datasources = [ - { - inherit (cfg) orgId; - name = "Prometheus"; - type = "prometheus"; - url = "http://127.0.0.1:${toString config.services.prometheus.port}"; - uid = "df80f9f5-97d7-4112-91d8-72f523a02b09"; - isDefault = true; - version = 1; - } - { - inherit (cfg) orgId; - name = "Loki"; - type = "loki"; - url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}"; - uid = "cd6cc53e-840c-484d-85f7-96fede324006"; - version = 1; - } - ]; - deleteDatasources = [ - { - inherit (cfg) orgId; - name = "Prometheus"; - } - { - inherit (cfg) orgId; - name = "Loki"; - } - ]; - }; - alerting = { - contactPoints.settings = { - apiVersion = 1; - contactPoints = [ - { - inherit (cfg) orgId; - name = "grafana-default-email"; - receivers = lib.optionals ((builtins.length cfg.contactPoints) > 0) [ - { - uid = "sysadmin"; - type = "email"; - settings.addresses = lib.concatStringsSep ";" cfg.contactPoints; - } - ]; - } - ]; - }; - policies.settings = { - apiVersion = 1; - policies = [ - { - inherit (cfg) orgId; - receiver = "grafana-default-email"; - group_by = [ - "grafana_folder" - "alertname" - ]; - group_wait = "30s"; - group_interval = "5m"; - repeat_interval = "4h"; - } - ]; - # resetPolicies seems to happen after setting the above policies, effectively rolling back - # any updates. - }; - rules.settings = let - rules = builtins.fromJSON (builtins.readFile ../rules.json); - in { - apiVersion = 1; - groups = [ - { - inherit (cfg) orgId; - name = "SysAdmin"; - folder = "Vhack"; - interval = "10m"; - inherit rules; - } - ]; - # deleteRules seems to happen after creating the above rules, effectively rolling back - # any updates. - }; - }; - }; - }; - }; - }; -} diff --git a/modules/by-name/mo/monitoring/components/loki.nix b/modules/by-name/mo/monitoring/components/loki.nix deleted file mode 100644 index 149e577..0000000 --- a/modules/by-name/mo/monitoring/components/loki.nix +++ /dev/null @@ -1,170 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - cfg = config.vhack.monitoring.loki; -in { - options.vhack.monitoring.loki = { - enable = lib.mkEnableOption "loki"; - - port = lib.mkOption { - type = lib.types.port; - description = "Port where Loki listens to HTTP requests."; - default = 3002; - }; - }; - - config = lib.mkIf cfg.enable { - vhack = { - persist.directories = [ - { - directory = "/var/lib/loki"; - user = "loki"; - group = "loki"; - mode = "0700"; - } - { - directory = "/var/lib/fluent-bit"; - user = "fluent-bit"; - group = "fluent-bit"; - mode = "0700"; - } - ]; - }; - - users = { - groups = { - fluent-bit = { - gid = config.vhack.constants.ids.gids.fluent-bit; - }; - loki = { - gid = config.vhack.constants.ids.gids.loki; - }; - }; - users = { - fluent-bit = { - isSystemUser = true; - group = "fluent-bit"; - uid = config.vhack.constants.ids.uids.fluent-bit; - }; - loki = { - isSystemUser = true; - group = "loki"; - uid = config.vhack.constants.ids.uids.loki; - }; - }; - }; - - # I decided to switch to fluent-bit because it can be tested locally https://docs.fluentbit.io/manual/local-testing/logging-pipeline - systemd.services.fluent-bit = { - serviceConfig = { - StateDirectory = "fluent-bit"; - User = "fluent-bit"; - Group = "fluent-bit"; - DynamicUser = lib.mkForce false; - }; - }; - services = { - fluent-bit = { - enable = true; - settings = { - service = { - flush = 1; - log_level = "info"; - http_server = "true"; - http_listen = "127.0.0.1"; - http_port = 9080; - grace = 30; - }; - - pipeline = { - inputs = [ - { - name = "systemd"; - - # The asterisk appends the _SYSTEMD_UNIT to the prefix. - tag = "systemd.*"; - - # Read logs from this systemd journal directory. - path = "/var/log/journal"; - - # Database file to keep track of the journald cursor. - db = "/var/lib/fluent-bit/systemd.db"; - - # Start reading new entries. Skip entries already stored in journald. - read_from_tail = true; - - # Max entries to lookback on start. - max_entries = 10000; - } - ]; - - outputs = [ - { - name = "loki"; - - match = "systemd.*"; - - host = "localhost"; - port = config.services.loki.configuration.server.http_listen_port; - - labels = lib.concatMapAttrsStringSep ", " (n: v: "${n}=${v}") { - job = "systemd-journal"; - inherit (config.vhack.monitoring.grafana) fqdn; - hostname = config.networking.hostName; - }; - - label_keys = "$unit"; - } - ]; - }; - }; - graceLimit = "1m"; - }; - - loki = { - enable = true; - dataDir = "/var/lib/loki"; - package = pkgs.grafana-loki; - configuration = { - auth_enabled = false; - - server.http_listen_port = cfg.port; - - common = { - ring = { - instance_addr = "127.0.0.1"; - kvstore = { - store = "inmemory"; - }; - }; - - replication_factor = 1; - path_prefix = "/tmp/loki"; - }; - - schema_config = { - configs = [ - { - from = "2020-05-15"; - store = "tsdb"; - object_store = "filesystem"; - schema = "v13"; - index = { - prefix = "index_"; - period = "24h"; - }; - } - ]; - }; - - storage_config = { - filesystem.directory = "/tmp/loki/chunks"; - }; - }; - }; - }; - }; -} diff --git a/modules/by-name/mo/monitoring/components/perses.nix b/modules/by-name/mo/monitoring/components/perses.nix deleted file mode 100644 index b0f1ab6..0000000 --- a/modules/by-name/mo/monitoring/components/perses.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - cfg = config.vhack.monitoring.perses; -in { - options.vhack.monitoring.perses = { - enable = lib.mkEnableOption "perses"; - }; - config = lib.mkIf cfg.enable { - services.perses = { - enable = true; - }; - }; -} diff --git a/modules/by-name/mo/monitoring/components/prometheus.nix b/modules/by-name/mo/monitoring/components/prometheus.nix deleted file mode 100644 index ca947d3..0000000 --- a/modules/by-name/mo/monitoring/components/prometheus.nix +++ /dev/null @@ -1,272 +0,0 @@ -{ - lib, - config, - nixLib, - ... -}: let - cfg = config.vhack.monitoring.prometheus; - - commonLabels = { - hostname = config.networking.hostName; - }; - - prom_cfg = config.services.prometheus; -in { - options.vhack.monitoring.prometheus = { - enable = lib.mkEnableOption "prometheus"; - - port = lib.mkOption { - type = lib.types.port; - description = "Port where Prometheus listens to HTTP requests."; - default = 3001; - }; - - remoteWriteReceiver = lib.mkOption { - example = "https://prometheus.server2.vhack.eu"; - type = lib.types.nullOr lib.types.str; - default = null; - description = '' - If not null, this prometheus server will be exposed via a reverse proxy and allow - other prometheus servers to write metrics to it. - ''; - }; - remoteWriteTo = lib.mkOption { - example = "https://prometheus.server3.vhack.eu"; - type = lib.types.nullOr (lib.types.submodule { - options = { - port = lib.mkOption { - type = lib.types.nullOr lib.types.port; - default = null; - }; - url = lib.mkOption { - type = lib.types.str; - }; - }; - }); - default = null; - description = '' - If not null, this prometheus server will run in agent mode, writing all recived - metrics to the specified remote prometheus server. - ''; - }; - - sources = lib.mkOption { - type = lib.types.listOf (lib.types.submodule { - options = { - name = lib.mkOption { - type = lib.types.str; - }; - target = lib.mkOption { - type = lib.types.str; - description = "The target url to scrape from."; - }; - extra = lib.mkOption { - type = lib.types.attrsOf lib.types.anything; - }; - }; - }); - }; - }; - - config = lib.mkIf cfg.enable { - vhack = { - nginx.enable = true; - - persist.directories = [ - { - directory = "/var/lib/prometheus2"; - user = "prometheus"; - group = "prometheus"; - mode = "0700"; - } - ]; - - monitoring.prometheus.sources = [ - { - name = "node"; - target = "127.0.0.1:${toString prom_cfg.exporters.node.port}"; - } - { - name = "prometheus_internal"; - target = "127.0.0.1:${toString prom_cfg.port}"; - } - { - name = "systemd"; - target = "127.0.0.1:${toString prom_cfg.exporters.systemd.port}"; - } - ]; - }; - - services.nginx = lib.mkIf (cfg.remoteWriteReceiver != null) { - virtualHosts.${cfg.remoteWriteReceiver} = { - locations."/" = { - proxyPass = "http://127.0.0.1:${toString cfg.port}/api/v1/write"; - - recommendedProxySettings = true; - proxyWebsockets = true; - }; - - enableACME = true; - forceSSL = true; - }; - }; - - users = { - groups = { - node-exporter.gid = config.vhack.constants.ids.gids.node-exporter; - }; - users = { - node-exporter = { - isSystemUser = true; - group = "node-exporter"; - uid = config.vhack.constants.ids.uids.node-exporter; - }; - }; - }; - - services = { - prometheus = { - enable = true; - inherit (cfg) port; - - globalConfig = { - scrape_interval = "15s"; - }; - remoteWrite = lib.optionals (cfg.remoteWriteTo != null) [ - { - url = let - port = - if (cfg.remoteWriteTo.port != null) - then ":${toString cfg.remoteWriteTo.port}" - else ""; - in "${cfg.remoteWriteTo.url}${port}"; - # TODO: Needs RFC42 for prometheus <2026-07-19> - # protobuf_message = "io.prometheus.write.v2.Request"; - } - ]; - - enableAgentMode = cfg.remoteWriteTo != null; - extraFlags = lib.mkMerge [ - ( - lib.mkIf (cfg.remoteWriteReceiver != null) [ - "--web.enable-remote-write-receiver" - # "--web.remote-write-receiver.accepted-protobuf-messages=io.prometheus.write.v2.Request" - ] - ) - ]; - - scrapeConfigs = builtins.map (attr: - nixLib.warnMerge { - job_name = attr.name; - static_configs = [ - { - targets = [attr.target]; - labels = commonLabels; - } - ]; - } - attr.extra "prometheus scrapeConfig '${attr.name}'") - cfg.sources; - # ++ (lib.optional (builtins.length (lib.attrNames config.services.redis.servers) > 0) { - # job_name = "redis"; - # static_configs = [ - # { - # targets = ["127.0.0.1:${toString config.services.prometheus.exporters.redis.port}"]; - # } - # ]; - # }) ++ (lib.optional (builtins.length (lib.attrNames config.services.openvpn.servers) > 0) { - # job_name = "openvpn"; - # static_configs = [ - # { - # targets = ["127.0.0.1:${toString config.services.prometheus.exporters.openvpn.port}"]; - # } - # ]; - # }) - # ++ (lib.optional config.services.dnsmasq.enable { - # job_name = "dnsmasq"; - # static_configs = [ - # { - # targets = ["127.0.0.1:${toString config.services.prometheus.exporters.dnsmasq.port}"]; - # labels = commonLabels; - # } - # ]; - # }); - - exporters = { - node = { - enable = true; - # https://github.com/prometheus/node_exporter#collectors - enabledCollectors = [ - "arp" - "cpu" - "cpufreq" - "diskstats" - "dmi" - "edac" - "entropy" - "filefd" - "filesystem" - "hwmon" - "loadavg" - "meminfo" - "netclass" - "netdev" - "netstat" - "nvme" - "os" - "pressure" - "rapl" - "schedstat" - "stat" - "thermal_zone" - "time" - "uname" - "vmstat" - "zfs" - - # Disabled by default - "cgroups" - "drm" - "ethtool" - "logind" - "wifi" - ]; - port = 9112; - listenAddress = "127.0.0.1"; - }; - # services.prometheus.exporters.redis = lib.mkIf (builtins.length (lib.attrNames config.services.redis.servers) > 0) { - # enable = true; - # port = 9119; - # listenAddress = "127.0.0.1"; - # }; - # services.prometheus.exporters.openvpn = lib.mkIf (builtins.length (lib.attrNames config.services.openvpn.servers) > 0) { - # enable = true; - # port = 9121; - # listenAddress = "127.0.0.1"; - # statusPaths = lib.mapAttrsToList (name: _config: "/tmp/openvpn/${name}.status") config.services.openvpn.servers; - # }; - # dnsmasq = lib.mkIf config.services.dnsmasq.enable { - # enable = true; - # port = 9211; - # listenAddress = "127.0.0.1"; - # }; - systemd = { - enable = true; - port = 9116; - listenAddress = "127.0.0.1"; - extraFlags = [ - "--log.level=info" - "--web.disable-exporter-metrics" - # "--systemd.collector.enable-resolved" - "--systemd.collector.enable-restart-count" - # "--systemd.collector.enable-file-descriptor-size" - "--systemd.collector.enable-ip-accounting" - "--systemd.collector.unit-include=\".+\"" - "--systemd.collector.unit-exclude=\".+\\\\.(device)\"" - ]; - }; - }; - }; - }; - }; -} diff --git a/modules/by-name/mo/monitoring/components/scrutiny.nix b/modules/by-name/mo/monitoring/components/scrutiny.nix deleted file mode 100644 index adb515e..0000000 --- a/modules/by-name/mo/monitoring/components/scrutiny.nix +++ /dev/null @@ -1,100 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: let - cfg = config.vhack.monitoring.scrutiny; -in { - options.vhack.monitoring.scrutiny = { - enable = lib.mkEnableOption "scrutiny service"; - }; - - # We don't currently _care_ about the health of the hardware, because hetzner does - # this for us (nor can we care, because it's not exposed in the VPS) - config = lib.mkIf false { - vhack.monitoring = { - prometheus.sources = [ - { - name = "scrutiny"; - extra.metrics_path = "/api/metrics"; - target = "127.0.0.1:${toString config.services.scrutiny.settings.web.listen.port}"; - } - { - name = "smartctl"; - target = "127.0.0.1:${toString config.services.prometheus.exporters.smartctl.port}"; - } - ]; - grafana.dashboards = [ - ../dashboards/Health.json - ]; - }; - - users = { - groups = { - smartctl-exporter-access.gid = config.vhack.constants.ids.gids.smartctl-exporter-access; - }; - users = { - smartctl-exporter-access = { - isSystemUser = true; - group = "smartctl-exporter-access"; - uid = config.vhack.constants.ids.uids.smartctl-exporter-access; - }; - }; - }; - - services = { - scrutiny = { - enable = true; - - openFirewall = false; - - # This src includes Prometheus metrics exporter. - package = pkgs.scrutiny.overrideAttrs { - src = pkgs.fetchFromGitHub { - owner = "ibizaman"; - repo = "scrutiny"; - rev = "74faf06f77df83f29e7e1806cd88b2fafc0bbb82"; - hash = "sha256-r0AVWL+E046xHxitwMPfRNTOpjuOk+W6tB41YgmLTPg="; - }; - - vendorHash = "sha256-kAlnlWnBMFCdgdak5L5hRquRtyLi5MTmDa/kxwqPs4E="; - }; - - settings = { - web = { - metrics.enabled = true; # Enables Prometheus exporter - listenHost = "127.0.0.1"; - }; - }; - - collector = { - enable = true; - }; - }; - prometheus = { - exporters.smartctl = { - enable = true; - port = 9115; - listenAddress = "127.0.0.1"; - }; - }; - }; - - # nixpkgs.overlays = [ - # (final: prev: { - # prometheus-systemd-exporter = prev.prometheus-systemd-exporter.overrideAttrs { - # src = final.fetchFromGitHub { - # owner = "ibizaman"; - # repo = prev.prometheus-systemd-exporter.pname; - # # rev = "v${prev.prometheus-systemd-exporter.version}"; - # rev = "next_timer"; - # sha256 = "sha256-jzkh/616tsJbNxFtZ0xbdBQc16TMIYr9QOkPaeQw8xA="; - # }; - # - # vendorHash = "sha256-4hsQ1417jLNOAqGkfCkzrmEtYR4YLLW2j0CiJtPg6GI="; - # }; - # }) - # ]; - }; -} |
