at 25.11-pre 8.8 kB view raw
1{ 2 lib, 3 pkgs, 4 config, 5 ... 6}: 7let 8 cfg = config.services.amazon-cloudwatch-agent; 9 10 tomlFormat = pkgs.formats.toml { }; 11 jsonFormat = pkgs.formats.json { }; 12 13 # See https://docs.aws.amazon.com/prescriptive-guidance/latest/implementing-logging-monitoring-cloudwatch/create-store-cloudwatch-configurations.html#store-cloudwatch-configuration-s3. 14 # 15 # We don't use the multiple JSON configuration files feature, 16 # but "config-translator" will log a benign error if the "-input-dir" option is omitted or is a non-existent directory. 17 # 18 # Create an empty directory to hide this benign error log. This prevents false-positives if users filter for "error" in the agent logs. 19 configurationDirectory = pkgs.runCommand "amazon-cloudwatch-agent.d" { } "mkdir $out"; 20in 21{ 22 options.services.amazon-cloudwatch-agent = { 23 enable = lib.mkEnableOption "Amazon CloudWatch Agent"; 24 package = lib.mkPackageOption pkgs "amazon-cloudwatch-agent" { }; 25 commonConfigurationFile = lib.mkOption { 26 type = lib.types.path; 27 default = tomlFormat.generate "common-config.toml" cfg.commonConfiguration; 28 defaultText = lib.literalExpression ''tomlFormat.generate "common-config.toml" cfg.commonConfiguration''; 29 description = '' 30 Amazon CloudWatch Agent common configuration. See 31 <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html#CloudWatch-Agent-profile-instance-first> 32 for supported values. 33 34 {option}`commonConfigurationFile` takes precedence over {option}`commonConfiguration`. 35 36 Note: Restricted evaluation blocks access to paths outside the Nix store. 37 This means detecting content changes for mutable paths (i.e. not input or content-addressed) can't be done. 38 As a result, `nixos-rebuild` won't reload/restart the systemd unit when mutable path contents change. 39 `systemctl restart amazon-cloudwatch-agent.service` must be used instead. 40 ''; 41 example = "/etc/amazon-cloudwatch-agent/amazon-cloudwatch-agent.json"; 42 }; 43 commonConfiguration = lib.mkOption { 44 type = tomlFormat.type; 45 default = { }; 46 description = '' 47 See {option}`commonConfigurationFile`. 48 49 {option}`commonConfigurationFile` takes precedence over {option}`commonConfiguration`. 50 ''; 51 example = { 52 credentials = { 53 shared_credential_profile = "profile_name"; 54 shared_credential_file = "/path/to/credentials"; 55 }; 56 proxy = { 57 http_proxy = "http_url"; 58 https_proxy = "https_url"; 59 no_proxy = "domain"; 60 }; 61 }; 62 }; 63 configurationFile = lib.mkOption { 64 type = lib.types.path; 65 default = jsonFormat.generate "amazon-cloudwatch-agent.json" cfg.configuration; 66 defaultText = lib.literalExpression ''jsonFormat.generate "amazon-cloudwatch-agent.json" cfg.configuration''; 67 description = '' 68 Amazon CloudWatch Agent configuration file. See 69 <https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html> 70 for supported values. 71 72 The following options aren't supported: 73 * `agent.run_as_user` 74 * Use {option}`user` instead. 75 76 {option}`configurationFile` takes precedence over {option}`configuration`. 77 78 Note: Restricted evaluation blocks access to paths outside the Nix store. 79 This means detecting content changes for mutable paths (i.e. not input or content-addressed) can't be done. 80 As a result, `nixos-rebuild` won't reload/restart the systemd unit when mutable path contents change. 81 `systemctl restart amazon-cloudwatch-agent.service` must be used instead. 82 ''; 83 example = "/etc/amazon-cloudwatch-agent/amazon-cloudwatch-agent.json"; 84 }; 85 configuration = lib.mkOption { 86 type = jsonFormat.type; 87 default = { }; 88 description = '' 89 See {option}`configurationFile`. 90 91 {option}`configurationFile` takes precedence over {option}`configuration`. 92 ''; 93 # Subset of "CloudWatch agent configuration file: Complete examples" and "CloudWatch agent configuration file: Traces section" in the description link. 94 # 95 # Log file path changed from "/opt/aws/amazon-cloudwatch-agent/logs" to "/var/log/amazon-cloudwatch-agent" to follow the FHS. 96 example = { 97 agent = { 98 metrics_collection_interval = 10; 99 logfile = "/var/log/amazon-cloudwatch-agent/amazon-cloudwatch-agent.log"; 100 }; 101 metrics = { 102 namespace = "MyCustomNamespace"; 103 metrics_collected = { 104 cpu = { 105 resource = [ "*" ]; 106 measurement = [ 107 { 108 name = "cpu_usage_idle"; 109 rename = "CPU_USAGE_IDLE"; 110 unit = "Percent"; 111 } 112 { 113 name = "cpu_usage_nice"; 114 unit = "Percent"; 115 } 116 "cpu_usage_guest" 117 ]; 118 totalcpu = false; 119 metrics_collection_interval = 10; 120 append_dimensions = { 121 customized_dimension_key_1 = "customized_dimension_value_1"; 122 customized_dimension_key_2 = "customized_dimension_value_2"; 123 }; 124 }; 125 }; 126 }; 127 logs = { 128 logs_collected = { 129 files = { 130 collect_list = [ 131 { 132 file_path = "/var/log/amazon-cloudwatch-agent/amazon-cloudwatch-agent.log"; 133 log_group_name = "amazon-cloudwatch-agent.log"; 134 log_stream_name = "{instance_id}"; 135 timezone = "UTC"; 136 } 137 ]; 138 }; 139 }; 140 log_stream_name = "log_stream_name"; 141 force_flush_interval = 15; 142 }; 143 traces = { 144 traces_collected = { 145 xray = { }; 146 oltp = { }; 147 }; 148 }; 149 }; 150 }; 151 # Replaces "agent.run_as_user" from the configuration file. 152 user = lib.mkOption { 153 type = lib.types.str; 154 default = "root"; 155 description = '' 156 The user that runs the Amazon CloudWatch Agent. 157 ''; 158 example = "amazon-cloudwatch-agent"; 159 }; 160 mode = lib.mkOption { 161 type = lib.types.str; 162 default = "auto"; 163 description = '' 164 Amazon CloudWatch Agent mode. Indicates whether the agent is running in EC2 ("ec2"), on-premises ("onPremise"), 165 or if it should guess based on metadata endpoints like IMDS or the ECS task metadata endpoint ("auto"). 166 ''; 167 example = "onPremise"; 168 }; 169 }; 170 171 config = lib.mkIf cfg.enable { 172 # See https://github.com/aws/amazon-cloudwatch-agent/blob/v1.300049.1/packaging/dependencies/amazon-cloudwatch-agent.service. 173 systemd.services.amazon-cloudwatch-agent = { 174 description = "Amazon CloudWatch Agent"; 175 after = [ "network.target" ]; 176 wantedBy = [ "multi-user.target" ]; 177 serviceConfig = { 178 Type = "simple"; 179 # "start-amazon-cloudwatch-agent" assumes the package is installed at "/opt/aws/amazon-cloudwatch-agent" so we can't use it. 180 # 181 # See https://github.com/aws/amazon-cloudwatch-agent/issues/1319. 182 # 183 # This program: 184 # 1. Switches to a non-root user if configured. 185 # 2. Runs "config-translator" to translate the input JSON configuration files into separate TOML (for CloudWatch Logs + Metrics), 186 # YAML (for X-Ray + OpenTelemetry), and JSON (for environment variables) configuration files. 187 # 3. Runs "amazon-cloudwatch-agent" with the paths to these generated files. 188 # 189 # Re-implementing with systemd options. 190 User = cfg.user; 191 RuntimeDirectory = "amazon-cloudwatch-agent"; 192 LogsDirectory = "amazon-cloudwatch-agent"; 193 ExecStartPre = builtins.concatStringsSep " " [ 194 "${cfg.package}/bin/config-translator" 195 "-config ${cfg.commonConfigurationFile}" 196 "-input ${cfg.configurationFile}" 197 "-input-dir ${configurationDirectory}" 198 "-mode ${cfg.mode}" 199 "-output \${RUNTIME_DIRECTORY}/amazon-cloudwatch-agent.toml" 200 ]; 201 ExecStart = builtins.concatStringsSep " " [ 202 "${cfg.package}/bin/amazon-cloudwatch-agent" 203 "-config \${RUNTIME_DIRECTORY}/amazon-cloudwatch-agent.toml" 204 "-envconfig \${RUNTIME_DIRECTORY}/env-config.json" 205 "-otelconfig \${RUNTIME_DIRECTORY}/amazon-cloudwatch-agent.yaml" 206 "-pidfile \${RUNTIME_DIRECTORY}/amazon-cloudwatch-agent.pid" 207 ]; 208 KillMode = "process"; 209 Restart = "on-failure"; 210 RestartSec = 60; 211 }; 212 }; 213 }; 214}