1
0
Fork 0
forked from pub-solar/infra

Merge pull request 'prometheus: refactor metrics scraping to use firewall rules' () from refactor-prometheus-exporters into main

Reviewed-on: 
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
This commit is contained in:
teutat3s 2025-04-18 12:38:06 +00:00
commit afe8746c8d
Signed by: pub.solar gitea
GPG key ID: F0332B04B7054873
14 changed files with 3295 additions and 45 deletions

View file

@ -50,7 +50,6 @@
self.nixosModules.nginx-mastodon-files
self.nixosModules.mediawiki
self.nixosModules.nextcloud
self.nixosModules.nginx-prometheus-exporters
self.nixosModules.nginx-website
self.nixosModules.nginx-website-miom
self.nixosModules.opensearch
@ -132,6 +131,7 @@
self.nixosModules.keycloak
self.nixosModules.grafana
self.nixosModules.prometheus
self.nixosModules.prometheus-exporters
self.nixosModules.loki
self.nixosModules.forgejo-actions-runner
];

View file

@ -7,6 +7,7 @@
./configuration.nix
./networking.nix
./prometheus-exporters.nix
./wireguard.nix
./backups.nix
"${flake.inputs.fork}/nixos/modules/services/matrix/matrix-authentication-service.nix"

View file

@ -0,0 +1,53 @@
{
config,
lib,
flake,
...
}:
{
age.secrets."nextcloud-serverinfo-token" = {
file = "${flake.self}/secrets/nextcloud-serverinfo-token.age";
mode = "400";
owner = "nextcloud-exporter";
};
services.prometheus = {
exporters = {
# https://github.com/xperimental/nextcloud-exporter
nextcloud = {
enable = true;
openFirewall = true;
firewallFilter = "--in-interface wg-ssh --protocol tcp --match tcp --dport ${toString config.services.prometheus.exporters.nextcloud.port}";
url = "https://cloud.pub.solar";
tokenFile = config.age.secrets."nextcloud-serverinfo-token".path;
port = 9205;
};
# https://github.com/nginx/nginx-prometheus-exporter
nginx = {
enable = true;
openFirewall = true;
firewallFilter = "--in-interface wg-ssh --protocol tcp --match tcp --dport ${toString config.services.prometheus.exporters.nginx.port}";
port = 9113;
};
# https://github.com/hipages/php-fpm_exporter
#php-fpm = {
# enable = true;
# extraFlags = [
# "--phpfpm.scrape-uri unix://${config.services.phpfpm.pools.nextcloud.socket};/status"
# ];
# group = "nginx";
# openFirewall = true;
# firewallFilter = "--in-interface wg-ssh --protocol tcp --match tcp --dport ${toString config.services.prometheus.exporters.php-fpm.port}";
# port = 9253;
#};
# https://github.com/prometheus-community/postgres_exporter
postgres = {
enable = true;
dataSourceName = "user=postgres-exporter database=postgres host=/run/postgresql sslmode=disable";
openFirewall = true;
firewallFilter = "--in-interface wg-ssh --protocol tcp --match tcp --dport ${toString config.services.prometheus.exporters.postgres.port}";
port = 9187;
};
};
};
}

View file

@ -23,11 +23,26 @@
};
environment.etc = {
"grafana-dashboards/nextcloud.json" = {
source = ./grafana-dashboards/nextcloud.json;
group = "grafana";
user = "grafana";
};
"grafana-dashboards/node-exporter-full_rev33.json" = {
source = ./grafana-dashboards/node-exporter-full_rev33.json;
group = "grafana";
user = "grafana";
};
"grafana-dashboards/nginx.json" = {
source = ./grafana-dashboards/nginx.json;
group = "grafana";
user = "grafana";
};
"grafana-dashboards/postgres-overview.json" = {
source = ./grafana-dashboards/postgres-overview.json;
group = "grafana";
user = "grafana";
};
"grafana-dashboards/synapse.json" = {
source = ./grafana-dashboards/synapse.json;
group = "grafana";

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,567 @@
{
"__inputs": [
{
"description": "",
"label": "Prometheus",
"name": "DS_PROMETHEUS",
"pluginId": "prometheus",
"pluginName": "Prometheus",
"type": "datasource"
}
],
"__requires": [
{
"id": "grafana",
"name": "Grafana",
"type": "grafana",
"version": "5.0.0"
},
{
"id": "graph",
"name": "Graph",
"type": "panel",
"version": ""
},
{
"id": "prometheus",
"name": "Prometheus",
"type": "datasource",
"version": "1.0.0"
},
{
"id": "singlestat",
"name": "Singlestat",
"type": "panel",
"version": ""
}
],
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "Official dashboard for NGINX Prometheus exporter",
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1562682051068,
"links": [],
"panels": [
{
"collapsed": false,
"datasource": "${DS_PROMETHEUS}",
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 4,
"panels": [],
"title": "Status",
"type": "row"
},
{
"cacheTimeout": null,
"colorBackground": true,
"colorPostfix": false,
"colorPrefix": false,
"colorValue": false,
"colors": [
"#E02F44",
"#FF9830",
"#299c46"
],
"datasource": "${DS_PROMETHEUS}",
"decimals": null,
"description": "",
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"gridPos": {
"h": 3,
"w": 12,
"x": 0,
"y": 1
},
"id": 8,
"interval": null,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"options": {},
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"repeat": "instance",
"repeatDirection": "h",
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"tableColumn": "",
"targets": [
{
"expr": "nginx_up{instance=~\"$instance\"}",
"format": "time_series",
"instant": false,
"intervalFactor": 1,
"refId": "A"
}
],
"thresholds": "1,1",
"timeFrom": null,
"timeShift": null,
"title": "NGINX Status for $instance",
"type": "singlestat",
"valueFontSize": "100%",
"valueMaps": [
{
"op": "=",
"text": "Down",
"value": "0"
},
{
"op": "=",
"text": "Up",
"value": "1"
}
],
"valueName": "current"
},
{
"collapsed": false,
"datasource": "${DS_PROMETHEUS}",
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 4
},
"id": 6,
"panels": [],
"title": "Metrics",
"type": "row"
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "${DS_PROMETHEUS}",
"decimals": null,
"description": "",
"fill": 1,
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 5
},
"id": 10,
"legend": {
"alignAsTable": false,
"avg": false,
"current": false,
"hideEmpty": false,
"max": false,
"min": false,
"rightSide": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "irate(nginx_connections_accepted{instance=~\"$instance\"}[5m])",
"format": "time_series",
"instant": false,
"intervalFactor": 1,
"legendFormat": "{{instance}} accepted",
"refId": "A"
},
{
"expr": "irate(nginx_connections_handled{instance=~\"$instance\"}[5m])",
"format": "time_series",
"instant": false,
"intervalFactor": 1,
"legendFormat": "{{instance}} handled",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Processed connections",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"decimals": 1,
"format": "short",
"label": "Connections (rate)",
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": "",
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "${DS_PROMETHEUS}",
"decimals": 0,
"fill": 1,
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 5
},
"id": 12,
"legend": {
"alignAsTable": false,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "nginx_connections_active{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "{{instance}} active",
"refId": "A"
},
{
"expr": "nginx_connections_reading{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "{{instance}} reading",
"refId": "B"
},
{
"expr": "nginx_connections_waiting{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "{{instance}} waiting",
"refId": "C"
},
{
"expr": "nginx_connections_writing{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "{{instance}} writing",
"refId": "D"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Active Connections",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"decimals": 0,
"format": "short",
"label": "Connections",
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "${DS_PROMETHEUS}",
"fill": 1,
"gridPos": {
"h": 8,
"w": 24,
"x": 0,
"y": 15
},
"id": 15,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "irate(nginx_http_requests_total{instance=~\"$instance\"}[5m])",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "{{instance}} total requests",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Total requests",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"refresh": "5s",
"schemaVersion": 18,
"style": "dark",
"tags": [
"nginx",
"prometheus",
"nginx prometheus exporter"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"tags": [],
"text": "default",
"value": "default"
},
"hide": 0,
"includeAll": false,
"label": "datasource",
"multi": false,
"name": "DS_PROMETHEUS",
"options": [],
"query": "prometheus",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"type": "datasource"
},
{
"allValue": null,
"current": {},
"datasource": "${DS_PROMETHEUS}",
"definition": "label_values(nginx_up, instance)",
"hide": 0,
"includeAll": true,
"label": "",
"multi": true,
"name": "instance",
"options": [],
"query": "label_values(nginx_up, instance)",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-15m",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "",
"title": "NGINX",
"uid": "MsjffzSZz",
"version": 1
}

File diff suppressed because it is too large Load diff

View file

@ -8,6 +8,13 @@
let
publicDomain = "matrix.${config.pub-solar-os.networking.domain}";
serverDomain = "${config.pub-solar-os.networking.domain}";
# Find element in list config.services.matrix-synapse.settings.listeners
# that sets type = "metrics"
listenerWithMetrics =
lib.findFirst (listener: listener.type == "metrics")
(throw "Found no matrix-synapse.settings.listeners.*.type containing string metrics")
config.services.matrix-synapse.settings.listeners;
synapseMetricsPort = listenerWithMetrics.port;
in
{
options.pub-solar-os = {
@ -45,6 +52,9 @@ in
};
config = lib.mkIf config.pub-solar-os.matrix.enable {
# Only expose matrix-synapse metrics port via wireguard interface
networking.firewall.interfaces.wg-ssh.allowedTCPPorts = [ synapseMetricsPort ];
services.matrix-synapse = {
enable = true;
log.root.level = "WARNING";
@ -81,7 +91,7 @@ in
x_forwarded = true;
}
{
bind_addresses = [ "127.0.0.1" ];
bind_addresses = [ "0.0.0.0" ];
port = 8012;
resources = [ { names = [ "metrics" ]; } ];
tls = false;

View file

@ -1,31 +0,0 @@
{
config,
flake,
lib,
...
}:
let
# Find element in list config.services.matrix-synapse.settings.listeners
# that sets type = "metrics"
listenerWithMetrics =
lib.findFirst (listener: listener.type == "metrics")
(throw "Found no matrix-synapse.settings.listeners.*.type containing string metrics")
config.services.matrix-synapse.settings.listeners;
synapseMetricsPort = "${toString listenerWithMetrics.port}";
in
{
services.nginx.virtualHosts = {
"nachtigall.wg.${config.pub-solar-os.networking.domain}" = {
listenAddresses = [
"10.7.6.1"
"[fd00:fae:fae:fae:fae:1::]"
];
locations."/metrics" = {
proxyPass = "http://127.0.0.1:${toString (config.services.prometheus.exporters.node.port)}";
};
locations."/_synapse/metrics" = {
proxyPass = "http://127.0.0.1:${synapseMetricsPort}";
};
};
};
}

View file

@ -15,6 +15,7 @@ in
services.nginx = {
enable = true;
enableReload = true;
statusPage = true;
proxyCachePath.cache = {
enable = true;
};

View file

@ -1,12 +1,11 @@
{ config, ... }:
{
# Only expose prometheus exporter port via wireguard interface
networking.firewall.interfaces.wg-ssh.allowedTCPPorts = [ 9002 ];
services.prometheus = {
exporters = {
node = {
enable = true;
openFirewall = true;
firewallFilter = "--in-interface wg-ssh --protocol tcp --match tcp --dport ${toString config.services.prometheus.exporters.node.port}";
enabledCollectors = [ "systemd" ];
port = 9002;
};

View file

@ -5,6 +5,15 @@
flake,
...
}:
let
# Find element in list config.services.matrix-synapse.settings.listeners
# that sets type = "metrics"
listenerWithMetrics =
lib.findFirst (listener: listener.type == "metrics")
(throw "Found no matrix-synapse.settings.listeners.*.type containing string metrics")
flake.self.nixosConfigurations.nachtigall.config.services.matrix-synapse.settings.listeners;
synapseMetricsPort = "${toString listenerWithMetrics.port}";
in
{
age.secrets.alertmanager-envfile = {
file = "${flake.self}/secrets/alertmanager-envfile.age";
@ -38,13 +47,6 @@
services.prometheus = {
enable = true;
port = 9001;
exporters = {
node = {
enable = true;
enabledCollectors = [ "systemd" ];
port = 9002;
};
};
globalConfig = {
scrape_interval = "10s";
scrape_timeout = "9s";
@ -54,7 +56,9 @@
job_name = "node-exporter";
static_configs = [
{
targets = [ "nachtigall.wg.${config.pub-solar-os.networking.domain}" ];
targets = [
"nachtigall.wg.${config.pub-solar-os.networking.domain}:${toString config.services.prometheus.exporters.node.port}"
];
labels = {
instance = "nachtigall";
};
@ -106,7 +110,7 @@
metrics_path = "/_synapse/metrics";
static_configs = [
{
targets = [ "nachtigall.wg.${config.pub-solar-os.networking.domain}" ];
targets = [ "nachtigall.wg.${config.pub-solar-os.networking.domain}:${synapseMetricsPort}" ];
labels = {
instance = "nachtigall";
};
@ -149,6 +153,74 @@
}
];
}
{
job_name = "nextcloud";
scrape_interval = "5m";
static_configs = [
{
targets = [
"nachtigall.wg.${config.pub-solar-os.networking.domain}:${toString config.services.prometheus.exporters.nextcloud.port}"
];
labels = {
instance = "nachtigall";
};
}
];
}
{
job_name = "nginx";
static_configs = [
{
targets = [
"nachtigall.wg.${config.pub-solar-os.networking.domain}:${toString config.services.prometheus.exporters.nginx.port}"
];
labels = {
instance = "nachtigall";
};
}
];
}
#{
# job_name = "php-fpm";
# static_configs = [
# {
# targets = [
# "nachtigall.wg.${config.pub-solar-os.networking.domain}:${toString config.services.prometheus.exporters.php-fpm.port}"
# ];
# labels = {
# instance = "nachtigall";
# };
# }
# ];
#}
{
job_name = "postgres";
relabel_configs = [
{
source_labels = [
"__address__"
];
target_label = "__param_target";
}
{
source_labels = [
"__param_target"
];
target_label = "instance";
}
{
target_label = "__address__";
replacement = "nachtigall.wg.${config.pub-solar-os.networking.domain}:${toString config.services.prometheus.exporters.postgres.port}";
}
];
static_configs = [
{
targets = [
"nachtigall.wg.${config.pub-solar-os.networking.domain}:${toString config.services.prometheus.exporters.postgres.port}"
];
}
];
}
];
ruleFiles = [

Binary file not shown.

View file

@ -81,6 +81,7 @@ in
"nextcloud-secrets.age".publicKeys = nachtigallKeys ++ adminKeys;
"nextcloud-admin-pass.age".publicKeys = nachtigallKeys ++ adminKeys;
"nextcloud-serverinfo-token.age".publicKeys = nachtigallKeys ++ adminKeys;
"searx-environment.age".publicKeys = nachtigallKeys ++ adminKeys;