237 lines
7.7 KiB
Nix
Executable File
237 lines
7.7 KiB
Nix
Executable File
{
|
|
config,
|
|
lib,
|
|
namespace,
|
|
...
|
|
}:
|
|
with lib;
|
|
let
|
|
name = "grafana";
|
|
cfg = config.${namespace}.services.${name};
|
|
|
|
giteaPort = config.${namespace}.services.gitea.port;
|
|
resticPort = config.${namespace}.services.restic.port;
|
|
nextcloudPort = config.${namespace}.services.nextcloud.port;
|
|
|
|
grafanaConfig = lib.${namespace}.mkModule {
|
|
inherit config name;
|
|
description = "grafana";
|
|
options = { };
|
|
moduleConfig = {
|
|
services = {
|
|
prometheus = {
|
|
enable = true;
|
|
exporters = {
|
|
node = {
|
|
enable = true;
|
|
enabledCollectors = [
|
|
"filesystem"
|
|
"diskstats"
|
|
"meminfo"
|
|
"cpu"
|
|
"systemd"
|
|
"processes"
|
|
];
|
|
extraFlags = [
|
|
"--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|run)($|/)"
|
|
];
|
|
};
|
|
|
|
libvirt = {
|
|
enable = false;
|
|
openFirewall = true;
|
|
};
|
|
|
|
nut = {
|
|
enable = true;
|
|
openFirewall = true;
|
|
passwordPath = config.sops.secrets."jallen-nas/ups_password".path;
|
|
nutUser = upsUser;
|
|
};
|
|
|
|
# PostgreSQL — runs as the local postgres superuser via peer auth
|
|
# (Unix socket, no password required).
|
|
postgres = {
|
|
enable = true;
|
|
runAsLocalSuperUser = true;
|
|
};
|
|
|
|
# Redis — single exporter instance covering all four Redis servers
|
|
# via the multi-target scrape pattern (/scrape?target=<addr>).
|
|
# The exporter needs AF_INET to reach TCP Redis instances.
|
|
redis = {
|
|
enable = true;
|
|
# No fixed --redis.addr: multi-target mode uses ?target= param.
|
|
};
|
|
|
|
# MariaDB — runs as the mysql OS user so it can connect via Unix
|
|
# socket without a password.
|
|
mysqld = {
|
|
enable = true;
|
|
runAsLocalSuperUser = true;
|
|
};
|
|
|
|
# Nextcloud — authenticates with the admin account.
|
|
# passwordFile must be readable by the prometheus-nextcloud-exporter
|
|
# user; sops mode 0440 + group keys covers that.
|
|
nextcloud = {
|
|
enable = true;
|
|
url = "http://localhost:${toString nextcloudPort}";
|
|
username = "mjallen";
|
|
passwordFile = config.sops.secrets."jallen-nas/nextcloud/adminpassword".path;
|
|
};
|
|
};
|
|
|
|
scrapeConfigs = [
|
|
# ── System ──────────────────────────────────────────────────────────
|
|
{
|
|
job_name = "node";
|
|
static_configs = [
|
|
{
|
|
targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ];
|
|
}
|
|
];
|
|
}
|
|
|
|
# ── UPS (NUT) ────────────────────────────────────────────────────────
|
|
{
|
|
job_name = "nut";
|
|
static_configs = [
|
|
{
|
|
targets = [ "localhost:${toString config.services.prometheus.exporters.nut.port}" ];
|
|
}
|
|
];
|
|
}
|
|
|
|
# ── Databases ────────────────────────────────────────────────────────
|
|
{
|
|
job_name = "postgres";
|
|
static_configs = [
|
|
{
|
|
targets = [ "localhost:${toString config.services.prometheus.exporters.postgres.port}" ];
|
|
}
|
|
];
|
|
}
|
|
{
|
|
# Redis multi-target: one exporter, four Redis instances.
|
|
# The redis_exporter's /scrape?target= endpoint proxies each target
|
|
# so a single exporter process covers all servers.
|
|
job_name = "redis";
|
|
metrics_path = "/scrape";
|
|
static_configs = [
|
|
{
|
|
targets = [
|
|
"redis://localhost:6379" # authentik
|
|
"redis://localhost:6363" # ccache
|
|
"redis://localhost:6380" # manyfold
|
|
"redis://localhost:6381" # onlyoffice
|
|
];
|
|
}
|
|
];
|
|
relabel_configs = [
|
|
{
|
|
source_labels = [ "__address__" ];
|
|
target_label = "__param_target";
|
|
}
|
|
{
|
|
source_labels = [ "__param_target" ];
|
|
target_label = "instance";
|
|
}
|
|
{
|
|
target_label = "__address__";
|
|
replacement = "localhost:${toString config.services.prometheus.exporters.redis.port}";
|
|
}
|
|
];
|
|
}
|
|
{
|
|
job_name = "mysqld";
|
|
static_configs = [
|
|
{
|
|
targets = [ "localhost:${toString config.services.prometheus.exporters.mysqld.port}" ];
|
|
}
|
|
];
|
|
}
|
|
|
|
# ── Application services ─────────────────────────────────────────────
|
|
{
|
|
# Caddy exposes its built-in Prometheus endpoint on port 2019.
|
|
job_name = "caddy";
|
|
static_configs = [
|
|
{
|
|
targets = [ "localhost:2019" ];
|
|
}
|
|
];
|
|
}
|
|
{
|
|
# Gitea's /metrics endpoint is protected by a Bearer token.
|
|
job_name = "gitea";
|
|
metrics_path = "/metrics";
|
|
bearer_token_file = config.sops.secrets."jallen-nas/gitea/metrics-key".path;
|
|
static_configs = [
|
|
{
|
|
targets = [ "localhost:${toString giteaPort}" ];
|
|
}
|
|
];
|
|
}
|
|
{
|
|
# restic REST server exposes Prometheus metrics at /metrics.
|
|
job_name = "restic";
|
|
metrics_path = "/metrics";
|
|
static_configs = [
|
|
{
|
|
targets = [ "localhost:${toString resticPort}" ];
|
|
}
|
|
];
|
|
}
|
|
{
|
|
job_name = "nextcloud";
|
|
static_configs = [
|
|
{
|
|
targets = [ "localhost:${toString config.services.prometheus.exporters.nextcloud.port}" ];
|
|
}
|
|
];
|
|
}
|
|
];
|
|
};
|
|
|
|
grafana = {
|
|
enable = true;
|
|
settings = {
|
|
server = {
|
|
http_port = cfg.port;
|
|
http_addr = "0.0.0.0";
|
|
};
|
|
};
|
|
|
|
dataDir = "${cfg.configDir}/grafana";
|
|
|
|
provision = {
|
|
enable = true;
|
|
datasources.settings.datasources = [
|
|
{
|
|
name = "Prometheus";
|
|
type = "prometheus";
|
|
access = "proxy";
|
|
url = "http://localhost:${toString config.services.prometheus.port}";
|
|
}
|
|
];
|
|
};
|
|
};
|
|
};
|
|
|
|
# The redis exporter needs AF_INET to reach TCP Redis instances.
|
|
# The default systemd hardening only allows AF_UNIX.
|
|
systemd.services.prometheus-redis-exporter.serviceConfig.RestrictAddressFamilies = [
|
|
"AF_UNIX"
|
|
"AF_INET"
|
|
"AF_INET6"
|
|
];
|
|
};
|
|
};
|
|
|
|
upsUser = "nas-admin";
|
|
in
|
|
{
|
|
imports = [ grafanaConfig ];
|
|
}
|