diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-07-19 03:14:35 +0200 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-07-19 03:16:20 +0200 |
| commit | 3ef5db455a46095196191ed10509d000a0f29dc1 (patch) | |
| tree | a2de40425b3e13650976d54009217f6142a444e0 | |
| parent | flake.lock: Update (diff) | |
| download | nixos-server-3ef5db455a46095196191ed10509d000a0f29dc1.zip | |
{modules,test}/monitoring: Init basic version
| -rw-r--r-- | modules/by-name/mo/monitoring/components/grafana.nix | 296 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/components/loki.nix | 122 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/components/perses.nix | 17 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/components/prometheus.nix | 192 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/components/scrutiny.nix | 106 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/dashboards/Errors.json | 811 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/dashboards/Health.json | 872 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/dashboards/Performance.json | 1606 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/dashboards/Scraping_Jobs.json | 334 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/module.nix | 31 | ||||
| -rw-r--r-- | modules/by-name/mo/monitoring/rules.json | 386 | ||||
| -rw-r--r-- | modules/by-name/ng/nginx/module.nix | 24 | ||||
| -rw-r--r-- | tests/by-name/mo/monitoring/test.nix | 76 |
13 files changed, 4870 insertions, 3 deletions
diff --git a/modules/by-name/mo/monitoring/components/grafana.nix b/modules/by-name/mo/monitoring/components/grafana.nix new file mode 100644 index 0000000..5459878 --- /dev/null +++ b/modules/by-name/mo/monitoring/components/grafana.nix @@ -0,0 +1,296 @@ +{ + 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"; + }; + }; + + vhack = { + postgresql.enable = true; + monitoring.grafana.dashboards = [ + ../dashboards/Errors.json + ../dashboards/Performance.json + ../dashboards/Scraping_Jobs.json + ]; + }; + + services = { + nginx = { + virtualHosts.${cfg.fqdn} = { + locations."/" = { + proxyPass = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}"; + proxyWebsockets = true; + extraConfig = '' + proxy_set_header Host $host; + ''; + }; + + forceSSL = true; + enableACME = true; + }; + }; + + 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 "davhackoard" {} "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 new file mode 100644 index 0000000..9a285c5 --- /dev/null +++ b/modules/by-name/mo/monitoring/components/loki.nix @@ -0,0 +1,122 @@ +{ + 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 { + services = { + 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"; + }; + }; + }; + + # I decided to switch to fluent-bit because it can be tested locally https://docs.fluentbit.io/manual/local-testing/logging-pipeline + 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/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"; + }; + }; + }; +} diff --git a/modules/by-name/mo/monitoring/components/perses.nix b/modules/by-name/mo/monitoring/components/perses.nix new file mode 100644 index 0000000..b0f1ab6 --- /dev/null +++ b/modules/by-name/mo/monitoring/components/perses.nix @@ -0,0 +1,17 @@ +{ + 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 new file mode 100644 index 0000000..468ece3 --- /dev/null +++ b/modules/by-name/mo/monitoring/components/prometheus.nix @@ -0,0 +1,192 @@ +{ + lib, + config, + nixLib, + ... +}: let + cfg = config.vhack.monitoring.prometheus; + + commonLabels = { + hostname = config.networking.hostName; + inherit (config.vhack.monitoring.grafana) fqdn; + }; + + 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; + }; + + 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; + }; + extra = lib.mkOption { + type = lib.types.attrsOf lib.types.anything; + }; + }; + }); + }; + }; + + config = lib.mkIf cfg.enable { + vhack = { + nginx.enable = true; + monitoring.prometheus.sources = [ + { + name = "node"; + target = "127.0.0.1:${toString prom_cfg.exporters.node.port}"; + } + { + name = "smartctl"; + target = "127.0.0.1:${toString prom_cfg.exporters.smartctl.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}"; + } + { + name = "netdata"; + target = "127.0.0.1:19999"; + extra = { + metrics_path = "/api/v1/allmetrics"; + params.format = ["prometheus"]; + honor_labels = true; + }; + } + ]; + }; + + services = { + prometheus = { + enable = true; + inherit (cfg) port; + + globalConfig = { + scrape_interval = "15s"; + }; + + scrapeConfigs = builtins.map (attr: + nixLib.warnMerge { + job_name = attr.name; + static_configs = [ + { + targets = [attr.target]; + labels = commonLabels; + } + ]; + } + attr.extra "prometheus scrapeConfig") + 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"; + }; + smartctl = { + enable = true; + port = 9115; + 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"; + }; + }; + }; + }; + }; +} diff --git a/modules/by-name/mo/monitoring/components/scrutiny.nix b/modules/by-name/mo/monitoring/components/scrutiny.nix new file mode 100644 index 0000000..31871cd --- /dev/null +++ b/modules/by-name/mo/monitoring/components/scrutiny.nix @@ -0,0 +1,106 @@ +{ + config, + pkgs, + lib, + ... +}: let + cfg = config.vhack.monitoring.scrutiny; +in { + options.vhack.monitoring.scrutiny = { + enable = lib.mkEnableOption "scrutiny service"; + + fqdn = lib.mkOption { + type = lib.types.nullOr lib.types.str; + description = '' + If a string, this will be the domain under which the scrutiny web interface will be servced. + + If null, the web interface will not be served and only the prometheus metrics will be accessible. + ''; + }; + }; + + config = { + vhack.monitoring = { + prometheus.sources = [ + { + name = "scrutiny"; + extra.metrics_path = "/api/metrics"; + target = "127.0.0.1:${toString config.services.scrutiny.settings.web.listen.port}"; + } + ]; + grafana.dashboards = [ + ../dashboards/Health.json + ]; + }; + + 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; + }; + }; + + # nginx.statusPage = lib.mkDefault config.services.nginx.enable; + nginx = lib.mkIf (cfg.fqdn != null) { + virtualHosts."${cfg.fqdn}" = { + locations."/".proxyPass = "http://127.0.0.1:${toString config.services.scrutiny.settings.web.listen.port}"; + + enableACME = true; + forceSSL = true; + }; + }; + + netdata = { + enable = true; + config = { + # web.mode = "none"; + # web."bind to" = "127.0.0.1:19999"; + global = { + "debug log" = "syslog"; + "access log" = "syslog"; + "error log" = "syslog"; + }; + }; + }; + }; + + # 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="; + # }; + # }) + # ]; + }; +} diff --git a/modules/by-name/mo/monitoring/dashboards/Errors.json b/modules/by-name/mo/monitoring/dashboards/Errors.json new file mode 100644 index 0000000..22f4340 --- /dev/null +++ b/modules/by-name/mo/monitoring/dashboards/Errors.json @@ -0,0 +1,811 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 8, + "links": [], + "panels": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "light-red", + "value": null + }, + { + "color": "transparent", + "value": 0.99 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 12, + "links": [ + { + "title": "explore", + "url": "https://grafana.tiserbox.com/explore?panes=%7B%22HWt%22:%7B%22datasource%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22expr%22:%22%7Bunit%3D%5C%22nginx.service%5C%22%7D%20%7C%20pattern%20%5C%22%3C_%3E%20%3C_%3E%20%3Cline%3E%5C%22%20%7C%20line_format%20%5C%22%7B%7B.line%7D%7D%5C%22%20%7C%20json%20%7C%20status%20%21~%20%5C%222..%5C%22%20%7C%20__error__%20%21%3D%20%5C%22JSONParserErr%5C%22%22,%22queryType%22:%22range%22,%22datasource%22:%7B%22type%22:%22loki%22,%22uid%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22%7D,%22editorMode%22:%22code%22%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D%7D&schemaVersion=1&orgId=1" + } + ], + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "sum by(server_name) (rate({unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | server_name =~ \"[[server_name]].*\" [$__auto]))", + "legendFormat": "{{server_name}}", + "queryType": "range", + "refId": "A" + } + ], + "title": "Rate of Requests", + "transformations": [ + { + "id": "extractFields", + "options": { + "replace": true, + "source": "Line" + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": { + "body_bytes_sent": 9, + "bytes_sent": 8, + "gzip_ration": 11, + "post": 12, + "referrer": 10, + "remote_addr": 3, + "remote_user": 6, + "request": 4, + "request_length": 7, + "request_time": 15, + "server_name": 2, + "status": 1, + "time_local": 0, + "upstream_addr": 13, + "upstream_connect_time": 17, + "upstream_header_time": 18, + "upstream_response_time": 16, + "upstream_status": 14, + "user_agent": 5 + }, + "renameByName": {} + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0.5, + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "dashed+area" + } + }, + "mappings": [], + "max": 1.01, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "light-red", + "value": null + }, + { + "color": "transparent", + "value": 0.99 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 9, + "links": [ + { + "title": "explore", + "url": "https://grafana.tiserbox.com/explore?panes=%7B%22HWt%22:%7B%22datasource%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22expr%22:%22%7Bunit%3D%5C%22nginx.service%5C%22%7D%20%7C%20pattern%20%5C%22%3C_%3E%20%3C_%3E%20%3Cline%3E%5C%22%20%7C%20line_format%20%5C%22%7B%7B.line%7D%7D%5C%22%20%7C%20json%20%7C%20status%20%21~%20%5C%222..%5C%22%20%7C%20__error__%20%21%3D%20%5C%22JSONParserErr%5C%22%22,%22queryType%22:%22range%22,%22datasource%22:%7B%22type%22:%22loki%22,%22uid%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22%7D,%22editorMode%22:%22code%22%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D%7D&schemaVersion=1&orgId=1" + } + ], + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "min" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "(sum by(server_name) (count_over_time({unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | status =~ \"[1234]..\" | server_name =~ \"[[server_name]].*\" [7d])) / sum by(server_name) (count_over_time({unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | server_name =~ \"[[server_name]].*\" [7d])))", + "legendFormat": "{{server_name}}", + "queryType": "range", + "refId": "A" + } + ], + "title": "5XX Requests Error Budgets", + "transformations": [ + { + "id": "extractFields", + "options": { + "replace": true, + "source": "Line" + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": { + "body_bytes_sent": 9, + "bytes_sent": 8, + "gzip_ration": 11, + "post": 12, + "referrer": 10, + "remote_addr": 3, + "remote_user": 6, + "request": 4, + "request_length": 7, + "request_time": 15, + "server_name": 2, + "status": 1, + "time_local": 0, + "upstream_addr": 13, + "upstream_connect_time": 17, + "upstream_header_time": 18, + "upstream_response_time": 16, + "upstream_status": 14, + "user_agent": 5 + }, + "renameByName": {} + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "max": 1.01, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "light-red", + "value": null + }, + { + "color": "transparent", + "value": 0.99 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 10, + "links": [ + { + "title": "explore", + "url": "https://grafana.tiserbox.com/explore?panes=%7B%22HWt%22:%7B%22datasource%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22expr%22:%22%7Bunit%3D%5C%22nginx.service%5C%22%7D%20%7C%20pattern%20%5C%22%3C_%3E%20%3C_%3E%20%3Cline%3E%5C%22%20%7C%20line_format%20%5C%22%7B%7B.line%7D%7D%5C%22%20%7C%20json%20%7C%20status%20%21~%20%5C%222..%5C%22%20%7C%20__error__%20%21%3D%20%5C%22JSONParserErr%5C%22%22,%22queryType%22:%22range%22,%22datasource%22:%7B%22type%22:%22loki%22,%22uid%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22%7D,%22editorMode%22:%22code%22%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D%7D&schemaVersion=1&orgId=1" + } + ], + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "min" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "(sum by(server_name) (count_over_time({unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | status =~ \"[1235]..\" | server_name =~ \"[[server_name]].*\" [7d])) / sum by(server_name) (count_over_time({unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | server_name =~ \"[[server_name]].*\" [7d])))", + "legendFormat": "{{server_name}}", + "queryType": "range", + "refId": "A" + } + ], + "title": "4XX Requests Error Budgets", + "transformations": [ + { + "id": "extractFields", + "options": { + "replace": true, + "source": "Line" + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": { + "body_bytes_sent": 9, + "bytes_sent": 8, + "gzip_ration": 11, + "post": 12, + "referrer": 10, + "remote_addr": 3, + "remote_user": 6, + "request": 4, + "request_length": 7, + "request_time": 15, + "server_name": 2, + "status": 1, + "time_local": 0, + "upstream_addr": 13, + "upstream_connect_time": 17, + "upstream_header_time": 18, + "upstream_response_time": 16, + "upstream_status": 14, + "user_agent": 5 + }, + "renameByName": {} + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 8, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": true, + "showTime": true, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "{unit=~\"[[service]].*\"}", + "queryType": "range", + "refId": "A" + } + ], + "title": "Log Errors", + "type": "logs" + }, + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "filterable": false, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 167 + } + ] + } + ] + }, + "gridPos": { + "h": 14, + "w": 24, + "x": 0, + "y": 22 + }, + "id": 7, + "links": [ + { + "title": "explore", + "url": "https://grafana.tiserbox.com/explore?panes=%7B%22HWt%22:%7B%22datasource%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22expr%22:%22%7Bunit%3D%5C%22nginx.service%5C%22%7D%20%7C%20pattern%20%5C%22%3C_%3E%20%3C_%3E%20%3Cline%3E%5C%22%20%7C%20line_format%20%5C%22%7B%7B.line%7D%7D%5C%22%20%7C%20json%20%7C%20status%20%21~%20%5C%222..%5C%22%20%7C%20__error__%20%21%3D%20%5C%22JSONParserErr%5C%22%22,%22queryType%22:%22range%22,%22datasource%22:%7B%22type%22:%22loki%22,%22uid%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22%7D,%22editorMode%22:%22code%22%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D%7D&schemaVersion=1&orgId=1" + } + ], + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.2.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "{unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | status =~ \"5..\" | server_name =~ \"[[server_name]].*\"", + "queryType": "range", + "refId": "A" + } + ], + "title": "5XX Requests Errors", + "transformations": [ + { + "id": "extractFields", + "options": { + "keepTime": false, + "replace": false, + "source": "Line" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Line": true, + "id": true, + "labels": true, + "time_local": true, + "tsNs": true + }, + "indexByName": { + "Line": 21, + "Time": 0, + "body_bytes_sent": 10, + "bytes_sent": 9, + "gzip_ration": 12, + "id": 23, + "labels": 20, + "post": 13, + "referrer": 11, + "remote_addr": 4, + "remote_user": 7, + "request": 5, + "request_length": 8, + "request_time": 16, + "server_name": 3, + "status": 2, + "time_local": 1, + "tsNs": 22, + "upstream_addr": 14, + "upstream_connect_time": 18, + "upstream_header_time": 19, + "upstream_response_time": 17, + "upstream_status": 15, + "user_agent": 6 + }, + "renameByName": {} + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "filterable": false, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 14, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 11, + "links": [ + { + "title": "explore", + "url": "https://grafana.tiserbox.com/explore?panes=%7B%22HWt%22:%7B%22datasource%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22expr%22:%22%7Bunit%3D%5C%22nginx.service%5C%22%7D%20%7C%20pattern%20%5C%22%3C_%3E%20%3C_%3E%20%3Cline%3E%5C%22%20%7C%20line_format%20%5C%22%7B%7B.line%7D%7D%5C%22%20%7C%20json%20%7C%20status%20%21~%20%5C%222..%5C%22%20%7C%20__error__%20%21%3D%20%5C%22JSONParserErr%5C%22%22,%22queryType%22:%22range%22,%22datasource%22:%7B%22type%22:%22loki%22,%22uid%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22%7D,%22editorMode%22:%22code%22%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D%7D&schemaVersion=1&orgId=1" + } + ], + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "10.2.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "{unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | status =~ \"4..\" | server_name =~ \"[[server_name]].*\"", + "queryType": "range", + "refId": "A" + } + ], + "title": "4XX Requests Errors", + "transformations": [ + { + "id": "extractFields", + "options": { + "replace": true, + "source": "Line" + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": { + "body_bytes_sent": 9, + "bytes_sent": 8, + "gzip_ration": 11, + "post": 12, + "referrer": 10, + "remote_addr": 3, + "remote_user": 6, + "request": 4, + "request_length": 7, + "request_time": 15, + "server_name": 2, + "status": 1, + "time_local": 0, + "upstream_addr": 13, + "upstream_connect_time": 17, + "upstream_header_time": 18, + "upstream_response_time": 16, + "upstream_status": 14, + "user_agent": 5 + }, + "renameByName": {} + } + } + ], + "type": "table" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [ + { + "allValue": ".+", + "current": { + "text": "All", + "value": "$__all" + }, + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "definition": "query_result(max by (name) (node_systemd_unit_state))", + "includeAll": true, + "multi": true, + "name": "service", + "options": [], + "query": { + "qryType": 3, + "query": "query_result(max by (name) (node_systemd_unit_state))", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "/name=\"(?<value>.*)\\.service\"/", + "sort": 1, + "type": "query" + }, + { + "current": { + "text": ".+", + "value": ".+" + }, + "name": "server_name", + "options": [ + { + "selected": true, + "text": ".+", + "value": ".+" + } + ], + "query": ".+", + "type": "textbox" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Errors", + "uid": "d66242cf-71e8-417c-8ef7-51b0741545df", + "version": 32, + "weekStart": "" +} diff --git a/modules/by-name/mo/monitoring/dashboards/Health.json b/modules/by-name/mo/monitoring/dashboards/Health.json new file mode 100644 index 0000000..a2079a2 --- /dev/null +++ b/modules/by-name/mo/monitoring/dashboards/Health.json @@ -0,0 +1,872 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 4, + "panels": [], + "repeat": "hostname", + "title": "${hostname}", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "footer": { + "reducers": [] + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 3, + "maxDataPoints": 400, + "options": { + "cellHeight": "sm", + "showHeader": true + }, + "pluginVersion": "12.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "node_os_info", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "OS Versions", + "transformations": [ + { + "id": "labelsToFields", + "options": { + "keepLabels": [ + "build_id", + "domain", + "hostname", + "id", + "instance", + "job", + "name", + "pretty_name", + "version", + "version_codename", + "version_id" + ], + "mode": "columns" + } + }, + { + "id": "groupBy", + "options": { + "fields": { + "Time": { + "aggregations": [ + "firstNotNull" + ], + "operation": "aggregate" + }, + "pretty_name": { + "aggregations": [], + "operation": "groupby" + } + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 1, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "node_hwmon_temp_celsius{hostname=~\"$hostname\"}", + "instant": false, + "legendFormat": "{{chip}} - {{sensor}}", + "range": true, + "refId": "A" + } + ], + "title": "Temperature", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "axisPlacement": "auto", + "fillOpacity": 70, + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 0 + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 5, + "interval": "1m", + "maxDataPoints": 200, + "options": { + "colWidth": 1, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "rowHeight": 0.8, + "showValue": "never", + "tooltip": { + "hideZeros": false, + "mode": "none", + "sort": "none" + } + }, + "pluginVersion": "12.4.0", + "repeat": "hostname", + "repeatDirection": "h", + "targets": [ + { + "editorMode": "code", + "expr": "node_zfs_zpool_state{hostname=~\"$hostname\", state=\"online\"} > 0", + "legendFormat": "{{zpool}} - {{state}}", + "range": true, + "refId": "A" + } + ], + "title": "ZFS Pools", + "type": "status-history" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line+area" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": 0 + }, + { + "color": "transparent", + "value": 604808 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 13 + }, + "id": 2, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "ssl_certificate_expiry_seconds", + "legendFormat": "{{exported_hostname}}: {{subject}} {{path}}", + "range": true, + "refId": "A" + } + ], + "title": "Certificate Remaining Validity", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "years" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 13 + }, + "id": 7, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0", + "targets": [ + { + "editorMode": "builder", + "expr": "scrutiny_smart_power_on_hours{hostname=~\"$hostname\"} / (24 * 365)", + "legendFormat": "{{device_name}}", + "range": true, + "refId": "A" + } + ], + "title": "Operating Years", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-YlRd" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMax": 100, + "axisSoftMin": 0, + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 6, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "width": 400 + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum by(hostname, domain, mountpoint, device) (node_filesystem_free_bytes{hostname=~\"$hostname\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "builder", + "expr": "sum by(hostname, domain, mountpoint, device) (node_filesystem_size_bytes{hostname=~\"$hostname\"})", + "hide": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + }, + { + "datasource": { + "name": "Expression", + "type": "__expr__", + "uid": "__expr__" + }, + "expression": "(1 - $A / $B) * 100", + "refId": "Disk Full", + "type": "math" + } + ], + "title": "Filesystem Disk Usage", + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "Time", + "mode": "outer" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 9, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0", + "targets": [ + { + "editorMode": "builder", + "expr": "scrutiny_smart_power_on_hours{hostname=~\"$hostname\"}", + "legendFormat": "{{device_name}}", + "range": true, + "refId": "A" + } + ], + "title": "Operating Years", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "footer": { + "reducers": [] + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 29 + }, + "id": 8, + "options": { + "cellHeight": "sm", + "showHeader": true + }, + "pluginVersion": "12.4.0", + "targets": [ + { + "editorMode": "builder", + "exemplar": false, + "expr": "scrutiny_device_info{hostname=~\"$hostname\"}", + "format": "table", + "instant": true, + "legendFormat": "{{device_name}}", + "range": false, + "refId": "A" + } + ], + "title": "Disk Info", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Value": true, + "__name__": true, + "domain": true, + "hostname": true, + "instance": true, + "job": true, + "wwn": false + }, + "includeByName": {}, + "indexByName": {}, + "renameByName": {} + } + } + ], + "type": "table" + } + ], + "preload": false, + "schemaVersion": 42, + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "baryum", + "value": "baryum" + }, + "definition": "label_values(up,hostname)", + "name": "hostname", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(up,hostname)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "regexApplyTo": "value", + "type": "query" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Node Health", + "uid": "edhuvl28vpjwge", + "version": 25, + "weekStart": "" +} diff --git a/modules/by-name/mo/monitoring/dashboards/Performance.json b/modules/by-name/mo/monitoring/dashboards/Performance.json new file mode 100644 index 0000000..bb8c88f --- /dev/null +++ b/modules/by-name/mo/monitoring/dashboards/Performance.json @@ -0,0 +1,1606 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 6, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 12, + "panels": [], + "title": "Node", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 3600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 2, + "fieldMinMax": false, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "transparent", + "value": 0.05 + } + ] + }, + "unit": "mbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "custom.axisPlacement", + "value": "right" + }, + { + "id": "unit", + "value": "ms" + }, + { + "id": "decimals" + }, + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 0, + 10 + ], + "fill": "dot" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "custom.fillOpacity", + "value": 10 + }, + { + "id": "custom.axisPlacement", + "value": "auto" + }, + { + "id": "custom.stacking", + "value": { + "group": "A", + "mode": "none" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 20, + "options": { + "legend": { + "calcs": [ + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "width": 300 + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "netdata_system_memory_full_pressure_stall_time_ms_average{hostname=~\"$hostname\"} * -1", + "hide": false, + "instant": false, + "legendFormat": "full stall time", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "sum(node_memory_MemTotal_bytes{instance=\"127.0.0.1:9112\"}) / 1000000 - sum(netdata_mem_available_MiB_average{instance=~\"$instance\"})", + "hide": false, + "instant": false, + "legendFormat": "remaining", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum by(dimension, service_name) (netdata_systemd_service_memory_usage_MiB_average{instance=~\"$instance\", service_name=~\"$service\", dimension=\"ram\"})", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "{{service_name}}", + "range": true, + "refId": "used", + "useBackend": false + } + ], + "title": "Memory", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 3600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 2, + "fieldMinMax": false, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "transparent", + "value": 0.05 + } + ] + }, + "unit": "mbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "custom.axisPlacement", + "value": "right" + }, + { + "id": "unit", + "value": "ms" + }, + { + "id": "decimals" + }, + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 0, + 10 + ], + "fill": "dot" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "custom.fillOpacity", + "value": 10 + }, + { + "id": "custom.axisPlacement", + "value": "auto" + }, + { + "id": "custom.stacking", + "value": { + "group": "A", + "mode": "none" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 23, + "options": { + "legend": { + "calcs": [ + "max", + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "width": 300 + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "netdata_system_memory_full_pressure_stall_time_ms_average{hostname=~\"$hostname\"} * -1", + "hide": false, + "instant": false, + "legendFormat": "full stall time", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "sum(node_memory_SwapFree_bytes{instance=~\"127.0.0.1:9112\"}) / 1000000", + "hide": false, + "instant": false, + "legendFormat": "remaining", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum by(dimension, service_name) (netdata_systemd_service_memory_usage_MiB_average{hostname=~\"$hostname\", service_name=~\"$service\", dimension=\"swap\"})", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "{{service_name}}", + "range": true, + "refId": "used", + "useBackend": false + } + ], + "title": "Swap", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 3600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 2, + "fieldMinMax": false, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "transparent", + "value": 0.05 + } + ] + }, + "unit": "percent" + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "custom.axisPlacement", + "value": "right" + }, + { + "id": "unit", + "value": "ms" + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 0, + 10 + ], + "fill": "dot" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "custom.fillOpacity", + "value": 34 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 22, + "options": { + "legend": { + "calcs": [ + "max", + "sum" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "width": 300 + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "netdata_system_cpu_some_pressure_stall_time_ms_average{hostname=~\"$hostname\"} * -1", + "hide": false, + "instant": false, + "legendFormat": "some stall time", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum by(dimension, service_name) (netdata_systemd_service_cpu_utilization_percentage_average{hostname=~\"$hostname\", service_name=~\"$service\"})", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "{{service_name}} / {{dimension}}", + "range": true, + "refId": "used", + "useBackend": false + } + ], + "title": "CPU", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 3600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 2, + "fieldMinMax": false, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "transparent", + "value": 0.05 + } + ] + }, + "unit": "Kibits" + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "custom.axisPlacement", + "value": "right" + }, + { + "id": "unit", + "value": "ms" + }, + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 0, + 10 + ], + "fill": "dot" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "custom.fillOpacity", + "value": 12 + }, + { + "id": "custom.stacking", + "value": { + "group": "A", + "mode": "none" + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "custom.axisPlacement", + "value": "right" + }, + { + "id": "unit", + "value": "ms" + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 0, + 10 + ], + "fill": "dot" + } + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "custom.fillOpacity", + "value": 17 + }, + { + "id": "custom.stacking", + "value": { + "group": "A", + "mode": "none" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 21, + "options": { + "legend": { + "calcs": [ + "max", + "sum" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "width": 300 + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "netdata_system_io_full_pressure_stall_time_ms_average{hostname=~\"$hostname\"} * -1", + "hide": false, + "instant": false, + "legendFormat": "full stall time", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "netdata_system_io_some_pressure_stall_time_ms_average{instance=~\"$instance\"} * -1", + "hide": false, + "instant": false, + "legendFormat": "some stall time", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum by(dimension, service_name) (netdata_systemd_service_disk_io_KiB_persec_average{instance=~\"$instance\", service_name=~\"$service\"})", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "legendFormat": "{{service_name}} / {{dimension}}", + "range": true, + "refId": "used", + "useBackend": false + } + ], + "title": "Disk I/O", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Kibits" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 17 + }, + "id": 18, + "options": { + "legend": { + "calcs": [ + "max", + "sum" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "netdata_disk_io_KiB_persec_average{hostname=~\"$hostname\", chart=~\"disk.sd.+\"}", + "instant": false, + "legendFormat": "{{device}} / {{dimension}}", + "range": true, + "refId": "A" + } + ], + "title": "Disk I/O", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 25 + }, + "id": 4, + "panels": [], + "title": "Network Requests", + "type": "row" + }, + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 26 + }, + "id": 17, + "links": [ + { + "title": "explore", + "url": "https://grafana.tiserbox.com/explore?panes=%7B%22HWt%22:%7B%22datasource%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22expr%22:%22%7Bunit%3D%5C%22nginx.service%5C%22%7D%20%7C%20pattern%20%5C%22%3C_%3E%20%3C_%3E%20%3Cline%3E%5C%22%20%7C%20line_format%20%5C%22%7B%7B.line%7D%7D%5C%22%20%7C%20json%20%7C%20status%20%21~%20%5C%222..%5C%22%20%7C%20__error__%20%21%3D%20%5C%22JSONParserErr%5C%22%22,%22queryType%22:%22range%22,%22datasource%22:%7B%22type%22:%22loki%22,%22uid%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22%7D,%22editorMode%22:%22code%22%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D%7D&schemaVersion=1&orgId=1" + } + ], + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "RdBu", + "steps": 62 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "decimals": 0, + "reverse": false, + "unit": "s" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "{hostname=~\"$hostname\",unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | request_time > 100", + "legendFormat": "{{server_name}}", + "queryType": "range", + "refId": "A" + } + ], + "title": "Slow Requests Histogram > 100ms", + "transformations": [ + { + "id": "extractFields", + "options": { + "keepTime": false, + "replace": false, + "source": "Line" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Line": true, + "body_bytes_sent": true, + "bytes_sent": true, + "gzip_ration": true, + "id": true, + "labels": true, + "post": true, + "referrer": true, + "remote_addr": true, + "remote_user": true, + "request": true, + "request_length": true, + "server_name": true, + "status": true, + "time_local": true, + "tsNs": true, + "upstream_addr": true, + "upstream_connect_time": true, + "upstream_header_time": true, + "upstream_response_time": true, + "upstream_status": true, + "user_agent": true + }, + "indexByName": {}, + "renameByName": {} + } + }, + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "number", + "targetField": "request_time" + } + ], + "fields": {} + } + }, + { + "id": "heatmap", + "options": { + "xBuckets": { + "mode": "size", + "value": "" + }, + "yBuckets": { + "mode": "size", + "scale": { + "log": 2, + "type": "log" + }, + "value": "" + } + } + } + ], + "type": "heatmap" + }, + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "points", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 26 + }, + "id": 2, + "options": { + "legend": { + "calcs": [ + "max", + "mean", + "variance" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "{hostname=~\"$hostname\",unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | request_time > 100", + "legendFormat": "", + "queryType": "range", + "refId": "A" + } + ], + "title": "Requests > 100ms", + "transformations": [ + { + "id": "extractFields", + "options": { + "keepTime": true, + "replace": true, + "source": "labels" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "body_bytes_sent": true, + "bytes_sent": true, + "gzip_ration": true, + "job": true, + "line": true, + "post": true, + "referrer": true, + "remote_addr": true, + "remote_user": true, + "request": true, + "request_length": true, + "status": true, + "time_local": true, + "unit": true, + "upstream_addr": true, + "upstream_connect_time": true, + "upstream_header_time": true, + "upstream_response_time": true, + "upstream_status": true, + "user_agent": true + }, + "indexByName": {}, + "renameByName": {} + } + }, + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "dateFormat": "", + "destinationType": "number", + "targetField": "request_time" + } + ], + "fields": {} + } + }, + { + "id": "partitionByValues", + "options": { + "fields": [ + "server_name" + ] + } + }, + { + "id": "renameByRegex", + "options": { + "regex": "request_time (.*)", + "renamePattern": "$1" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "filterable": false, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 34 + }, + "id": 3, + "links": [ + { + "title": "explore", + "url": "https://grafana.tiserbox.com/explore?panes=%7B%22HWt%22:%7B%22datasource%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22expr%22:%22%7Bunit%3D%5C%22nginx.service%5C%22%7D%20%7C%20pattern%20%5C%22%3C_%3E%20%3C_%3E%20%3Cline%3E%5C%22%20%7C%20line_format%20%5C%22%7B%7B.line%7D%7D%5C%22%20%7C%20json%20%7C%20status%20%21~%20%5C%222..%5C%22%20%7C%20__error__%20%21%3D%20%5C%22JSONParserErr%5C%22%22,%22queryType%22:%22range%22,%22datasource%22:%7B%22type%22:%22loki%22,%22uid%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22%7D,%22editorMode%22:%22code%22%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D%7D&schemaVersion=1&orgId=1" + } + ], + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "{hostname=~\"$hostname\",unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | request_time > 1", + "queryType": "range", + "refId": "A" + } + ], + "title": "Network Requests Above 1s", + "transformations": [ + { + "id": "extractFields", + "options": { + "replace": true, + "source": "Line" + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 42 + }, + "id": 7, + "panels": [], + "title": "Databases", + "type": "row" + }, + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": { + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "duration_ms" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "unit" + }, + "properties": [ + { + "id": "custom.width", + "value": 150 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 43 + }, + "id": 6, + "links": [ + { + "title": "explore", + "url": "https://grafana.tiserbox.com/explore?panes=%7B%22HWt%22:%7B%22datasource%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22expr%22:%22%7Bunit%3D%5C%22nginx.service%5C%22%7D%20%7C%20pattern%20%5C%22%3C_%3E%20%3C_%3E%20%3Cline%3E%5C%22%20%7C%20line_format%20%5C%22%7B%7B.line%7D%7D%5C%22%20%7C%20json%20%7C%20status%20%21~%20%5C%222..%5C%22%20%7C%20__error__%20%21%3D%20%5C%22JSONParserErr%5C%22%22,%22queryType%22:%22range%22,%22datasource%22:%7B%22type%22:%22loki%22,%22uid%22:%22cd6cc53e-840c-484d-85f7-96fede324006%22%7D,%22editorMode%22:%22code%22%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D%7D&schemaVersion=1&orgId=1" + } + ], + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "{hostname=~\"$hostname\",unit=\"postgresql.service\"} | regexp \".*duration: (?P<duration_ms>[0-9.]+) ms (?P<statement>.*)\" | duration_ms > 500 | __error__ != \"LabelFilterErr\"", + "queryType": "range", + "refId": "A" + } + ], + "title": "Slow DB Queries", + "transformations": [ + { + "id": "extractFields", + "options": { + "replace": true, + "source": "labels" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "job": true + }, + "indexByName": { + "duration_ms": 0, + "job": 1, + "statement": 3, + "unit": 2 + }, + "renameByName": {} + } + } + ], + "type": "table" + } + ], + "preload": false, + "refresh": "1m", + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [ + { + "allValue": ".*", + "current": { + "text": [ + "baryum" + ], + "value": [ + "baryum" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "definition": "label_values(netdata_systemd_service_unit_state_state_average,hostname)", + "includeAll": false, + "multi": true, + "name": "hostname", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(netdata_systemd_service_unit_state_state_average,hostname)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "type": "query" + }, + { + "allValue": ".*", + "current": { + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "definition": "label_values(netdata_systemd_service_unit_state_state_average,unit_name)", + "includeAll": true, + "multi": true, + "name": "service", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(netdata_systemd_service_unit_state_state_average,unit_name)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "type": "query" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Performance", + "uid": "e01156bf-cdba-42eb-9845-a401dd634d41", + "version": 82, + "weekStart": "" +} diff --git a/modules/by-name/mo/monitoring/dashboards/Scraping_Jobs.json b/modules/by-name/mo/monitoring/dashboards/Scraping_Jobs.json new file mode 100644 index 0000000..39921d0 --- /dev/null +++ b/modules/by-name/mo/monitoring/dashboards/Scraping_Jobs.json @@ -0,0 +1,334 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 5, + "links": [], + "panels": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 5, + "options": { + "dedupStrategy": "none", + "enableInfiniteScrolling": false, + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": true, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "pluginVersion": "12.2.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "direction": "backward", + "editorMode": "code", + "expr": "{unit=~\"prometheus-.*-exporter.service\"}", + "queryType": "range", + "refId": "A" + } + ], + "title": "Exporter Logs", + "type": "logs" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "red", + "mode": "shades" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "rate(net_conntrack_dialer_conn_failed_total{hostname=~\"$hostname\"}[2m]) > 0", + "instant": false, + "legendFormat": "{{dialer_name}} - {{reason}}", + "range": true, + "refId": "A" + } + ], + "title": "Errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "red", + "mode": "thresholds" + }, + "custom": { + "axisPlacement": "auto", + "fillOpacity": 70, + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineWidth": 0, + "spanNulls": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 1 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "options": { + "alignValue": "center", + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "mergeValues": true, + "rowHeight": 0.9, + "showValue": "never", + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "prometheus_sd_discovered_targets{hostname=~\"$hostname\"}", + "hide": false, + "instant": false, + "legendFormat": "{{config}}", + "range": true, + "refId": "All" + }, + { + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "label_replace(increase((sum by(dialer_name) (net_conntrack_dialer_conn_failed_total{hostname=~\"$hostname\"}))[15m:1m]), \"config\", \"$1\", \"dialer_name\", \"(.*)\")", + "hide": false, + "instant": false, + "legendFormat": "{{dialer_name}}", + "range": true, + "refId": "Failed" + } + ], + "title": "Scraping jobs", + "transformations": [ + { + "id": "labelsToFields", + "options": { + "keepLabels": [ + "config" + ], + "mode": "columns" + } + }, + { + "id": "merge", + "options": {} + }, + { + "id": "organize", + "options": { + "excludeByName": { + "prometheus_sd_discovered_targets": true + }, + "indexByName": {}, + "renameByName": { + "prometheus_sd_discovered_targets": "" + } + } + }, + { + "id": "partitionByValues", + "options": { + "fields": [ + "config" + ] + } + } + ], + "type": "state-timeline" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 42, + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "baryum", + "value": "baryum" + }, + "definition": "label_values(up,hostname)", + "includeAll": false, + "name": "hostname", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(up,hostname)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "type": "query" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Scraping Jobs", + "uid": "debb763d-77aa-47bd-9290-2e02583c8ed2", + "version": 24 +} diff --git a/modules/by-name/mo/monitoring/module.nix b/modules/by-name/mo/monitoring/module.nix new file mode 100644 index 0000000..e0fc5db --- /dev/null +++ b/modules/by-name/mo/monitoring/module.nix @@ -0,0 +1,31 @@ +# Heavily inspired by: +# https://github.com/ibizaman/selfhostblocks/blob/989865eb519e3fc3e8a803c374775451c47a29c8/modules/blocks/monitoring.nix +{ + lib, + config, + ... +}: let + cfg = config.vhack.monitoring; +in { + imports = [ + ./components/loki.nix + # ./components/perses.nix + ./components/grafana.nix + ./components/scrutiny.nix + ./components/prometheus.nix + ]; + + options.vhack.monitoring = { + enable = lib.mkEnableOption "monitoring defaults"; + }; + + config.vhack.monitoring = lib.mkIf cfg.enable { + grafana.enable = true; + + loki.enable = true; + + prometheus.enable = true; + + scrutiny. enable = true; + }; +} diff --git a/modules/by-name/mo/monitoring/rules.json b/modules/by-name/mo/monitoring/rules.json new file mode 100644 index 0000000..8e050e6 --- /dev/null +++ b/modules/by-name/mo/monitoring/rules.json @@ -0,0 +1,386 @@ +[ + { + "uid": "f5246fa3-163f-4eae-9e1d-5b0fe2af0509", + "title": "5XX Requests Error Budgets Under 99%", + "condition": "threshold", + "data": [ + { + "refId": "A", + "queryType": "range", + "relativeTimeRange": { + "from": 21600, + "to": 0 + }, + "datasourceUid": "cd6cc53e-840c-484d-85f7-96fede324006", + "model": { + "datasource": { + "type": "loki", + "uid": "cd6cc53e-840c-484d-85f7-96fede324006" + }, + "editorMode": "code", + "expr": "(sum by(server_name) (count_over_time({unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | status =~ \"[1234]..\" | server_name =~ \".*\" [1h])) / sum by(server_name) (count_over_time({unit=\"nginx.service\"} | pattern \"<_> <_> <line>\" | line_format \"{{.line}}\" | json | __error__ != \"JSONParserErr\" | server_name =~ \".*\" [1h])))", + "intervalMs": 1000, + "legendFormat": "{{server_name}}", + "maxDataPoints": 43200, + "queryType": "range", + "refId": "A" + } + }, + { + "refId": "last", + "relativeTimeRange": { + "from": 0, + "to": 0 + }, + "datasourceUid": "__expr__", + "model": { + "conditions": [ + { + "evaluator": { + "params": [], + "type": "gt" + }, + "operator": { + "type": "and" + }, + "query": { + "params": [ + "B" + ] + }, + "reducer": { + "params": [], + "type": "last" + }, + "type": "query" + } + ], + "datasource": { + "type": "__expr__", + "uid": "__expr__" + }, + "expression": "A", + "intervalMs": 1000, + "maxDataPoints": 43200, + "reducer": "last", + "refId": "last", + "type": "reduce" + } + }, + { + "refId": "threshold", + "relativeTimeRange": { + "from": 0, + "to": 0 + }, + "datasourceUid": "__expr__", + "model": { + "conditions": [ + { + "evaluator": { + "params": [ + 0.99 + ], + "type": "lt" + }, + "operator": { + "type": "and" + }, + "query": { + "params": [ + "C" + ] + }, + "reducer": { + "params": [], + "type": "last" + }, + "type": "query" + } + ], + "datasource": { + "type": "__expr__", + "uid": "__expr__" + }, + "expression": "last", + "intervalMs": 1000, + "maxDataPoints": 43200, + "refId": "threshold", + "type": "threshold" + } + } + ], + "dasboardUid": "d66242cf-71e8-417c-8ef7-51b0741545df", + "panelId": 9, + "noDataState": "OK", + "execErrState": "Error", + "for": "20m", + "annotations": { + "__dashboardUid__": "d66242cf-71e8-417c-8ef7-51b0741545df", + "__panelId__": "9", + "description": "", + "runbook_url": "", + "summary": "The error budget for a service for the last 1 hour is under 99%" + }, + "labels": { + "role": "sysadmin" + }, + "isPaused": false + }, + { + "uid": "ee817l3a88s1sd", + "title": "Certificate Did Not Renew", + "condition": "C", + "data": [ + { + "refId": "A", + "relativeTimeRange": { + "from": 1800, + "to": 0 + }, + "datasourceUid": "df80f9f5-97d7-4112-91d8-72f523a02b09", + "model": { + "adhocFilters": [], + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "expr": "min by(subject) (ssl_certificate_expiry_seconds)", + "interval": "", + "intervalMs": 15000, + "legendFormat": "{{exported_hostname}}: {{subject}} {{path}}", + "maxDataPoints": 43200, + "range": true, + "refId": "A" + } + }, + { + "refId": "B", + "relativeTimeRange": { + "from": 0, + "to": 0 + }, + "datasourceUid": "__expr__", + "model": { + "conditions": [ + { + "evaluator": { + "params": [], + "type": "gt" + }, + "operator": { + "type": "and" + }, + "query": { + "params": [ + "B" + ] + }, + "reducer": { + "params": [], + "type": "last" + }, + "type": "query" + } + ], + "datasource": { + "type": "__expr__", + "uid": "__expr__" + }, + "expression": "A", + "intervalMs": 1000, + "maxDataPoints": 43200, + "reducer": "last", + "refId": "B", + "type": "reduce" + } + }, + { + "refId": "C", + "relativeTimeRange": { + "from": 0, + "to": 0 + }, + "datasourceUid": "__expr__", + "model": { + "conditions": [ + { + "evaluator": { + "params": [ + 604800 + ], + "type": "lt" + }, + "operator": { + "type": "and" + }, + "query": { + "params": [ + "C" + ] + }, + "reducer": { + "params": [], + "type": "last" + }, + "type": "query" + } + ], + "datasource": { + "type": "__expr__", + "uid": "__expr__" + }, + "expression": "B", + "intervalMs": 1000, + "maxDataPoints": 43200, + "refId": "C", + "type": "threshold" + } + } + ], + "dashboardUid": "ae818js0bvw8wb", + "panelId": 3, + "noDataState": "NoData", + "execErrState": "Error", + "for": "20m", + "annotations": { + "__dashboardUid__": "ae818js0bvw8wb", + "__panelId__": "3", + "description": "The expiry date of the certificate is 1 week from now.", + "summary": "Certificate did not renew on time." + }, + "labels": { + "role": "sysadmin" + }, + "isPaused": false + }, + { + "uid": "df4doj5pomhvkf", + "title": "Late Backups", + "condition": "C", + "data": [ + { + "refId": "A", + "relativeTimeRange": { + "from": 10800, + "to": 0 + }, + "datasourceUid": "df80f9f5-97d7-4112-91d8-72f523a02b09", + "model": { + "adhocFilters": [], + "datasource": { + "type": "prometheus", + "uid": "df80f9f5-97d7-4112-91d8-72f523a02b09" + }, + "editorMode": "code", + "exemplar": false, + "expr": "(\n # Timer triggered at least once in the last 24h\n label_replace((\n time()\n -\n systemd_timer_last_trigger_seconds{name=~\".*backup.*.timer\"}\n ) < 24*60*60, \"name\", \"$1.service\", \"name\", \"(.*).timer\")\n AND on(name)\n # At least one failure in the last 24h\n (\n max_over_time(systemd_unit_state{name=~\".*backup.*.service\", state=\"failed\"}[24h]) > 0\n )\n AND on(name)\n # No successes in the last 24h\n (\n max_over_time(systemd_unit_state{name=~\".*backup.*.service\", state=\"inactive\"}[24h]) == 0\n )\n)", + "instant": false, + "interval": "", + "intervalMs": 15000, + "legendFormat": "{{name}}", + "maxDataPoints": 43200, + "range": true, + "refId": "A" + } + }, + { + "refId": "B", + "relativeTimeRange": { + "from": 0, + "to": 0 + }, + "datasourceUid": "__expr__", + "model": { + "conditions": [ + { + "evaluator": { + "params": [], + "type": "gt" + }, + "operator": { + "type": "and" + }, + "query": { + "params": [ + "B" + ] + }, + "reducer": { + "params": [], + "type": "last" + }, + "type": "query" + } + ], + "datasource": { + "type": "__expr__", + "uid": "__expr__" + }, + "expression": "A", + "intervalMs": 1000, + "maxDataPoints": 43200, + "reducer": "last", + "refId": "B", + "type": "reduce" + } + }, + { + "refId": "C", + "relativeTimeRange": { + "from": 0, + "to": 0 + }, + "datasourceUid": "__expr__", + "model": { + "conditions": [ + { + "evaluator": { + "params": [ + 0 + ], + "type": "gt" + }, + "operator": { + "type": "and" + }, + "query": { + "params": [ + "C" + ] + }, + "reducer": { + "params": [], + "type": "last" + }, + "type": "query" + } + ], + "datasource": { + "type": "__expr__", + "uid": "__expr__" + }, + "expression": "B", + "intervalMs": 1000, + "maxDataPoints": 43200, + "refId": "C", + "type": "threshold" + } + } + ], + "dashboardUid": "f05500d0-15ed-4719-b68d-fb898ca13cc8", + "panelId": 15, + "noDataState": "OK", + "execErrState": "Error", + "annotations": { + "__dashboardUid__": "f05500d0-15ed-4719-b68d-fb898ca13cc8", + "__panelId__": "15", + "summary": "A backup did not run in the last 24 hours." + }, + "labels": { + "role": "sysadmin" + }, + "isPaused": false + } +] diff --git a/modules/by-name/ng/nginx/module.nix b/modules/by-name/ng/nginx/module.nix index fa3337d..734a2d2 100644 --- a/modules/by-name/ng/nginx/module.nix +++ b/modules/by-name/ng/nginx/module.nix @@ -39,9 +39,27 @@ in { }; config = lib.mkIf cfg.enable { - vhack.persist.directories = [ - "/var/lib/acme" - ]; + vhack = { + persist.directories = [ + "/var/lib/acme" + ]; + + monitoring.prometheus = { + sources = [ + { + name = "nginx"; + target = "127.0.0.1:${toString config.services.prometheus.exporters.nginx.port}"; + } + ]; + }; + }; + + services.prometheus.exporters.nginx = { + enable = true; + port = 9111; + listenAddress = "127.0.0.1"; + scrapeUri = "http://localhost:80/nginx_status"; + }; users = { users.acme = { diff --git a/tests/by-name/mo/monitoring/test.nix b/tests/by-name/mo/monitoring/test.nix new file mode 100644 index 0000000..0b2ed1c --- /dev/null +++ b/tests/by-name/mo/monitoring/test.nix @@ -0,0 +1,76 @@ +{ + extraModules, + pkgs, + vhack, + ... +}: let + grafanaDomain = "grafana.server.org"; + scrutinyDomain = "scrutiny.server.org"; +in + vhack.runTest { + name = "monitoring"; + + serverDomains = [ + {server = grafanaDomain;} + {server = scrutinyDomain;} + ]; + + nodes = { + client = {}; + + server = {config, ...}: { + imports = + extraModules + ++ [ + ../../../../modules + ]; + + # there are no SMART available disk in the VM, so this service always fails. + systemd.services."smartd".enable = false; + + age.identityPaths = ["${../../../common/email/hostKey}"]; + + vhack = { + monitoring = { + grafana = { + enable = true; + contactPoints = ["me@example.com"]; + fqdn = grafanaDomain; + + adminPassword = ../../../common/email/dkim/alice.com/private.age; + secretKey = ../../../common/email/dkim/bob.com/private.age; + + # TODO: Add a test for that <2026-07-19> + smtp = null; + }; + + loki = { + enable = true; + }; + + prometheus = { + enable = true; + }; + + scrutiny = { + enable = true; + fqdn = scrutinyDomain; + }; + }; + }; + }; + }; + + services = [ + {server = "grafana.service";} + {server = "fluent-bit.service";} + {server = "loki.service";} + {server = "netdata.service";} + ]; + + testScript = {...}: + # Python + '' + # TODO: We should probably query some of the prometheus metrics here? <2026-07-19> + ''; + } |
