ECS Logs


https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_firelens.html
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/firelens-taskdef.html
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html
https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html
https://docs.victoriametrics.com/victorialogs/data-ingestion/fluentbit/
https://docs.victoriametrics.com/victorialogs/data-ingestion/
https://docs.victoriametrics.com/victorialogs/querying/

1. Important Points#

ECS 日志进 VictoriaLogs,优先推荐 FireLens / Fluent Bit 直连 VictoriaLogs。

best option:
    app stdout/stderr -> FireLens -> VictoriaLogs

transition option:
    awslogs -> CloudWatch Logs -> subscription -> VictoriaLogs

legacy EC2 host logs:
    CloudWatch Agent -> CloudWatch Logs -> subscription -> VictoriaLogs
why FireLens first:
    路径短
    延迟低
    少一层 CloudWatch Logs ingestion cost
    和 ECS task definition 直接集成

2. Ingestion Model#

VictoriaLogs 官方支持 JSON line / ndjson ingestion,也支持 Fluent Bit collector。

VictoriaLogs endpoint:
    /insert/jsonline

recommended stream fields:
    service
    env
    cluster
    task_definition
    container

verify VictoriaLogs#

curl -s https://victorialogs.example.com/health

insert one JSON line#

printf '{"log":{"level":"info","message":"hello from ecs"},"stream":"order-api","date":"0"}\n' \
  | curl -sS \
      --cacert /etc/ssl/company-ca.pem \
      -u logs-ingest:change-me \
      -H 'content-type: application/stream+json' \
      --data-binary @- \
      'https://victorialogs.example.com/insert/jsonline?_stream_fields=stream&_time_field=date&_msg_field=log.message'

query#

curl --cacert /etc/ssl/company-ca.pem \
  -u logs-reader:change-me \
  -G 'https://victorialogs.example.com/select/logsql/query' \
  --data-urlencode 'query=service:order-api'

3. FireLens Direct#

when to use#

use when:
    new ECS service
    logs already go to stdout/stderr
    you want direct delivery to VictoriaLogs
    you want to reduce CloudWatch Logs dependence

Fluent Bit output#

VictoriaLogs 的 Fluent Bit 目标通常就是 HTTP JSON line。

[Output]
    Name http
    Match *
    Host victorialogs.example.com
    Port 443
    URI /insert/jsonline?_stream_fields=service,env,cluster,task_definition,container&_msg_field=log.message&_time_field=date
    Format json_lines
    json_date_format iso8601
    tls On
    tls.verify On
    Header Authorization Basic <base64(username:password)>
notes:
    如果前面有 vmauth,就把 Host 指向 vmauth 的入口
    ECS metadata 建议通过 record_transformer / modify filter 写进字段
    _stream_fields 要稳定,不要把 request_id 之类高基数字段放进去

ECS task definition sketch#

{
  "family": "order-api",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecs-task-execution-role",
  "containerDefinitions": [
    {
      "name": "log_router",
      "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
      "essential": true,
      "firelensConfiguration": { "type": "fluentbit" }
    },
    {
      "name": "app",
      "image": "123456789012.dkr.ecr.ap-east-1.amazonaws.com/order-api:2026-06-02",
      "essential": true,
      "logConfiguration": {
        "logDriver": "awsfirelens",
        "options": {
          "Name": "http",
          "Host": "victorialogs.example.com",
          "Port": "443",
          "URI": "/insert/jsonline?_stream_fields=service,env,cluster,task_definition,container&_msg_field=log.message&_time_field=date",
          "Format": "json_lines"
        }
      }
    }
  ]
}

4. CloudWatch Bridge#

如果你现在已经全量在用 awslogs,可以先不动 ECS task definition,而是走 CloudWatch Logs bridge。

flow:
    ECS app logs -> CloudWatch Logs -> subscription filter -> Lambda / processor -> VictoriaLogs

good for:
    migration
    compliance path that needs CloudWatch copy
    teams that cannot touch task definition immediately
tradeoff:
    extra CloudWatch cost
    extra latency
    more moving parts than FireLens

5. Operational Checklist#

1. app logs contain stable fields like service / env / cluster
2. FireLens or awslogs bridge selected intentionally
3. VictoriaLogs ingestion endpoint protected by auth
4. UI path /select/vmui/ protected by the same auth layer
5. query and ingest paths are validated separately
6. high-cardinality fields are not used as stream keys
7. retention and backup policy are defined