Send logs from AWS ECS Fargate using Fluent Bit FireLens Sidecar
You must be using Fluent Bit 3.x or newer.
Values needed for configuration
| SolarWinds Observability SaaSfield | Source on AWS ECS Fargate | How to convert to environmental variable |
|---|---|---|
host.name = ECS service name |
Not auto-injected by ECS | Set explicitly in the task definition's environment block per service |
service.name = ECS task ID |
Part of ECS_CONTAINER_METADATA_URI_V4 |
Parse with a 2-line shell entrypoint |
Step 1: Custom Fluent Bit sidecar image (Dockerfile)
FROM amazon/aws-for-fluent-bit:3.3.2 COPY entrypoint.sh /entrypoint.sh COPY extra.conf /fluent-bit/etc/extra.conf RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh derives the task ID from the metadata URI using POSIX shell parameter expansion, then hands off to Fluent Bit:
#!/bin/sh
# ECS_CONTAINER_METADATA_URI_V4 is always set on Fargate platform 1.4+:
# http://169.254.170.2/v4/<taskId>-<containerId>
# Take the path tail (last '/' segment) and strip the container suffix after the first '-'.
last_segment="${ECS_CONTAINER_METADATA_URI_V4##*/}"
SWO_TASK_ID="${last_segment%%-*}"
export SWO_TASK_ID
exec /fluent-bit/bin/fluent-bit \
-e /fluent-bit/firehose.so \
-e /fluent-bit/cloudwatch.so \
-e /fluent-bit/kinesis.so \
-c /fluent-bit/etc/fluent-bit.conf
Step 2: Fluent Bit override config (extra.config)
This is the file FireLens layers on top of its auto-generated base config:
[OUTPUT]
Name http
Match *
Host ${SWO_LOGS_HOST}
Port 443
URI /v1/logs/bulk
tls on
tls.verify on
Format json_lines
json_date_key timestamp
json_date_format iso8601
allow_duplicated_headers false
Header Authorization Bearer ${SWO_INGESTION_TOKEN}
Header Content-Type application/octet-stream
Header X-Otel-Resource-Attr host.name=${SWO_HOST_NAME}, service.name=${SWO_TASK_ID}
Retry_Limit 5
Set SWO_LOGS_HOST per DC: logs.collector.na-01.cloud.solarwinds.com, swap the na-01 prefix to match (na-02, eu-01, ap-01).
Step 3: ECS task definition
{
"family": "checkout-api",
"requiresCompatibilities": ["FARGATE"],
"containerDefinitions": [
{
"name": "app",
"image": "123456789012.dkr.ecr.us-east-2.amazonaws.com/checkout-api:latest",
"essential": true,
"logConfiguration": {
"logDriver": "awsfirelens"
}
},
{
"name": "log_router",
"image": "123456789012.dkr.ecr.us-east-2.amazonaws.com/swo-fluent-bit:latest",
"essential": true,
"firelensConfiguration": {
"type": "fluentbit",
"options": {
"enable-ecs-log-metadata": "true",
"config-file-type": "file",
"config-file-value": "/fluent-bit/etc/extra.conf"
}
},
"environment": [
{ "name": "SWO_HOST_NAME", "value": "checkout-api" },
{ "name": "SWO_LOGS_HOST", "value": "logs.collector.na-01.cloud.solarwinds.com" }
],
"secrets": [
{
"name": "SWO_INGESTION_TOKEN",
"valueFrom": "arn:aws:secretsmanager:us-east-2:123456789012:secret:swo/ingestion-token-XXXXXX"
}
],
"memoryReservation": 64
}
]
}
Please note the following:
-
SWO_HOST_NAMEis set to the ECS service name (checkout-api). You will need to set this per task definition. -
SWO_TASK_IDis not in this JSON. The entrypoint computes it fromECS_CONTAINER_METADATA_URI_V4at container start, which ECS always sets on Fargate. -
SWO_INGESTION_TOKENis fed in via Secrets Manager. Don't inline the token in plain task-definition JSON in production.
Behavior in SolarWinds Observability SaaS
After the task starts, every log from the app container will land with the following:
-
System (Host) =
checkout-api(your ECS service name) -
program = the task ID (e.g.,
a1b2c3d4e5f64789abcd1234567890ef)
This is searchable as
host:checkout-api program:a1b2c3d4e5f64789abcd1234567890ef
Adding the record_modifier filter before OUTPUT will back ECS cluster, container name, and stream into each line:
[FILTER]
Name record_modifier
Match *
Record ecs_cluster ${ECS_CLUSTER}
Record ecs_service_name ${SWO_HOST_NAME}
Record ecs_task_id ${SWO_TASK_ID}
ecs_cluster, ecs_task_arn, ecs_task_definition, container_name, container_id, and source are already added automatically because enable-ecs-log-metadata: true is on.
The scripts are not supported under any SolarWinds support program or service. The scripts are provided AS IS without warranty of any kind. SolarWinds further disclaims all warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The risk arising out of the use or performance of the scripts and documentation stays with you. In no event shall SolarWinds or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the scripts or documentation.