Fluentd’s debug logging is often misunderstood as just "more logs," but it’s actually a powerful tool that exposes the internal state transitions of your data pipeline, revealing where and why messages get dropped or corrupted.

Let’s see it in action. Imagine you have a simple Fluentd configuration:

<source>
  @type forward
  port 24224
  <parse>
    @type json
  </parse>
</source>

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

This setup listens for JSON messages on port 24224 and prints them to standard output. Now, let’s simulate a problem: a message arrives that isn’t valid JSON. Without debug logging, you might just see nothing appearing in stdout, or a generic error if the stdout plugin itself fails.

To enable debug logging, you modify your fluentd command or service configuration. If you’re running fluentd from the command line, you’d add the -v or -vv flags. For more verbose output (which is usually what you want for debugging), -vv is the way to go.

fluentd -c /etc/fluentd/fluentd.conf -vv

If you’re managing Fluentd as a systemd service, you’d edit the service file (e.g., /etc/systemd/system/fluentd.service) and add the -vv flag to the ExecStart line:

ExecStart=/usr/sbin/fluentd -c /etc/fluentd/fluentd.conf -vv

After restarting the service (sudo systemctl restart fluentd), and sending a malformed JSON message (e.g., {"key": "value" without the closing brace), your logs will explode with information. You’ll see detailed traces of Fluentd attempting to parse the incoming data, the specific point of failure, and how it subsequently handles the unparseable record.

The core problem debug logging solves is ambiguity. When a message vanishes or an unexpected transformation occurs, debug logs show you the exact sequence of events within Fluentd. You’re not guessing what happened; you’re observing the internal state changes.

Here’s how it works mechanically. Fluentd operates as a series of plugins: source, filter, and match. Debug logging increases the log_level for all these plugins. When enabled, each plugin will emit verbose messages detailing:

  • Data Ingestion: When a source plugin receives data, it logs the raw bytes or initial parsed structure.
  • Parsing Attempts: When a parser (like json, apache2, regexp) is invoked, debug logs show the input string and the result of the parsing attempt – success or failure with specific error details.
  • Record Transformation: If filter plugins are used, each filter will log the record before and after its operation, showing exactly what data is being modified.
  • Routing Decisions: For match plugins, you’ll see which match patterns are evaluated and which ones succeed for a given record.
  • Buffering and Output: When data is buffered or sent to an output plugin, debug logs detail the process, including any errors encountered during transmission.

Consider a common scenario: data is sent to Fluentd, but never appears in your Elasticsearch index. With -vv, you’d see:

  1. The forward source plugin receiving the data.
  2. The parse json plugin attempting to deserialize it. If it fails, you’ll see an error like JSON::ParserError and the offending fragment of data.
  3. If parsing succeeds, you’ll see the record being passed to the match section.
  4. The elasticsearch output plugin will log its attempt to index the document, including the HTTP request details and any response from Elasticsearch.

This detailed trace allows you to pinpoint the exact plugin and the specific operation that’s failing. You can then adjust configurations, fix malformed data at the source, or troubleshoot network issues between Fluentd and its downstream systems.

The surprising thing about Fluentd’s debug logging is how granular it is about failed operations. It doesn’t just log "error"; it logs "attempted to parse X as JSON, failed with Unexpected token '}' at position 42, and is now discarding this record." This level of detail is crucial for understanding why data might be silently disappearing from your pipeline, rather than just indicating a general error state.

When you’re done debugging, remember to revert your Fluentd configuration to a less verbose log level (e.g., -q for quiet, or no flag for default) to avoid overwhelming your log storage and impacting performance.

The next common issue you’ll encounter is understanding how Fluentd’s buffering mechanisms handle large volumes of data during periods of high load or downstream unavailability.

Want structured learning?

Take the full Fluentd course →