CloudWatch
Logs e métricas com Amazon CloudWatch.
Logs
Structured Logging (JSON)
Python (Backend):
import json
import logging
from pythonjsonlogger import jsonlogger
logger = logging.getLogger()
logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter()
logHandler.setFormatter(formatter)
logger.addHandler(logHandler)
logger.setLevel(logging.INFO)
# Usage
logger.info("User logged in", extra={
"user_id": user.id,
"email": user.email,
"ip_address": request.client.host,
"correlation_id": correlation_id
})
Output:
{
"message": "User logged in",
"user_id": 123,
"email": "user@example.com",
"ip_address": "192.168.1.1",
"correlation_id": "abc-123-def",
"timestamp": "2026-01-20T10:30:00Z",
"level": "INFO",
"logger": "app.auth"
}
Log Groups
Cada Lambda tem seu log group:
/aws/lambda/app-user-api-staging/aws/lambda/app-user-api-production/aws/lambda/app-payment-processor-staging/aws/lambda/app-payment-processor-production
Retention
- Staging: 30 dias
- Production: 90 dias
Searching Logs
# Via AWS CLI
aws logs filter-log-events \
--log-group-name /aws/lambda/app-user-api-production \
--filter-pattern '{ $.user_id = 123 }' \
--start-time $(date -d '1 hour ago' +%s)000
# Via CloudWatch Insights
CloudWatch Insights Queries:
-- Erros na última hora
fields @timestamp, @message, error
| filter level = "ERROR"
| sort @timestamp desc
| limit 100
-- Requests lentos (> 1s)
fields @timestamp, user_id, duration
| filter duration > 1000
| stats avg(duration), max(duration), count() by bin(1m)
-- Requests por usuário
fields user_id
| stats count() by user_id
| sort count() desc
Correlation IDs
Para rastrear requests através de múltiplos serviços:
import uuid
from contextvars import ContextVar
correlation_id_var: ContextVar[str] = ContextVar('correlation_id')
# Middleware FastAPI
@app.middleware("http")
async def add_correlation_id(request: Request, call_next):
correlation_id = request.headers.get('X-Correlation-ID') or str(uuid.uuid4())
correlation_id_var.set(correlation_id)
response = await call_next(request)
response.headers['X-Correlation-ID'] = correlation_id
return response
# Logger com correlation ID
def get_logger():
correlation_id = correlation_id_var.get(None)
return logger.bind(correlation_id=correlation_id)
Métricas
Lambda Metrics
AWS Managed:
- Invocations - Número de invocações
- Errors - Número de erros
- Duration - Duração (ms)
- Throttles - Throttling events
- ConcurrentExecutions - Execuções simultâneas
- IteratorAge - Idade do batch (SQS/Kinesis)
Custom Metrics:
import boto3
cloudwatch = boto3.client('cloudwatch')
def publish_metric(metric_name: str, value: float, unit: str = 'Count'):
"""Publish custom metric to CloudWatch."""
cloudwatch.put_metric_data(
Namespace='MyApp',
MetricData=[{
'MetricName': metric_name,
'Value': value,
'Unit': unit,
'Timestamp': datetime.utcnow()
}]
)
# Usage
publish_metric('UserSignups', 1, 'Count')
publish_metric('PaymentAmount', 99.99, 'None')
publish_metric('APILatency', 250, 'Milliseconds')
SQS Metrics
NumberOfMessagesSentNumberOfMessagesReceivedApproximateAgeOfOldestMessage- Importantíssimo!ApproximateNumberOfMessagesVisible
RDS Metrics
DatabaseConnectionsCPUUtilizationFreeableMemoryReadLatency/WriteLatencyFreeStorageSpace
Dashboards
Dashboard Principal
Widgets:
- API Health
- Request count (last hour)
- Error rate
-
Average latency (p50, p90, p99)
-
Lambda Performance
- Invocations por função
- Duration metrics
- Error count
-
Throttles
-
Queue Health
- Messages in queue
- Age of oldest message
-
DLQ messages
-
Database
- Connections
- CPU usage
-
Disk space
-
Business Metrics
- User signups (today)
- Orders created (today)
- Revenue (today)
Criar Dashboard
# Via AWS CLI
aws cloudwatch put-dashboard \
--dashboard-name "App-Production" \
--dashboard-body file://dashboard.json