homelab/modules/homelab/services/grafana.nix
2025-07-30 00:22:33 +02:00

84 lines
2 KiB
Nix

{
config,
lib,
pkgs,
...
}:
with lib; let
serviceName = "grafana";
cfg = config.homelab.services.${serviceName};
in {
imports = [
(import ../lib/features/monitoring.nix serviceName)
(import ../lib/features/logging.nix serviceName)
(import ../lib/features/proxy.nix serviceName)
];
options.homelab.services.${serviceName} = {
enable = mkEnableOption "Grafana Dashboard";
port = mkOption {
type = types.port;
default = 3000;
};
description = mkOption {
type = types.str;
default = "Grafana Metrics Dashboard";
};
};
config = mkIf cfg.enable (mkMerge [
# Core Grafana service
{
services.grafana = {
enable = true;
settings.server = {
http_port = cfg.port;
http_addr = "0.0.0.0";
};
};
networking.firewall.allowedTCPPorts = [cfg.port];
homelab.services.${serviceName}.monitoring.enable = mkDefault true;
}
# Smart defaults for Grafana
{
# Grafana-specific log setup
homelab.services.${serviceName}.logging = mkDefault {
files = ["/var/log/grafana/grafana.log"];
parsing = {
# Grafana log format: t=2024-01-01T12:00:00Z lvl=info msg="message"
regex = "^t=(?P<timestamp>[^ ]+) lvl=(?P<level>\\w+) msg=\"(?P<message>[^\"]*)\"";
extractFields = ["level"];
};
extraLabels = {
application = "grafana";
component = "dashboard";
};
};
}
{
homelab.services.${serviceName}.monitoring = mkDefault {
metrics.path = "/metrics";
healthCheck = {
path = "/api/health";
conditions = ["[STATUS] == 200" "[BODY].database == ok"];
};
extraLabels = {
component = "dashboard";
tier = "monitoring";
};
};
}
{
# Grafana needs auth by default (admin interface)
homelab.services.${serviceName}.proxy = mkDefault {
subdomain = "grafana";
# enableAuth = true;
};
}
]);
}