๐ Logging & Observability
Observability is your ability to understand what is happening inside your application from the outside. It's built on three pillars: Logs, Metrics, and Traces โ and how you use them together.
๐ Covers: 3 Pillars ยท Structured Logging ยท Centralized Logging ยท Lambda Powertools ยท Anomaly TrackingWhat is Observability?
Observability is the ability to answer questions about your system's internal state using only the data it outputs (without needing to change or probe the system directly). A system is "observable" if, when something goes wrong, you can figure out why โ just from the data it emits.
๐๏ธ The Three Pillars of Observability
๐ Pillar 1 โ Metrics
What: Numbers aggregated over time.
Examples: Requests/second, error rate %, CPU %, memory MB, latency ms.
Good for: Trending, alerting, capacity planning. Tells you THAT something is wrong.
AWS tool: CloudWatch Metrics
๐ Pillar 2 โ Logs
What: Text records of discrete events with timestamps.
Examples: "User login", "Payment failed", "Request processed in 340ms".
Good for: Debugging specific incidents. Tells you WHAT happened and the context.
AWS tool: CloudWatch Logs
๐ Pillar 3 โ Traces
What: The path of one request through all services.
Examples: Request went to API Gateway โ Lambda โ DynamoDB (3.7s bottleneck).
Good for: Distributed systems, finding WHERE a bottleneck is.
AWS tool: AWS X-Ray
Structured Logging โ Make Logs Machine-Readable
Unstructured logging is when your logs are just random text strings. Structured logging means writing logs in a consistent, machine-parseable format โ usually JSON. This makes logs searchable, filterable, and processable by tools like CloudWatch Logs Insights.
โ Unstructured Log (BAD)
User login successful for [email protected]ERROR payment failed order 12345 user 789Request processed in 340ms status 200
Problems: Hard to parse, inconsistent format, can't easily extract values, hard to search across logs.
โ Structured Log (GOOD)
{"level":"INFO","event":"login","userId":"[email protected]","timestamp":"2024-01-15T14:32:07Z"}{"level":"ERROR","event":"payment_failed","orderId":"12345","userId":"789","timestamp":"..."}{"level":"INFO","event":"request","duration":340,"statusCode":200,"path":"/api/orders"}
Benefits of Structured Logging
- Queryable: With CloudWatch Logs Insights, you can query
filter userId = "789"and find all log events for that user instantly - Consistent: All team members and all services log the same fields in the same format
- Machine-readable: Automated systems can parse and act on log data
- Metric extraction: You can use Metric Filters or EMF to automatically extract numbers from structured JSON logs
๐ Standard Log Fields to Always Include
| Field | Purpose | Example |
|---|---|---|
timestamp | When it happened (ISO 8601) | "2024-01-15T14:32:07Z" |
level | Severity | "INFO", "WARN", "ERROR" |
service | Which service logged it | "OrderService" |
correlationId | Unique ID to trace across services | "req-abc123" |
requestId | Lambda/API GW request ID | "a1b2c3d4-..." |
message | Human-readable description | "Order processed successfully" |
userId | User context | "user-789" |
duration | How long the operation took (ms) | 340 |
Centralized Logging โ One Place for All Logs
When you have 10+ microservices, each writing logs separately, you have a problem: to debug a user's issue, you'd need to search logs in 10 different places. Centralized logging means aggregating all logs from all services into one searchable place.
๐ Correlation IDs โ The Key to Cross-Service Debugging
When a request flows through 5 services and fails at step 4, how do you find all the related log entries across all 5 services? By passing a Correlation ID (also called Request ID or Trace ID) through every service call, and including it in every log entry.
correlationId = "REQ-abc123"This ID is passed to Lambda โ Lambda passes it to DynamoDB calls โ Lambda passes it to SES โ etc.
Every log entry from every service includes
"correlationId": "REQ-abc123"Now search CloudWatch Logs Insights:
filter correlationId = "REQ-abc123"You instantly see the complete story of that one order across all 5 services.
AWS Lambda Powertools โ Simplified Observability for Lambda
Lambda Powertools is an open-source library (available for Python, Node.js, Java, .NET) that provides structured logging, distributed tracing (X-Ray), and metrics (EMF) with minimal code. It implements best practices out of the box.
๐ง Three Core Utilities
๐ Logger
Structured JSON logging with automatic injection of: Lambda context (function name, request ID, cold start indicator), log level filtering, correlation IDs.
๐ Metrics
EMF-based metrics with a simple API. Creates CloudWatch metrics from log writes. No separate API calls. Auto-flushes at end of each Lambda invocation.
๐ Tracer
X-Ray tracing with automatic annotation, subsegment creation for AWS SDK calls, and response/error capture. Works with Active Tracing enabled.
User Behavior Logging & Anomaly Tracking
Beyond technical metrics, good observability includes logging user behavior and detecting anomalies (unusual patterns that might indicate a bug, attack, or business problem).
๐ค User Behavior Logging
Log what users do in your application to understand usage patterns and identify issues:
- Which features are used most? (product analytics)
- Where do users drop off in the checkout flow? (funnel analysis)
- Which users are generating the most errors? (identify problematic clients)
- What did a specific user do right before they reported a bug? (reproduce issues)
๐ Anomaly Detection
CloudWatch has Anomaly Detection โ a machine learning feature that learns the normal patterns of a metric and automatically alerts when values deviate from the expected range.
- Learns seasonal patterns (traffic spikes on Mondays, low traffic at 3am)
- Automatically adjusts expected range based on historical data
- You don't need to set hard thresholds โ it adapts automatically
- Use case: "Alert me when traffic drops unexpectedly" (even if you don't know what the threshold should be)
๐ System State Logging
Log system state at important transitions โ not just errors:
- Application startup/shutdown
- Configuration changes
- Database connection pool state
- Cache hit/miss rates
- Queue depths
This data helps you understand why a spike occurred โ was it a deployment? A config change? An external event?