Reassemble multiline Docker logs in Fluentd

Use concat with an explicit event boundary, container-and-stream isolation, timeout routing, and deliberate timestamp behavior.

Best practices
Illustration of server operations and log analysis

Docker's Fluentd driver forwards application log records; it does not automatically reconstruct an exception stack into one application event. A Fluentd concat filter can group records, but its boundary rule, stream identity, separator, and timeout handling must match the actual input.

Configure concat and timeout output

Install a compatible fluent-plugin-concat version in the Fluentd image. With a separate tag per container, a diagnostic configuration can use:

<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>

<filter docker.**>
  @type concat
  key log
  stream_identity_key source
  multiline_start_regexp /^\d{4}-\d{2}-\d{2}/
  separator "\n"
  flush_interval 5
  use_first_timestamp true
  timeout_label @MULTILINE_TIMEOUT
</filter>

<match docker.**>
  @type stdout
</match>

<label @MULTILINE_TIMEOUT>
  <match docker.**>
    @type stdout
  </match>
</label>

The example assumes each new application event starts with a date and individual log values need a newline inserted between them. Inspect the driver output first: an empty separator is suitable only if the records already contain the intended delimiters. Date detection is a boundary heuristic, not timestamp parsing.

The plugin groups by tag plus the selected identity field. A container-specific tag separates containers; source separates stdout from stderr. It still cannot disentangle interleaved threads writing multiline messages to the same stream. Prefer structured single-line events for that case.

use_first_timestamp true deliberately selects the first event's timestamp; it is not the plugin's default. timeout_label routes a final incomplete group after inactivity to an output instead of leaving timeout events to an unspecified error path. Replace both stdout outputs with the intended production destination.

Point the Docker daemon at Fluentd

For a Linux Docker host with Fluentd published on the host's loopback TCP port:

docker run --log-driver=fluentd \
  --log-opt fluentd-address=127.0.0.1:24224 \
  --log-opt 'tag=docker.{{.FullID}}' \
  myapp:approved

Use the actual application image. The logging driver connects from the Docker daemon's network context. A Compose service name such as fluentd is not automatically resolvable there. For a remote daemon or Docker Desktop, choose an endpoint reachable from that daemon.

Ensure Fluentd is ready before starting the application. The driver's synchronous connection behavior can prevent startup when the destination is unavailable; asynchronous options and buffers change failure behavior and need an explicit loss/backpressure policy.

FAQ

Can indentation define continuation lines?

A start expression such as /^\S/ treats non-indented lines as new events. Test real stack formats: exception causes and other continuation lines may also begin without whitespace.

Does the five-second interval guarantee a complete stack?

No. A pause longer than the interval can split an event, while too long an interval delays output. Test quiet final events and shutdown behavior as well as back-to-back stacks.

Is single-line JSON better?

When feasible, emit each event as one JSON record with escaped newlines inside the stack field. Runtime partial-record splitting and maximum event sizes still need separate handling; application multiline reconstruction and partial-message reconstruction are different tasks.

References: Docker Fluentd driver, concat plugin configuration.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting