Monitoring AWS with OpenTelemetry means using the AWS Distro for OpenTelemetry (ADOT) and Collector receivers to collect CloudWatch metrics, traces and logs over OTLP, so AWS services sit in one open pipeline..
Monitoring AWS with OpenTelemetry means using the AWS Distro for OpenTelemetry (ADOT) and Collector receivers to collect CloudWatch metrics, traces and logs over OTLP, so AWS services sit in one open pipeline.
An AWS estate is many services, so the goal is one correlated view rather than a console tab per service: application error rate and latency, the saturation and throttling of the managed services underneath (RDS, DynamoDB, ELB, Lambda), and cost. The recurring pattern behind AWS incidents is an application symptom, elevated 5xx or latency, whose real cause is a throttled or saturated managed service one layer down.
The practical split is: use application traces (over OTLP) for request latency and error attribution, and pull CloudWatch metrics for the managed services you do not run yourself, then correlate the two so an ALB 5xx spike lines up with the unhealthy target or the throttled database behind it.
The clean way to collect AWS telemetry with OpenTelemetry is the AWS Distro for OpenTelemetry (ADOT), an AWS-supported build of the Collector. Its awscloudwatch receiver pulls CloudWatch metrics for managed services, application traces arrive over OTLP and integrate with AWS X-Ray, and Container Insights covers ECS and EKS. Everything exports over OTLP to your backend, so AWS data sits beside the rest of your telemetry.
Two operational notes: pulling from CloudWatch has both a cost and a delay (metrics are minute-granularity and the API is billed), so pull the managed-service metrics you need rather than everything, and lean on OTLP application traces for low-latency request data. Give the Collector an IAM role scoped to the CloudWatch and X-Ray reads it needs, no more.
Key CloudWatch signals by service, the ones behind most AWS incidents:
| Signal | Source | What it tells you / watch for |
|---|---|---|
AWS/RDS DatabaseConnections, CPUUtilization | awscloudwatch | Database connection saturation and CPU; the usual cause of an app that suddenly errors under load. |
AWS/ApplicationELB HTTPCode_Target_5XX_Count, TargetResponseTime | awscloudwatch | Load-balancer 5xx and latency; a spike here points at unhealthy or slow targets. |
AWS/ApplicationELB UnHealthyHostCount | awscloudwatch | Targets failing health checks, the reason an ELB starts shedding 5xx. |
AWS/Lambda Throttles, Errors, Duration | awscloudwatch | Serverless throttling, failures and functions creeping toward their timeout. |
AWS/DynamoDB ThrottledRequests, ConsumedReadCapacityUnits | awscloudwatch | Table throttling from exceeding provisioned capacity; shows up as application errors. |
application error rate / latency | OTLP traces | Request-level truth from your own services, to correlate with the managed-service metrics above. |
An AWS dashboard should be organised so an application symptom leads straight to the managed-service cause. Row one is the application: error rate and p95 latency by service, from your OTLP traces. Row two is the data and edge tier: RDS connections and CPU, ALB 5xx and unhealthy-host count, DynamoDB throttling. Row three is serverless and cost: Lambda throttles and duration-against-timeout, and daily spend by service so a runaway cost is visible the same day.
# ALB 5xx correlated with unhealthy targets
AWS/ApplicationELB.HTTPCode_Target_5XX_Count by (load_balancer)
AWS/ApplicationELB.UnHealthyHostCount by (target_group)
# RDS connection saturation
AWS/RDS.DatabaseConnections / rds_max_connections
# Lambda functions approaching their timeout
AWS/Lambda.Duration / lambda_timeout_ms by (function_name)
The application starts erroring under load, and AWS/RDS DatabaseConnections is pinned near the instance limit. Requests queue or fail to get a connection. The fix is a connection pooler (RDS Proxy) and finding the service that opens connections without releasing them, not simply a bigger instance.
HTTPCode_Target_5XX_Count spikes and UnHealthyHostCount rises together: the load balancer is returning 5xx because targets are failing health checks. Trace into the targets, the cause is usually the application on those instances crashing, out of memory, or dependent on something that is itself down.
Invocations throttle (concurrency limit reached) or their Duration creeps toward the configured timeout and they start failing. Watch throttles and duration-against-timeout; raise reserved concurrency for the former and profile the slow path or downstream call for the latter.
ThrottledRequests rises because reads or writes exceed provisioned (or burst) capacity, surfacing as application errors and retries. Switch to on-demand capacity or raise provisioned throughput, and check for a hot partition key concentrating traffic.
Starting thresholds to tune:
| Condition | Signal | Meaning |
|---|---|---|
| RDS DatabaseConnections / max > 0.85 for 5m | database | Connection exhaustion approaching. |
| ALB Target 5xx rate > 2% for 5m | edge | Targets failing behind the load balancer. |
| Lambda Throttles > 0 sustained | serverless | Hitting the concurrency ceiling. |
| DynamoDB ThrottledRequests > 0 for 5m | database | Exceeding table capacity. |
Ops Singularity's TelemetryOps ingests AWS telemetry over OpenTelemetry and its FinOps pillar tracks AWS cost, while Sentinel AI resolves incidents across the estate through governed Action Tickets. Explore TelemetryOps and FinOps.
Use the AWS Distro for OpenTelemetry (ADOT). The awscloudwatch receiver pulls CloudWatch metrics and logs, application traces arrive over OTLP and integrate with X-Ray, and everything exports over OTLP.
ADOT is the AWS Distro for OpenTelemetry, an AWS-supported distribution of the OpenTelemetry Collector and SDKs for collecting metrics, traces and logs from AWS services and applications.
Bring a real incident. We will show you Sentinel investigate, act and verify end to end, with every action reversible and audited.