Reassemble multiline Docker logs in Fluentd
Use concat with an explicit event boundary, container-and-stream isolation, timeout routing, and deliberate timestamp behavior.
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.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan