CloudWatch Enablement Reference

Several AWS services do not publish CloudWatch metrics or logs by default and require per-resource opt-in before telemetry appears in your streams or log groups. Enable the relevant services before configuring subscription filters or a metrics stream to ensure complete coverage.

General Administration

Limit Namespace and Region Scope

By default, the enrichment scraper fetches metadata from all supported namespaces in all regions. To reduce API call volume and cost, restrict the scope using the namespaces and regions lists in the Helm values shown in Configure Kloudfuse via Helm.

You can also limit which namespaces are included in the CloudWatch Metrics Stream itself (see Step 1) to reduce the volume of metrics forwarded to Kloudfuse.

Reduce Ingestion Costs

CloudWatch charges for metrics streams based on the number of metric updates forwarded. To reduce costs:

  • Use --include-filters when creating the metrics stream to forward only the namespaces you need.

  • Set namespaces in the Helm awsScraper config to match the namespaces in your stream.

  • Disable AutoScaling and S3 request metrics unless you specifically need them.

  • Use regions filtering to scrape only the regions where your workloads run.

Metrics Enablement

The following services require opt-in configuration before metrics appear in a CloudWatch Metrics Stream.

Service What requires enabling Charged separately?

AutoScaling

Group-level metrics (instance counts, scaling activity)

No

S3

Request metrics (GET, PUT, DELETE counts and latency)

Yes

EC2

1-minute granularity detailed monitoring (default is 5-minute)

Yes

RDS

Enhanced monitoring (OS-level metrics at up to 1-second resolution)

Yes

EBS

Volume-level I/O metrics (requires attaching to a running instance)

No

NAT Gateway

Per-gateway traffic and connection metrics

No

CloudFront

Additional distribution metrics (cache hit rate, origin latency, error rates)

Yes

API Gateway

Detailed metrics per route/resource (default publishes stage-level only)

No

AutoScaling Group Metrics

AutoScaling group metrics (instance counts, in-service counts, and scaling activity) are not published by default. Enable them for each group you want to monitor:

aws autoscaling enable-metrics-collection \
  --auto-scaling-group-name my-asg \
  --granularity "1Minute"
bash

To enable for all AutoScaling groups in a region:

aws autoscaling describe-auto-scaling-groups \
  --query 'AutoScalingGroups[*].AutoScalingGroupName' \
  --output text | tr '\t' '\n' | while read ASG; do
    aws autoscaling enable-metrics-collection \
      --auto-scaling-group-name "$ASG" \
      --granularity "1Minute"
    echo "Enabled metrics for: $ASG"
  done
bash

S3 Request Metrics

S3 storage metrics (bucket size, object count) are published by default, but request metrics (GET, PUT, DELETE counts, latency, and errors) are opt-in and charged separately. Enable them per bucket:

aws s3api put-bucket-metrics-configuration \
  --bucket my-bucket \
  --id kloudfuse-metrics \
  --metrics-configuration '{"Id": "kloudfuse-metrics"}'
bash

To apply a filter and only collect metrics for objects under a specific prefix:

aws s3api put-bucket-metrics-configuration \
  --bucket my-bucket \
  --id kloudfuse-prefix-metrics \
  --metrics-configuration '{
    "Id": "kloudfuse-prefix-metrics",
    "Filter": {"Prefix": "logs/"}
  }'
bash
S3 request metrics incur additional CloudWatch charges. See the CloudWatch pricing page for current rates.

EC2 Detailed Monitoring

EC2 instances publish metrics at 5-minute resolution by default (basic monitoring). Enable detailed monitoring to get 1-minute resolution — required for accurate autoscaling and alerting:

aws ec2 monitor-instances --instance-ids i-1234567890abcdef0
bash

To enable for all running instances in a region:

aws ec2 describe-instances \
  --filters "Name=instance-state-name,Values=running" \
  --query 'Reservations[*].Instances[*].InstanceId' \
  --output text | tr '\t' '\n' | while read ID; do
    aws ec2 monitor-instances --instance-ids "$ID"
    echo "Enabled detailed monitoring for: $ID"
  done
bash
Detailed monitoring is charged per instance per month. See the CloudWatch pricing page for current rates.

RDS Enhanced Monitoring

RDS Enhanced Monitoring publishes OS-level metrics (CPU steal, swap, per-process stats) at up to 1-second resolution via CloudWatch Logs rather than CloudWatch Metrics. Enable it per DB instance:

aws rds modify-db-instance \
  --db-instance-identifier my-db \
  --monitoring-interval 60 \
  --monitoring-role-arn arn:aws:iam::<account-id>:role/rds-monitoring-role \
  --apply-immediately
bash

The --monitoring-interval value can be 1, 5, 10, 15, 30, or 60 seconds.

The monitoring-role-arn must be an IAM role that allows RDS to write to CloudWatch Logs. To create the role:

aws iam create-role \
  --role-name rds-monitoring-role \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "monitoring.rds.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

aws iam attach-role-policy \
  --role-name rds-monitoring-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole
bash
Enhanced Monitoring metrics flow through CloudWatch Logs (log group /aws/rds/instance/<id>/os), not the CloudWatch Metrics Stream. To ingest them in Kloudfuse, add a CloudWatch Logs subscription filter for that log group — see AWS CloudWatch Logs Integration.

EBS Volume Metrics

EBS publishes volume-level metrics (VolumeReadBytes, VolumeWriteBytes, VolumeReadOps, VolumeWriteOps, VolumeTotalReadTime, VolumeTotalWriteTime) automatically for attached volumes at 5-minute resolution — no enablement required.

However, VolumeThroughputPercentage and VolumeConsumedReadWriteOps (for io1/io2 provisioned IOPS volumes only) are only published when the volume is attached to a running instance with detailed monitoring enabled.

Enable detailed monitoring on the attached EC2 instance as described in EC2 Detailed Monitoring.

NAT Gateway Metrics

NAT Gateway publishes metrics automatically once the gateway is created. No extra enablement is required; however, metrics are only published when traffic flows through the gateway.

If metrics are missing, confirm that:

  • The NAT Gateway is in an available state: aws ec2 describe-nat-gateways --filter "Name=state,Values=available"

  • Traffic is actively routing through the gateway (metrics have a 1-minute delay).

CloudFront Additional Metrics

CloudFront publishes a basic set of metrics by default (requests, bytes downloaded, error rate). A second tier of additional metrics (cache hit rate, origin latency, P50/P75/P90/P95/P99 latency, bytes uploaded) must be enabled per distribution and are charged separately:

aws cloudfront create-monitoring-subscription \
  --distribution-id EDFDVBD6EXAMPLE \
  --monitoring-subscription '{
    "RealtimeMetricsSubscriptionConfig": {
      "RealtimeMetricsSubscriptionStatus": "Enabled"
    }
  }'
bash

To check the current subscription status for a distribution:

aws cloudfront get-monitoring-subscription --distribution-id EDFDVBD6EXAMPLE
bash
CloudFront additional metrics are charged per distribution per month. See the CloudWatch pricing page for current rates.

API Gateway Detailed Metrics

API Gateway (REST API) publishes stage-level metrics by default. Route-level (per-method) metrics must be enabled per stage. Enabling them also enables access logging if not already configured:

aws apigateway update-stage \
  --rest-api-id <api-id> \
  --stage-name <stage-name> \
  --patch-operations op=replace,path=/*/*/metrics/enabled,value=true
bash

For HTTP APIs (API Gateway v2), detailed metrics are enabled per stage via the defaultRouteSettings:

aws apigatewayv2 update-stage \
  --api-id <api-id> \
  --stage-name <stage-name> \
  --default-route-settings '{"DetailedMetricsEnabled": true}'
bash
Detailed metrics for REST APIs add one CloudWatch metric per route per stage. In APIs with many routes this can increase CloudWatch costs significantly — enable selectively for high-value stages (for example, prod).

Logs Enablement

The following services do not write to CloudWatch Logs by default. Enable them before creating subscription filters to forward logs to Kloudfuse.

Service What requires enabling Log destination

VPC Flow Logs

Per-VPC, subnet, or ENI traffic logs

CloudWatch Logs or S3

RDS Logs

Slow query, error, audit, and general logs (varies by engine)

CloudWatch Logs

EKS Control Plane Logs

API server, audit, authenticator, controller manager, scheduler

CloudWatch Logs

CloudTrail to CloudWatch Logs

API audit trail delivered to a log group

CloudWatch Logs

API Gateway Access Logs

Per-stage access logging

CloudWatch Logs

WAF Logs

Per-WebACL request logs

CloudWatch Logs, S3, or Firehose

VPC Flow Logs

VPC Flow Logs capture accepted and rejected IP traffic for a VPC, subnet, or network interface. They are not enabled by default. Enable them and route to a CloudWatch Logs log group:

aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids vpc-12345678 \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name /aws/vpc/flowlogs \
  --deliver-logs-permission-arn arn:aws:iam::<account-id>:role/FlowLogsRole
bash

The IAM role must allow logs:CreateLogGroup, logs:CreateLogStream, and logs:PutLogEvents. Create it with:

aws iam create-role \
  --role-name FlowLogsRole \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "vpc-flow-logs.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

aws iam attach-role-policy \
  --role-name FlowLogsRole \
  --policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
bash

Once enabled, add a subscription filter on the /aws/vpc/flowlogs log group — see AWS CloudWatch Logs Integration.

RDS Logs

RDS does not publish logs to CloudWatch by default. The available log types depend on the database engine:

Engine Available log types

MySQL / MariaDB

error, slowquery, audit, general

PostgreSQL

postgresql, upgrade

Oracle

alert, audit, listener, trace

SQL Server

error, agent

Enable log export per DB instance:

aws rds modify-db-instance \
  --db-instance-identifier my-db \
  --cloudwatch-logs-export-configuration '{"EnableLogTypes":["error","slowquery"]}' \
  --apply-immediately
bash

Logs appear in CloudWatch under /aws/rds/instance/<db-instance-identifier>/<log-type>. Add a subscription filter on each log group to forward to Kloudfuse — see AWS CloudWatch Logs Integration.

EKS Control Plane Logs

EKS control plane logging is disabled by default. Enable the log types you need per cluster:

aws eks update-cluster-config \
  --name my-cluster \
  --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'
bash

You can enable a subset — audit is the most commonly needed for security and compliance monitoring. Logs appear in CloudWatch under /aws/eks/<cluster-name>/cluster.

CloudTrail to CloudWatch Logs

CloudTrail records API activity across your AWS account. By default it does not deliver to CloudWatch Logs — it writes to S3. To also deliver to a log group:

LOG_GROUP_ARN=$(aws logs create-log-group \
  --log-group-name CloudTrail/DefaultLogGroup \
  && aws logs describe-log-groups \
    --log-group-name-prefix CloudTrail/DefaultLogGroup \
    --query 'logGroups[0].arn' --output text)

aws cloudtrail update-trail \
  --name my-trail \
  --cloud-watch-logs-log-group-arn "$LOG_GROUP_ARN" \
  --cloud-watch-logs-role-arn arn:aws:iam::<account-id>:role/CloudTrail_CloudWatchLogs_Role
bash

The IAM role must allow logs:CreateLogStream and logs:PutLogEvents for the log group.

If you are using the EventBridge integration for CloudTrail events, you do not need to route CloudTrail to CloudWatch Logs as well — see AWS EventBridge Integration.

API Gateway Access Logs

API Gateway does not write access logs by default. Enable them per stage by pointing to a CloudWatch Logs log group ARN:

LOG_GROUP_ARN=$(aws logs create-log-group \
  --log-group-name /aws/apigateway/my-api \
  && aws logs describe-log-groups \
    --log-group-name-prefix /aws/apigateway/my-api \
    --query 'logGroups[0].arn' --output text)

aws apigateway update-stage \
  --rest-api-id <api-id> \
  --stage-name <stage-name> \
  --patch-operations \
    op=replace,path=/accessLogSettings/destinationArn,value="$LOG_GROUP_ARN"
bash

For HTTP APIs (v2):

aws apigatewayv2 update-stage \
  --api-id <api-id> \
  --stage-name <stage-name> \
  --access-log-settings DestinationArn="$LOG_GROUP_ARN"
bash

WAF Logs

AWS WAF does not log requests by default. Enable logging per WebACL — the destination can be CloudWatch Logs, S3, or Kinesis Firehose. To send directly to CloudWatch Logs:

aws wafv2 put-logging-configuration \
  --logging-configuration '{
    "ResourceArn": "arn:aws:wafv2:<region>:<account-id>:regional/webacl/my-webacl/<id>",
    "LogDestinationConfigs": [
      "arn:aws:logs:<region>:<account-id>:log-group:aws-waf-logs-kloudfuse"
    ]
  }'
bash

The log group name must start with aws-waf-logs-. WAF creates the log group automatically if it does not exist.

WAF logging is charged per GB of log data delivered. See the WAF pricing page for current rates.