SaveMyCert
Log in
5 of 5 free questions left today·for unlimited practice
Troubleshooting and Optimization

Instrument Code for Observability: CloudWatch, X-Ray, and Alarms

15 min readDVA-C02 · Troubleshooting and OptimizationUpdated

Observability is the ability to understand what is happening inside your application from the telemetry it emits — logs, metrics, and traces — well enough to diagnose failures you never predicted. Task 4.2 of the DVA-C02 exam tests whether you can produce that telemetry from code: design a logging strategy that records the right events and never the wrong ones, emit structured JSON logs with correlation IDs, publish custom metrics through PutMetricData or embedded metric format, instrument distributed tracing with AWS X-Ray, wire alerts through CloudWatch alarms and EventBridge, and configure health checks that tell load balancers the truth. It also tests definitions directly: logging versus monitoring versus observability, and annotations versus metadata, are classic exam distinctions. This lesson covers every skill in the task, along with the trade-offs — synchronous versus asynchronous metric publication, indexed versus unindexed trace data, shallow versus deep health checks — that exam answers turn on.

What you’ll learn
  • Distinguish logging, monitoring, and observability, and recognize which one an exam question is describing
  • Design a logging strategy that captures state transitions and identifiers while excluding secrets and PII
  • Implement structured JSON logging with correlation IDs propagated across service boundaries
  • Choose between PutMetricData and embedded metric format, and configure metric resolution and dimensions deliberately
  • Instrument distributed tracing with AWS X-Ray: segments, subsegments, sampling, and annotations versus metadata
  • Configure alerts through CloudWatch alarms, SNS, and EventBridge, and design health checks that avoid cascading failures

Logging, monitoring, and observability: the definitional ladder

These three terms form a ladder, and the exam tests the rungs directly. Logging is the act of recording discrete events as they happen — a request arrived, a payment failed, an exception was thrown. A log is raw material: it states what occurred at a point in time, with whatever context the code chose to include.

Monitoring is watching known signals against expectations — collecting metrics, graphing them, and alarming when a threshold is crossed. Monitoring answers questions you knew to ask in advance: is the error rate acceptable, is p99 latency in bounds, is the queue draining. It is reactive by design and blind to anything you did not think to measure.

Observability is a property of the system rather than an activity: a system is observable when its outputs — logs, metrics, and traces together — are rich enough that you can work out its internal state and diagnose problems you never anticipated, without shipping new instrumentation first. Monitoring tells you a known symptom appeared; observability lets you ask brand-new questions of telemetry you already have. Those three signal types are commonly called the three pillars of observability, and instrumenting all of them from code is what this task is about.

The exam phrasing to recognize: "known issues and predefined thresholds" describes monitoring; "understand internal state from external outputs" and "investigate previously unknown issues" describe observability; "a record of discrete events" describes logging. Questions often present all three as options and reward the candidate who keeps the definitions straight.

Designing an effective logging strategy

An effective logging strategy decides, before any incident, what gets recorded, at what level, and for how long. What to log: state transitions (order created, payment authorized, message rejected), the identifiers needed to follow one transaction (request ID, order ID, user ID), decision outcomes with the inputs that drove them, and every error with enough context to reproduce it. Log at boundaries — incoming requests, outgoing calls, queue interactions — because boundaries are where failures get diagnosed.

What never to log: secrets, API keys, session and bearer tokens, passwords, full payment card numbers, and personally identifiable information beyond what your data policies allow. Logs fan out to many systems and many readers; a credential in a log line is a credential leaked, and scrubbing after the fact is unreliable. Sanitize at the logging call site, not downstream.

Levels: use the conventional ladder — DEBUG for high-volume diagnostic detail, INFO for normal state transitions, WARN for handled anomalies, ERROR for failures needing attention — and make the active level configurable through an environment variable, so production runs at INFO and can be dropped to DEBUG during an investigation without a code change or redeploy of new logic.

Retention: CloudWatch Logs groups keep events indefinitely by default, which quietly becomes a storage bill. Set a retention policy on each log group that matches the data's diagnostic and compliance value. Retention is configuration on the log group, not something application code manages.

Structured logging and correlation IDs

Structured logging means emitting each log event as a machine-parseable record — in practice, one JSON object per line with consistent field names — instead of free-form text. The payoff is queryability: CloudWatch Logs Insights automatically discovers JSON fields, so filter level = "ERROR" and orderId = "o-8817" just works, with no brittle parse patterns over hand-formatted strings. Consistent fields across services (level, service, requestId, durationMs) mean one query style and one mental model for the whole system. Version 2.1 of the exam guide calls this skill out explicitly, so expect it to appear.

The keystone field is the correlation ID: one identifier minted at the edge of the system — commonly the API Gateway request ID, or an ID your first service generates — and passed along with the work through every hop: HTTP headers to downstream services, message attributes on SQS messages, the detail of EventBridge events. Every service writes it into every structured log line it emits for that transaction. The result is that a single Logs Insights query across log groups reassembles the complete story of one transaction, no matter how many services touched it. Without propagation, each service's logs are an island and cross-service debugging becomes guesswork.

You can implement this by hand with a logging wrapper that merges standard fields into every record, but on Lambda the idiomatic implementation is AWS Lambda Powertools: its logger emits structured JSON, enriches records with function context automatically, and appends correlation IDs extracted from the incoming event. Know it at concept level — a structured logger, EMF-based metrics, and tracing utilities in one library.

Emitting custom metrics: PutMetricData versus embedded metric format

Business-level signals — checkouts per minute, cache hit ratio, failures per payment provider — do not exist until your code emits them, and you have two publication paths to choose between.

PutMetricData is the CloudWatch API: your code calls it, ideally batching datapoints, and the metric exists once the call succeeds. It works from anywhere with credentials, but the call sits in your request path: it adds latency, it is subject to API quotas and throttling, and under load you end up maintaining buffering and flush logic that has nothing to do with your business domain.

Embedded metric format (EMF) inverts the model: your code writes a structured JSON log line whose _aws block declares the namespace, dimensions, and metric fields, and CloudWatch extracts the metrics from the log stream asynchronously. Nothing synchronous happens in your hot path, and every datapoint keeps its full log context queryable afterward.

PutMetricDataEmbedded metric format
DeliverySynchronous API callLog line, extracted asynchronously
Hot-path costLatency plus API quotasNone beyond writing a log line
Request context keptNo — numbers onlyYes — the log event remains queryable
Best fitCode without CloudWatch-connected loggingLambda and high-volume services already logging to CloudWatch

Two more knobs the exam checks. Resolution: standard metrics store at one-minute granularity; high-resolution metrics accept one-second granularity for latency-sensitive alarming. Dimensions: name-value pairs that qualify a metric — but every unique combination of dimension values is a separate metric, so an unbounded dimension such as a per-user ID explodes cardinality and cost.

Distributed tracing with AWS X-Ray

AWS X-Ray records the path of individual requests across your services so latency and errors can be attributed to a specific hop. The moving parts: the X-Ray SDK in your code records segments — one per service handling the request — and subsegments for the work inside them, especially downstream calls. The SDK does not call the X-Ray API directly; it emits segment documents over UDP to the X-Ray daemon, a local agent that buffers and uploads them in batches, keeping tracing overhead out of your request path. A trace header propagated on outbound calls stitches every service's segments into one trace.

Instrumenting is mostly wrapping. Patch your AWS SDK clients and subsegments for every DynamoDB, S3, or SQS call appear automatically; wrap your HTTP client and outbound calls to third-party APIs are captured too. On Lambda you enable active tracing on the function and the platform runs the daemon for you; API Gateway can enable tracing per stage, so the trace begins before your code runs.

Tracing every request would be costly, so X-Ray samples: the default rule records the first request each second plus 5% of any additional requests, and you can define sampling rules to trace more of the traffic that matters most.

Concretely, an instrumented order flow — API Gateway with tracing enabled, an order Lambda function with active tracing and a patched SDK client, a DynamoDB write, and an HTTPS call to a payment provider — produces one trace with a segment per hop and subsegments for the table write and the payment call. When checkout is slow, that trace shows whether the time sits in your function's own code, the table write, or the third-party API.

Annotations versus metadata: what gets indexed

Both annotations and metadata attach your own data to X-Ray segments, and the difference between them is one of the most reliably tested distinctions in this domain: annotations are indexed, metadata is not.

Annotations are simple key-value pairs — strings, numbers, or booleans — that X-Ray indexes for search. Record customerId, orderId, or tier as annotations and filter expressions can pull up exactly the traces that match: every trace for one customer, every failed trace where paymentProvider = "cardco". X-Ray supports up to 50 annotations per segment, so reserve them for the handful of business identifiers you will actually filter or group by.

Metadata accepts arbitrary JSON — request payloads, configuration snapshots, structured debugging context. It is visible when you open an individual trace, but it is not indexed and can never appear in a filter expression. Use it for rich context you want available once you have already found the trace by other means.

AnnotationsMetadata
Indexed and searchableYes — usable in filter expressionsNo
Data typesString, number, booleanAny JSON
Use forIdentifiers you filter or group byRich context you read after finding a trace

The exam phrasing is nearly a password: any question about "filtering traces by customer," "searching traces for a specific order," or "grouping traces by a business attribute" is answered by annotations. A value stored as metadata can never be found by a filter expression — that is the trap the wrong options rely on.

Alerts: CloudWatch alarms, SNS, and EventBridge

Telemetry only helps if someone finds out in time, and the exam expects you to route two different kinds of signal through two different mechanisms.

Threshold breaches go through CloudWatch alarms. An alarm watches one metric — built-in or custom; a metric emitted through embedded metric format alarms like any other — and changes state when the value crosses a threshold for a configured number of evaluation periods; requiring several consecutive datapoints keeps a single noisy spike from paging anyone. Alarm actions publish to an Amazon SNS topic, which fans out to email, SMS, HTTPS endpoints, or a Lambda function that opens a ticket or posts to chat. Composite alarms combine other alarms with AND/OR logic — alert only when the error-rate alarm and the latency alarm fire together — which cuts noise during incidents that trip many related alarms at once.

Discrete operational events go through Amazon EventBridge. A deployment completing or failing, a pipeline changing state, a service quota approaching its limit — these are not metrics crossing thresholds; they are events that occur. AWS services publish them to EventBridge, where a rule matches on the event pattern — a CodeDeploy deployment entering a failed state, a CodePipeline execution succeeding, a Service Quotas or Trusted Advisor notification about an approaching limit — and routes to targets such as an SNS topic or a Lambda function.

The split to carry into the exam: "notify when a metric is too high" is an alarm plus SNS; "notify when a deployment completes" or "when nearing a quota" is an EventBridge rule. Choosing an alarm for a discrete event, or polling an API for state changes, is the distractor.

Health checks and readiness probes

A health check is an endpoint or command that reports whether one instance of your application can do its job, and the current exam guide added the skill to this task. Two purposes must not be conflated. A liveness check asks "is this process alive at all?" — failing it means the process is hung or dead and should be restarted. A readiness probe asks "can this instance take traffic right now?" — failing it means the instance should be temporarily removed from rotation (still warming up, still loading configuration, momentarily overloaded) but not killed. Restarting an instance that merely was not ready yet is how warmup problems become outages.

AWS provides health checking at several layers. An Application Load Balancer probes each target on a configured path and routes only to targets that pass; healthy and unhealthy thresholds — consecutive successes or failures required to change state — prevent flapping. Amazon Route 53 health checks operate at the DNS layer, steering resolution away from unhealthy endpoints for failover between regions or sites. In Amazon ECS, the task definition can declare a container health check command that runs inside the container, letting the scheduler replace containers that fail it.

Shallow versus deep is the design decision the exam probes. A shallow check returns healthy if the process is up and serving requests. A deep check also verifies dependencies — database reachable, downstream API answering. Deep checks look responsible but carry a failure mode: when one shared dependency blips, every instance's deep check fails simultaneously, the load balancer marks the whole fleet unhealthy, and a partial degradation becomes a total outage. The usual guidance: keep liveness shallow, scope readiness to dependencies the individual instance owns, and surface shared-dependency health through metrics and alarms instead.

Tip. The exam tests this task through definitions and trigger phrases as much as scenarios. "Filter traces by customer" or any searchable business attribute → annotations, never metadata; "custom metrics without throttling or added latency" → embedded metric format; "understand internal state from outputs" or "diagnose previously unknown issues" → observability, not monitoring; "notify on deployment completion" → an EventBridge rule, while a metric crossing a threshold means a CloudWatch alarm publishing to SNS. Health-check questions hinge on the liveness-versus-readiness distinction and on recognizing that deep checks against shared dependencies cascade failures across a fleet.

Key takeaways
  • Logging records events, monitoring watches known thresholds, observability lets you diagnose problems you never predicted from telemetry you already emit.
  • Never log secrets, tokens, or PII; log state transitions and identifiers at a level set by environment variable, and set log group retention explicitly.
  • Structured JSON logs with a correlation ID propagated across every hop make one transaction queryable end to end in Logs Insights.
  • Embedded metric format publishes metrics through log lines — asynchronous and immune to PutMetricData throttling; every unique dimension combination is a separate metric.
  • X-Ray annotations are indexed and filterable (up to 50 per segment); metadata holds any JSON but can never appear in a filter expression.
  • Default X-Ray sampling traces the first request each second plus 5% of the rest; Lambda active tracing runs the daemon for you.
  • Metric thresholds alert via CloudWatch alarms to SNS, with composite alarms to cut noise; discrete events like deployment completions route via EventBridge rules.
  • Readiness gates traffic and liveness gates restarts — and deep health checks on shared dependencies can cascade one blip into a fleet-wide outage.

Frequently asked questions

What is the difference between logging, monitoring, and observability?

Logging is recording discrete events as they happen — the raw record of what occurred. Monitoring is watching known signals against thresholds you defined in advance, and alerting when they are crossed; it only catches problems you anticipated. Observability is a property of the system: when its logs, metrics, and traces are rich enough, you can work out its internal state and diagnose failures you never predicted, without adding new instrumentation first. Monitoring answers known questions; observability lets you ask new ones.

What is the difference between X-Ray annotations and metadata?

Annotations are simple key-value pairs (strings, numbers, booleans) that X-Ray indexes, so filter expressions can search traces by them — up to 50 per segment. Metadata accepts arbitrary JSON but is not indexed: it is visible inside an individual trace, and no filter expression can ever match on it. Use annotations for business identifiers you will filter or group by, such as a customer or order ID, and metadata for rich context you only need after you have found the trace.

When should I use embedded metric format instead of PutMetricData?

Use embedded metric format (EMF) when your code already logs to CloudWatch — especially Lambda functions and high-volume services. EMF publishes metrics by writing structured JSON log lines that CloudWatch extracts asynchronously, so there is no API call in your hot path, no PutMetricData throttling, and each datapoint keeps its request context queryable in Logs Insights. PutMetricData remains the option for code that is not connected to CloudWatch Logs, and it should be batched when used.

How does AWS X-Ray sampling work by default?

By default X-Ray records the first request each second, plus 5% of any additional requests beyond that. The fixed one-per-second portion guarantees a baseline trace even at low traffic, while the percentage keeps costs proportional at high traffic. You can define custom sampling rules to raise coverage for specific services, routes, or request properties when some traffic deserves closer inspection than the default provides.

What is the difference between a liveness check and a readiness probe?

A liveness check answers "is this process alive?" — failing it means the process is hung or dead and should be restarted. A readiness probe answers "can this instance serve traffic right now?" — failing it means the instance should be taken out of rotation temporarily, for example while warming up or loading configuration, but not restarted. Confusing them causes real damage: restarting instances that are merely not ready turns a warmup delay into an outage.

How do I get notified when a deployment completes or a quota limit is near?

Use an Amazon EventBridge rule, not a CloudWatch alarm. Deployment completions and quota warnings are discrete events, not metrics crossing thresholds: AWS services such as CodeDeploy and CodePipeline publish state-change events to EventBridge, and Service Quotas and Trusted Advisor emit notifications about approaching limits. A rule matching the event pattern routes it to a target such as an SNS topic for human notification or a Lambda function for automated response.

Test yourself on this topic
Practice questions with full explanations.
Practice now

Sign up free to mark lessons complete, bookmark topics and track your exam readiness.