← Back to DevBytes

Fluentd Log Collector: Complete Implementation Guide

Understanding Fluentd and the Unified Logging Layer

What is Fluentd?

Fluentd is an open-source data collector designed to unify the process of log collection, aggregation, and forwarding. It treats logs as a structured data stream, enabling you to collect events from various sources, filter and transform them in-flight, and deliver them to multiple destinations simultaneously. Built in Ruby with a pluggable architecture, Fluentd supports over 500 plugins, making it highly extensible.

Why Fluentd Matters for Modern Applications

In distributed systems, logs are scattered across hundreds of microservices, containers, and cloud environments. Without a centralized collector, debugging and monitoring become impossible. Fluentd solves this by:

Core Concepts and Architecture

🚀 Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

Events and the Fluentd Pipeline

Fluentd processes data as events. An event consists of a tag (a string used for routing), a timestamp, and a record (a JSON-like hash). The processing pipeline follows:

Input → Engine → Filter → Output

Input plugins receive events from sources (files, HTTP, syslog, etc.). The engine routes events based on their tag. Filters can modify, enrich, or drop events. Output plugins send events to destinations like databases, cloud services, or other Fluentd nodes.

Tags and Routing

Tags are hierarchical strings like app.production.nginx.access. The configuration uses <match> directives with wildcard patterns to route events to appropriate outputs. For example:

<match app.production.*>
  @type elasticsearch
  # ...
</match>

Installing Fluentd

Using the Official Packages (Recommended)

Fluentd provides native packages for Linux (rpm/deb), macOS (dmg), and Windows (msi). For a Debian-based system:

# Install the GPG key and repository
curl -fsSL https://toolbelt.treasuredata.com/sh/install-debian-stretch-td-agent4.sh | sh
# Or use the newer Fluentd package
# For Ubuntu 20.04+
curl -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-focal-td-agent4.sh | sh
sudo systemctl start td-agent
sudo systemctl enable td-agent

The package installs td-agent, a distribution of Fluentd maintained by Treasure Data. The configuration file is at /etc/td-agent/td-agent.conf.

Docker Deployment

Fluentd is often deployed as a DaemonSet in Kubernetes. You can pull the official Docker image:

docker run -d --name fluentd \
  -v /path/to/conf:/fluentd/etc \
  -p 24224:24224 \
  fluentd/fluentd:latest

Building Your First Configuration

Reading Logs from a File (Input Plugin)

A common task is tailing log files from a web server. The tail input plugin monitors files and parses each line as an event. Below is a minimal configuration:

<source>
  @type tail
  path /var/log/nginx/access.log
  pos_file /var/log/td-agent/nginx-access.log.pos
  tag nginx.access
  format nginx
  <parse>
    @type nginx
  </parse>
</source>

This reads the Nginx access log, uses a positional file to track where it left off, and tags events as nginx.access.

Transforming Events with Filters

Often you need to enrich logs with metadata or parse unstructured data. The filter section modifies events before they reach the output. For example, to add the hostname of the node:

<filter nginx.*>
  @type record_transformer
  enable_ruby true
  <record>
    hostname "#{Socket.gethostname}"
    environment "production"
  </record>
</filter>

The record_transformer plugin allows inline Ruby code to compute new fields.

Sending Data to Output Destinations

Now route the enriched events to an output. A typical stack includes Elasticsearch for search and a file for local backup:

<match nginx.*>
  @type copy
  <store>
    @type elasticsearch
    host elasticsearch.production.local
    port 9200
    logstash_format true
    include_tag_key true
    tag_key "fluentd_tag"
    flush_interval 10s
  </store>
  <store>
    @type file
    path /var/log/fluentd/nginx-archive.log
    compress gzip
    <buffer time>
      timekey 1d
      timekey_wait 10m
    </buffer>
  </store>
</match>

The copy output duplicates events to multiple stores. Elasticsearch output is configured with index formatting, while the file output buffers by day and compresses.

Complete Working Example: Nginx to Elasticsearch and Stdout

Below is a complete configuration file that reads Nginx logs, adds node metadata, and sends them to both Elasticsearch and stdout for debugging:

# Input: tail Nginx access log
<source>
  @type tail
  path /var/log/nginx/access.log
  pos_file /var/log/td-agent/nginx-access.pos
  tag nginx.access
  format nginx
  <parse>
    @type nginx
  </parse>
</source>

# Filter: enrich records
<filter nginx.access>
  @type record_transformer
  <record>
    node "#{Socket.gethostname}"
    app "frontend"
  </record>
</filter>

# Output: Elasticsearch and stdout
<match nginx.access>
  @type copy
  <store>
    @type elasticsearch
    host 127.0.0.1
    port 9200
    index_name nginx-logs-%Y.%m.%d
    include_tag_key true
    flush_interval 5s
  </store>
  <store>
    @type stdout
    output_type json
  </store>
</match>

Save this to /etc/td-agent/td-agent.conf, restart td-agent, and you will see JSON events printed to td-agent's log and indexed in Elasticsearch.

Handling Multi-line and Unstructured Logs

Multi-line Logs (e.g., Stack Traces)

The tail plugin can handle multi-line logs using the multiline parser. For Java stack traces:

<source>
  @type tail
  path /var/log/app.log
  pos_file /var/log/td-agent/app.log.pos
  tag app.logs
  <parse>
    @type multiline
    format_firstline /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/
    format1 /^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(?<level>\w+)\] (?<message>.*)/
    format2 /^\s+(at .+)/
    format3 /^\s+... (?<more>\d+) more/
  </parse>
</source>

Parsing JSON or Key-Value Logs

For structured logs that are already JSON, use the json parser:

<source>
  @type tail
  path /var/log/myapp/*.json
  pos_file /var/log/td-agent/myapp.pos
  tag app.json_logs
  <parse>
    @type json
  </parse>
</source>

Buffering and Reliability

Understanding Buffering

Output plugins buffer events in memory or disk before shipping. This provides resilience against network failures and backpressure. Configuration options like flush_interval, chunk_limit_size, and buffer_type control buffering behavior. For production, always use buffer_type file to prevent data loss during service restarts.

Example: File Buffer with Retry

<match app.logs>
  @type forward
  send_timeout 60s
  recover wait_interval 10s
  hard_timeout 300s
  <buffer>
    @type file
    path /var/log/td-agent/buffer/app
    chunk_limit_size 8MB
    total_limit_size 64GB
    flush_interval 5s
    retry_exponential_backoff true
    retry_max_times 10
  </buffer>
  <server>
    host log-aggregator.local
    port 24224
  </server>
</match>

Best Practices for Fluentd in Production

1. Use File Buffering for All Outputs

Memory buffers are faster but volatile. Always configure buffer_type file with appropriate paths to survive crashes. Set total_limit_size to prevent disk exhaustion.

2. Centralize Configuration with Includes

Large configurations become unwieldy. Use the @include directive to split configs by input, filter, and output:

# /etc/td-agent/td-agent.conf
@include /etc/td-agent/conf.d/inputs/*.conf
@include /etc/td-agent/conf.d/filters/*.conf
@include /etc/td-agent/conf.d/outputs/*.conf

3. Monitor Fluentd Itself

Enable the built-in monitoring agent to expose metrics on HTTP:

<source>
  @type monitor_agent
  port 24220
  bind 0.0.0.0
</source>

Integrate these metrics with Prometheus or Datadog to detect backpressure or plugin errors.

4. Use Labeled Routes for Complex Pipelines

The @label directive allows splitting the pipeline into separate processing paths, reducing confusion in large configs:

<source>
  @type tail
  @label @nginx
  path /var/log/nginx/access.log
  tag raw.nginx
</source>

<label @nginx>
  <filter raw.nginx>
    @type parser
    key_name message
    <parse>@type nginx</parse>
  </filter>
  <match raw.nginx>
    @type elasticsearch
    # ...
  </match>
</label>

5. Handle High Throughput with Workers

Fluentd v1.14+ supports multi-process workers to utilize multiple CPU cores. Set the workers parameter in the system config:

<system>
  workers 4
</system>

6. Secure Your Log Stream

Enable TLS for forward outputs and encrypt sensitive fields using the filter_record_transformer or custom plugins. Always run Fluentd as a non-root user in containers.

Common Troubleshooting Scenarios

Events Not Being Delivered

Parsing Failures

If events have the @timestamp missing or are tagged as unknown, the parser likely failed. Use the @type none parser to capture raw logs and then apply a filter parser with emit_invalid_record_to_error true to debug.

Conclusion

Fluentd is a robust, scalable solution for log unification that becomes indispensable in modern infrastructure. By understanding its event-driven architecture, mastering the configuration syntax, and applying production best practices—such as file buffering, monitoring, and pipeline segmentation—you can build a reliable logging pipeline that adapts to any environment. Start with simple tail-and-forward setups, then gradually introduce parsing, enrichment, and multi-output routing as your needs grow. With over 500 plugins, Fluentd can integrate with virtually any system, making it the backbone of your observability stack.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles