3.2.1.3. Real-time Log Ingestion
3.2.1.3. Real-time Log Ingestion
Log ingestion must happen in real-time for operational visibility. A 30-minute delay in log delivery means you're debugging issues that happened 30 minutes ago.
CloudWatch Logs ingestion paths:
| Source | Ingestion Method | Latency |
|---|---|---|
| EC2 instances | CloudWatch Agent | Seconds |
| Lambda functions | Automatic (stdout/stderr) | Seconds |
| ECS/Fargate | awslogs log driver | Seconds |
| API Gateway | Enable access logging per stage | Seconds |
| VPC Flow Logs | Direct to CloudWatch Logs or S3 | Minutes |
| CloudTrail | Trail → CloudWatch Logs log group | Minutes |
| Custom applications | CloudWatch Logs SDK/CLI (PutLogEvents) | Seconds |
CloudWatch Agent configuration:
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/application/*.log",
"log_group_name": "/app/production",
"log_stream_name": "{instance_id}",
"retention_in_days": 30
}
]
}
}
}
}
Agent log collection: one CloudWatch Agent process collects both metrics and logs, and it collects a log file only when the config's logs section has a file_path that matches the real file. The agent runs as root by default; if run_as_user names a non-root user such as cwagent, that user needs read permission on each file — otherwise metrics keep arriving while those logs never do.
Log group organization: Use a consistent naming convention: /<environment>/<application>/<component> (e.g., /prod/order-service/api). This enables IAM policies that grant access by environment or application using wildcard patterns.
Exam Trap: Lambda function logs go to a log group named /aws/lambda/<function-name> automatically — but the Lambda execution role must have logs:CreateLogGroup, logs:CreateLogStream, and logs:PutLogEvents permissions. If Lambda logs are missing, the execution role is the first place to check.
Structured logs: Logs Insights auto-discovers fields only in log events that are valid JSON. Plain print() text shows up in @message, but its "fields" can't be queried without parse; emit each line as a JSON object (e.g., Powertools for AWS Lambda Logger or json.dumps) to query fields such as responseTime directly.