Michael Follmann
12/03/2025, 6:43 PMMarvin
12/03/2025, 6:43 PMMarvin
12/03/2025, 6:49 PM/etc/prefect/logging.yml) in the worker image:
version: 1
disable_existing_loggers: false
formatters:
json:
(): prefect.logging.formatters.JsonFormatter
# "default" is compact; "pretty" adds indentation
format: "default"
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: json
stream: <ext://sys.stdout>
# Optional: still send logs to Prefect API
api:
class: prefect.logging.handlers.APILogHandler
level: INFO
# Worker-specific API handler
worker_api:
class: prefect.logging.handlers.WorkerAPILogHandler
level: INFO
loggers:
# Worker logs (what you asked about)
prefect.workers:
level: INFO
handlers: [console, worker_api] # drop worker_api if you do NOT want logs in Prefect
propagate: false
# Core Prefect logs
prefect:
level: INFO
handlers: [console]
propagate: false
root:
level: INFO
handlers: [console]
Notes
- This uses Prefect’s built-in JsonFormatter so each log line is a JSON object (includes fields like severity, flow_run_id, task_run_id, etc. when applicable).
- If you do not want any logs sent to Prefect’s API, remove `worker_api`/`api` handlers and/or set the env var noted below.
2) Point Prefect at that config and disable color/markup
Add these environment variables to your ECS worker task definition:
PREFECT_LOGGING_SETTINGS_PATH=/etc/prefect/logging.yml
PREFECT_LOGGING_COLORS=false
PREFECT_LOGGING_MARKUP=false
# Optional: if you do NOT want logs in Prefect’s API as well
# PREFECT_LOGGING_TO_API_ENABLED=false
3) Ensure ECS sends stdout/stderr to Datadog
- If you use CloudWatch Logs: use the awslogs driver and Datadog’s CloudWatch log forwarder.
- If you use FireLens/Fluent Bit (recommended for direct ingest): configure the worker container with awsfirelens and a log router sidecar.
Example (FireLens to Datadog) snippet in the worker task definition:
{
"containerDefinitions": [
{
"name": "prefect-worker",
"image": "prefecthq/prefect:3-latest",
"essential": true,
"command": [
"prefect",
"worker",
"start",
"--pool",
"my-ecs-pool"
],
"environment": [
{
"name": "PREFECT_LOGGING_SETTINGS_PATH",
"value": "/etc/prefect/logging.yml"
},
{
"name": "PREFECT_LOGGING_COLORS",
"value": "false"
},
{
"name": "PREFECT_LOGGING_MARKUP",
"value": "false"
}
],
"logConfiguration": {
"logDriver": "awsfirelens",
"options": {
"Name": "datadog",
"apikey": "<DATADOG_API_KEY>",
"provider": "ecs",
"service": "prefect-worker",
"env": "prod"
}
},
"mountPoints": [
{
"sourceVolume": "prefect-config",
"containerPath": "/etc/prefect"
}
]
},
{
"name": "log-router",
"image": "amazon/aws-for-fluent-bit:latest",
"essential": true,
"firelensConfiguration": {
"type": "fluentbit"
}
}
],
"volumes": [
{
"name": "prefect-config",
"host": {
"sourcePath": "/path/on/host/with/logging.yml"
}
}
]
}
Practical tips
- Put the logging.yml in your worker image (or mount it as a volume) and set PREFECT_LOGGING_SETTINGS_PATH to that location.
- The same approach works for flow-run containers too. If you also want structured logs from your flows, include the same file and env var in the image used by your deployments.
- Keep colors=false and markup=false to avoid escape codes that would break JSON parsing.
- Datadog will automatically parse the JSON and surface your custom attributes (e.g., flow_run_id, task_run_id, etc.) for filtering and dashboards.
ReferencesMarvin
12/03/2025, 6:49 PMlogging.yml and task definition patch based on your current ECS task JSON and how you’re sending logs to Datadog (CloudWatch forwarder vs FireLens)?