at 23.11-pre 5.5 kB view raw
1{ lib, pkgs, config, generators, ... }: 2with lib; 3let 4 cfg = config.services.grafana-agent; 5 settingsFormat = pkgs.formats.yaml { }; 6 configFile = settingsFormat.generate "grafana-agent.yaml" cfg.settings; 7in 8{ 9 meta = { 10 maintainers = with maintainers; [ flokli zimbatm ]; 11 }; 12 13 options.services.grafana-agent = { 14 enable = mkEnableOption (lib.mdDoc "grafana-agent"); 15 16 package = mkPackageOptionMD pkgs "grafana-agent" { }; 17 18 credentials = mkOption { 19 description = lib.mdDoc '' 20 Credentials to load at service startup. Keys that are UPPER_SNAKE will be loaded as env vars. Values are absolute paths to the credentials. 21 ''; 22 type = types.attrsOf types.str; 23 default = { }; 24 25 example = { 26 logs_remote_write_password = "/run/keys/grafana_agent_logs_remote_write_password"; 27 LOGS_REMOTE_WRITE_URL = "/run/keys/grafana_agent_logs_remote_write_url"; 28 LOGS_REMOTE_WRITE_USERNAME = "/run/keys/grafana_agent_logs_remote_write_username"; 29 metrics_remote_write_password = "/run/keys/grafana_agent_metrics_remote_write_password"; 30 METRICS_REMOTE_WRITE_URL = "/run/keys/grafana_agent_metrics_remote_write_url"; 31 METRICS_REMOTE_WRITE_USERNAME = "/run/keys/grafana_agent_metrics_remote_write_username"; 32 }; 33 }; 34 35 extraFlags = mkOption { 36 type = with types; listOf str; 37 default = [ ]; 38 example = [ "-enable-features=integrations-next" "-disable-reporting" ]; 39 description = lib.mdDoc '' 40 Extra command-line flags passed to {command}`grafana-agent`. 41 42 See <https://grafana.com/docs/agent/latest/static/configuration/flags/> 43 ''; 44 }; 45 46 settings = mkOption { 47 description = lib.mdDoc '' 48 Configuration for {command}`grafana-agent`. 49 50 See <https://grafana.com/docs/agent/latest/configuration/> 51 ''; 52 53 type = types.submodule { 54 freeformType = settingsFormat.type; 55 }; 56 57 default = { }; 58 defaultText = lib.literalExpression '' 59 { 60 metrics = { 61 wal_directory = "\''${STATE_DIRECTORY}"; 62 global.scrape_interval = "5s"; 63 }; 64 integrations = { 65 agent.enabled = true; 66 agent.scrape_integration = true; 67 node_exporter.enabled = true; 68 }; 69 } 70 ''; 71 example = { 72 metrics.global.remote_write = [{ 73 url = "\${METRICS_REMOTE_WRITE_URL}"; 74 basic_auth.username = "\${METRICS_REMOTE_WRITE_USERNAME}"; 75 basic_auth.password_file = "\${CREDENTIALS_DIRECTORY}/metrics_remote_write_password"; 76 }]; 77 logs.configs = [{ 78 name = "default"; 79 scrape_configs = [ 80 { 81 job_name = "journal"; 82 journal = { 83 max_age = "12h"; 84 labels.job = "systemd-journal"; 85 }; 86 relabel_configs = [ 87 { 88 source_labels = [ "__journal__systemd_unit" ]; 89 target_label = "systemd_unit"; 90 } 91 { 92 source_labels = [ "__journal__hostname" ]; 93 target_label = "nodename"; 94 } 95 { 96 source_labels = [ "__journal_syslog_identifier" ]; 97 target_label = "syslog_identifier"; 98 } 99 ]; 100 } 101 ]; 102 positions.filename = "\${STATE_DIRECTORY}/loki_positions.yaml"; 103 clients = [{ 104 url = "\${LOGS_REMOTE_WRITE_URL}"; 105 basic_auth.username = "\${LOGS_REMOTE_WRITE_USERNAME}"; 106 basic_auth.password_file = "\${CREDENTIALS_DIRECTORY}/logs_remote_write_password"; 107 }]; 108 }]; 109 }; 110 }; 111 }; 112 113 config = mkIf cfg.enable { 114 services.grafana-agent.settings = { 115 # keep this in sync with config.services.grafana-agent.settings.defaultText. 116 metrics = { 117 wal_directory = mkDefault "\${STATE_DIRECTORY}"; 118 global.scrape_interval = mkDefault "5s"; 119 }; 120 integrations = { 121 agent.enabled = mkDefault true; 122 agent.scrape_integration = mkDefault true; 123 node_exporter.enabled = mkDefault true; 124 }; 125 }; 126 127 systemd.services.grafana-agent = { 128 wantedBy = [ "multi-user.target" ]; 129 script = '' 130 set -euo pipefail 131 shopt -u nullglob 132 133 # Load all credentials into env if they are in UPPER_SNAKE form. 134 if [[ -n "''${CREDENTIALS_DIRECTORY:-}" ]]; then 135 for file in "$CREDENTIALS_DIRECTORY"/*; do 136 key=$(basename "$file") 137 if [[ $key =~ ^[A-Z0-9_]+$ ]]; then 138 echo "Environ $key" 139 export "$key=$(< "$file")" 140 fi 141 done 142 fi 143 144 # We can't use Environment=HOSTNAME=%H, as it doesn't include the domain part. 145 export HOSTNAME=$(< /proc/sys/kernel/hostname) 146 147 exec ${lib.getExe cfg.package} -config.expand-env -config.file ${configFile} ${escapeShellArgs cfg.extraFlags} 148 ''; 149 serviceConfig = { 150 Restart = "always"; 151 DynamicUser = true; 152 RestartSec = 2; 153 SupplementaryGroups = [ 154 # allow to read the systemd journal for loki log forwarding 155 "systemd-journal" 156 ]; 157 StateDirectory = "grafana-agent"; 158 LoadCredential = lib.mapAttrsToList (key: value: "${key}:${value}") cfg.credentials; 159 Type = "simple"; 160 }; 161 }; 162 }; 163}