Enable tracing

Quarkus Flow provides a logging-only execution tracer. It emits human-readable log lines and attaches structured fields via MDC so you can search and graph them in tools like Kibana or Datadog. This tracer is independent of Messaging/CloudEvents.

This guide shows how to:

  • enable the Flow tracer

  • expose MDC fields via JSON or pattern logging

  • understand the MDC keys emitted for each event

  • relate tracing to Messaging

Prerequisites

  • A Quarkus application with Quarkus Flow set up.

  • Basic familiarity with Quarkus logging configuration (JSON vs pattern, log categories).

1. Enable tracing

Add to application.properties:

# Production (explicit ON)
quarkus.flow.tracing.enabled=true

1.1 Defaults per profile

Tracing is enabled by default in dev and test modes, and disabled by default in prod.

Dev/Test (default ON):

# implicit default (no config needed)
# %dev.quarkus.flow.tracing.enabled=true
# %test.quarkus.flow.tracing.enabled=true

# you can explicitly turn it off:
%dev.quarkus.flow.tracing.enabled=false
%test.quarkus.flow.tracing.enabled=false

Prod (default OFF):

# enable tracing explicitly
quarkus.flow.tracing.enabled=true

2. Structured logging and MDC

To make fields queryable, enable JSON console logging and include MDC. Example for the test profile:

%test.quarkus.flow.tracing.enabled=true

# Enable JSON console logging (disabled by default)
%test.quarkus.log.console.json.enabled=true

# Optional: when using *pattern* (non-JSON) logging, you can surface MDC values
# in the format string (ignored when JSON logging is enabled):
%test.quarkus.log.console.format=%d{HH:mm:ss} %-5p quarkus.flow.instanceId=%X{quarkus.flow.instanceId} quarkus.flow.event=%X{quarkus.flow.event} [%c{2.}] (%t) %s%n
Quarkus logging options evolve; see the official guide for the most up-to-date knobs: Quarkus Logging guide.

2.1 MDC keys emitted by the tracing listener

Key Example Description

quarkus.flow.instanceId

01K9GDCXJVN89V0N4CWVG40R7C

Workflow instance ID.

quarkus.flow.event

workflow.started, workflow.completed, task.started, task.completed, task.failed, …

Normalized lifecycle event name.

quarkus.flow.time

2025-11-07T19:20:59.120084-05:00

Event timestamp (same as the event’s eventDate()).

quarkus.flow.task

sayHelloWorld

Task name (task events only).

quarkus.flow.taskPos

do/0/sayHelloWorld

JSON pointer to the task position in the workflow definition (task events only).

MDC fields become first-class, searchable fields only when quarkus.log.console.json.enabled=true and JSON logging includes MDC by default (Quarkus JSON encoder).

With pattern logging you must reference %X{key} in quarkus.log.console.format. See Quarkus Logging guide.

3. Example output (test profile)

When JSON console logging is enabled, logs resemble:

{"timestamp":"2025-11-07T19:20:59.096591-05:00","loggerName":"io.quarkiverse.flow.recorders.WorkflowApplicationRecorder","level":"INFO","message":"Flow: Tracing enabled","mdc":{}}
{"timestamp":"2025-11-07T19:20:59.117491-05:00","loggerName":"io.quarkiverse.flow.tracing.TraceLoggerExecutionListener","level":"INFO","message":"Workflow id=01K9GDCXJVN89V0N4CWVG40R7C started at 2025-11-07T19:20:59.106716-05:00 input={}","mdc":{"quarkus.flow.event":"workflow.started","quarkus.flow.time":"2025-11-07T19:20:59.106716-05:00","quarkus.flow.instanceId":"01K9GDCXJVN89V0N4CWVG40R7C"}}
{"timestamp":"2025-11-07T19:20:59.118746-05:00","loggerName":"io.quarkiverse.flow.tracing.TraceLoggerExecutionListener","level":"INFO","message":"Task 'sayHelloWorld' started at 2025-11-07T19:20:59.118675-05:00 pos=do/0/sayHelloWorld","mdc":{"quarkus.flow.event":"task.started","quarkus.flow.time":"2025-11-07T19:20:59.118675-05:00","quarkus.flow.task":"sayHelloWorld","quarkus.flow.taskPos":"do/0/sayHelloWorld","quarkus.flow.instanceId":"01K9GDCXJVN89V0N4CWVG40R7C"}}
{"timestamp":"2025-11-07T19:20:59.120407-05:00","loggerName":"io.quarkiverse.flow.tracing.TraceLoggerExecutionListener","level":"INFO","message":"Task 'sayHelloWorld' completed at 2025-11-07T19:20:59.120084-05:00 output={\"message\":\"hello world!\"}","mdc":{"quarkus.flow.event":"task.completed","quarkus.flow.time":"2025-11-07T19:20:59.120084-05:00","quarkus.flow.task":"sayHelloWorld","quarkus.flow.taskPos":"do/0/sayHelloWorld","quarkus.flow.instanceId":"01K9GDCXJVN89V0N4CWVG40R7C"}}
{"timestamp":"2025-11-07T19:20:59.120991-05:00","loggerName":"io.quarkiverse.flow.tracing.TraceLoggerExecutionListener","level":"INFO","message":"Workflow id=01K9GDCXJVN89V0N4CWVG40R7C completed at 2025-11-07T19:20:59.120947-05:00","mdc":{"quarkus.flow.event":"workflow.completed","quarkus.flow.time":"2025-11-07T19:20:59.120947-05:00","quarkus.flow.instanceId":"01K9GDCXJVN89V0N4CWVG40R7C"}}

These records give you:

  • a linear view of workflow and task lifecycle

  • a stable instanceId you can filter on

  • a taskPos pointer you can map back to the workflow definition

4. Relation to Messaging

The tracing listener is independent from Messaging lifecycle publishing. You can enable either or both:

  • Tracing — emits log entries with MDC (good for log-based observability).

  • Messaging lifecycle stream — emits CloudEvents on a channel (good for external monitoring systems and event-driven dashboards).

For CloudEvents-based lifecycle monitoring, see Use messaging and events.

See also