The app writes logs to stdout and stderr, and AWS ships them to CloudWatch Logs.
- On ECS, the
awslogslog driver or FireLens sends them to a CloudWatch Logs log group. - Lambda sends its output to a log group automatically.
- Each container or execution environment writes to its own log stream inside the group.
Use structured JSON logs, because you can filter and aggregate them reliably. Give each line fields like level, message, requestId, userId, durationMs and a trace ID. Then:
- CloudWatch Logs Insights can query JSON fields directly. For example, it can find slow requests by route.
- Metric filters can turn matching log lines into metrics.
With free-text logs, you must search with regex, and regex searches break easily.
Good practice:
- Use a logger like pino.
- Add a correlation ID to each request, so you can follow one request through all its logs.
- Never log secrets or personal data.
- Set a retention period on each log group, because by default CloudWatch keeps logs forever.
- The app logs to stdout; on ECS the awslogs driver or FireLens ships the logs, and Lambda does it automatically.
- Logs go into log groups, and each container or environment has its own log stream.
- JSON fields can be queried in Logs Insights and used in metric filters.
- Include request and trace IDs, and never log secrets.
- Set a retention period, because by default logs never expire.