How to View and Configure Amazon ECS Logs
Last verified on Nov 8, 2026.
Amazon ECS containers write to stdout and stderr, and the log driver in each container definition decides where that output goes. The awslogs driver sends it to CloudWatch Logs with no extra containers. FireLens adds a Fluent Bit or Fluentd router when you need to filter, enrich, or send logs elsewhere. This guide covers both, how to find one task's output, and why logs go missing.
Choosing a Log Driver
Start with awslogs unless you need something it cannot do. It has the fewest moving parts, and the console Logs tab reads from it directly.
Configuring the awslogs Driver
Add a logConfiguration block to each container definition. On Fargate this is required to get logs at all. On EC2 you need container agent 1.9.0 or later, and the instance or task execution role needs logs:CreateLogStream and logs:PutLogEvents.
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/checkout",
"awslogs-region": "us-west-2",
"awslogs-stream-prefix": "api"
}
}What each option does:
awslogs-groupis the destination group. It must exist in the Region you name, unless you let ECS create it.awslogs-create-groupdefaults tofalse. Setting it totruerequireslogs:CreateLogGroupin your IAM policy.awslogs-regionis the Region that receives the logs. You can send several Regions' logs to one place.awslogs-stream-prefixproduces stream names of the formprefix/container-name/task-id. Without it the stream is named after the Docker container ID, which is hard to trace back. You need a prefix for the logs to appear in the ECS console.awslogs-datetime-formatorawslogs-multiline-patternjoins stack traces into one event by defining what starts a new message. You cannot set both, and multiline matching can slow logging.
A task definition does not set retention. Set it on the log group afterward with aws logs put-retention-policy.
Blocking vs Non-Blocking Delivery
The mode option controls what happens when logs cannot be delivered. In blocking mode, writes to stdout and stderr block, so the application can stall and fail health checks. In non-blocking mode, logs go to an in-memory buffer sized by max-buffer-size, which defaults to 10m. When the buffer fills, further logs are lost.
On June 25, 2025, ECS changed the default from blocking to non-blocking. Containers that rely on never losing a line should set "mode": "blocking" explicitly, or set the defaultLogDriverMode account setting.
Finding a Task's Logs
Each task writes to its own stream, one per container, following prefix/container-name/task-id. A task keeps the same stream for its whole lifetime, and a service that scales out gets a new set per task.
In the console, open Clusters, choose the cluster, then either choose a service and its Logs tab or the Tasks tab, a task, and its Logs tab. CloudWatch Logs Live Tail streams new events there. It needs logs:DescribeLogGroups, logs:StartLiveTail, and logs:StopLiveTail, and bills by session minute.
From a terminal:
# Find task IDs for a service
aws ecs list-tasks --cluster prod --service-name checkout
# Follow everything the service's containers write under the prefix
aws logs tail /ecs/checkout --follow --log-stream-name-prefix api
# One task, last 30 minutes, errors only
aws logs tail /ecs/checkout --since 30m \
--log-stream-name-prefix api/web/0123456789abcdef0123456789abcdef \
--filter-pattern ERRORThe last segment of a stream name is the task ID, which is the final part of the task ARN. For aggregate questions, CloudWatch Logs Insights can query the group, and @logStream separates tasks.
Routing Logs with FireLens
FireLens runs a log router as a sidecar in the task. You define one container with a firelensConfiguration, mark it essential, and give every application container the awsfirelens driver. ECS generates the router's output configuration from your options and mounts it at /fluent-bit/etc/fluent-bit.conf for Fluent Bit or /fluentd/etc/fluent.conf for Fluentd.
{
"containerDefinitions": [
{
"name": "log_router",
"image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:3",
"essential": true,
"firelensConfiguration": { "type": "fluentbit" },
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/firelens-router",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "firelens"
}
}
},
{
"name": "app",
"image": "public.ecr.aws/docker/library/httpd:latest",
"essential": true,
"logConfiguration": {
"logDriver": "awsfirelens",
"options": {
"Name": "firehose",
"region": "us-west-2",
"delivery_stream": "my-stream"
}
}
}
]
}Things to know before you ship it:
- The task needs a task IAM role with permission to call the destination, such as
firehose:PutRecordBatch. On Fargate you also need the task execution role for ECR image pulls or Secrets Manager references. - FireLens listens on port
24224. Do not allow inbound traffic to that port in the task's security group. - By default ECS adds
ecs_cluster,ecs_task_arn,ecs_task_definition, and, on EC2,ec2_instance_idto each record. Setenable-ecs-log-metadatatofalseto remove them. - Send the router's own logs somewhere with
awslogs, as above, so you can debug the router. - For custom filters, set
config-file-typeandconfig-file-valueinfirelensConfiguration. Use a path other than the reserved/fluent-bit/etc/fluent-bit.conf. Fargate supports only thefiletype.
When ECS Logs Are Missing
- Wrong Region.
awslogs-regionmust match the group's Region. - Group missing. Create it, or set
awslogs-create-grouptotrueand grantlogs:CreateLogGroup. - Permissions. The role that ECS uses needs
logs:CreateLogStreamandlogs:PutLogEvents. TheecsTaskExecutionRolenormally has them. - No stream prefix. Logs exist but the console Logs tab shows nothing.
- Application writes to a file. The driver captures only stdout and stderr.
- Dropped in non-blocking mode. A full
max-buffer-sizebuffer discards lines. Raise it or switch modes.
Searching ECS Logs with Sazabi
Sazabi, an AI-native observability and security platform, offers two routes. For awslogs, connect CloudWatch under Settings > Log streams > Add source > CloudWatch, then add your /ecs/... groups with Add log stream. Sazabi installs a subscription filter on each group, and only groups in your project's region appear. See the CloudWatch source docs and the CloudWatch integration.
For FireLens, Sazabi's Fluent Bit docs describe an opentelemetry output that works with any Fluent Bit v2.0 or later. You can add that output through a FireLens custom configuration file. See the Fluent Bit integration for the setup.
Frequently Asked Questions
Where do Amazon ECS container logs go?
With the awslogs driver, to the CloudWatch Logs log group named in the container logConfiguration, one log stream per container per task. With FireLens they go wherever the Fluent Bit or Fluentd output sends them.
Why are my ECS task logs not showing in CloudWatch?
Common causes are a missing log group when awslogs-create-group is false, a Region in awslogs-region that does not match the group, a task execution role without logs:CreateLogStream and logs:PutLogEvents, or no awslogs-stream-prefix, which hides the logs from the console Logs tab.
How do I tail ECS logs from the command line?
Run aws logs tail with the log group name, --follow, and optionally --log-stream-name-prefix set to your stream prefix. The group and prefix come from the task definition awslogs options.
What is the difference between awslogs and FireLens?
awslogs sends container stdout and stderr to CloudWatch Logs with no extra containers. FireLens adds a Fluent Bit or Fluentd sidecar that can filter, enrich, and route logs to CloudWatch, Firehose, Kinesis, or a partner destination.
Sources
- The awslogs driver passes STDOUT and STDERR to CloudWatch Logs, Fargate needs logConfiguration, and EC2 needs agent 1.9.0, logs:CreateLogStream, and logs:PutLogEvents (accessed Nov 8, 2026)
- awslogs options (group, region, stream prefix, create-group, datetime, and multiline), the stream name format, blocking and non-blocking mode, the June 25, 2025 default change and max-buffer-size default of 10m (accessed Nov 8, 2026)
- Example task definition logConfiguration for the awslogs driver and optional put-retention-policy on the log group (accessed Nov 8, 2026)
- Console Logs tab for tasks and services, per-container log streams, Live Tail permissions, and per-minute Live Tail cost (accessed Nov 8, 2026)
- FireLens works with Fluentd and Fluent Bit, runs on Fargate and EC2 Linux but not Windows, listens on port 24224, and adds ECS metadata fields by default (accessed Nov 8, 2026)
- FireLens task definition with a log router container and awsfirelens log driver, generated output config paths, and custom configuration file options (accessed Nov 8, 2026)
- aws logs tail with --follow, --since, and --log-stream-name-prefix (accessed Nov 8, 2026)
- Sazabi accepts logs from any Fluent Bit deployment over the opentelemetry output plugin in Fluent Bit v2.0 or later (accessed Nov 8, 2026)
- Connecting CloudWatch log groups to Sazabi via subscription filters (accessed Nov 8, 2026)