External Log Collectors

Sending Logs to an External Collector

Once there are several hosts, or a container is removed with its log, you need every line in a central store. Fluent Bit 83,977 (github.com/fluent/fluent-bit (https://github.com/fluent/fluent-bit 8,125 ), Apache-2.0, a CNCF graduated project) is a small collector written in C that accepts the Fluentd 175,921 forward protocol, which Docker 514 's fluentd driver speaks. Give it a pipeline from forward input to standard output, and point a container at it:

A container's lines arriving at Fluent Bit, and what happens when it is downShell
printf '%s\n' 'pipeline:' '  inputs: [{name: forward, listen: 0.0.0.0, port: 24224}]' \
  '  outputs: [{name: stdout, match: "*", format: json_lines}]' > fluent-bit.yaml
docker run -d --name l3-fluentbit -p 127.0.0.1:33224:24224 \
  -v "$PWD/fluent-bit.yaml:/fb.yaml:ro" fluent/fluent-bit:5.1.2 -c /fb.yaml >/dev/null
FD="--log-driver fluentd --log-opt fluentd-address=127.0.0.1:33224"
docker run --name l3-lg $FD alpine:3 sh -c 'echo GET /api/books 200; echo oops >&2' &>/dev/null
sleep 2; docker logs l3-fluentbit 2>&1 | grep '"log"' | jq -c '{log, source, container_name}'
docker logs l3-lg; docker rm l3-lg >/dev/null
docker stop l3-fluentbit >/dev/null
docker run --rm $FD alpine:3 echo hi 2>&1 | head -1 | cut -c 1-90
docker run --rm $FD --log-opt fluentd-async=true alpine:3 echo hi; echo "exit=$?"
docker rm l3-fluentbit >/dev/null
Output
{"log":"GET /api/books 200","source":"stdout","container_name":"/l3-lg"}
{"log":"oops","source":"stderr","container_name":"/l3-lg"}
GET /api/books 200
oops
docker: Error response from daemon: failed to create task for container: failed to initial
hi
exit=0

Each record carries the line, its stream and the container's name and ID, ready for a search index, and docker logs still works from the dual-logging cache (Logging Drivers). The last two runs show the trap: with the collector down, a container using the fluentd driver refuses to start, because the driver connects at startup. fluentd-async=true buffers and retries in the background instead, and mode=non-blocking with max-buffer-size (1 MB by default) drops lines rather than stall an application whose collector is slow. The other common pattern keeps the local driver and runs the collector as a container that tails the log files, as Kubernetes 5,150 clusters do.

Log collectors and stores, open source and commercial
Tool License Role Cost
Fluent Bit, OpenTelemetry 36,171 Collector Apache-2.0 Collect, filter, forward Free
Vector MPL-2.0 Collect, transform, forward Free
Grafana Loki 2,264 AGPL-3.0 Log store and query Free self-hosted; cloud paid
Datadog 381 , Splunk 5,555 Proprietary Hosted pipeline and search Paid per GB or host