Docs: Fluent Bit
Documentation / Ingestion

Fluent Bit

Ship logs from Fluent Bit or Fluentd to OBSESC over the native Fluent Forward protocol.

OBSESC speaks the Fluent Forward protocol natively, so Fluent Bit and Fluentd can send to it with their built-in forward output. Add one [OUTPUT] block and keep your existing output as it is.

Endpoint

SettingValue
ProtocolFluent Forward (msgpack over TCP, not HTTP)
Default port24224 (ingest.fluent_port)
Modes acceptedForward, PackedForward, CompressedPackedForward (gzip)
AuthenticationShared-key handshake (security.fluent_shared_key)
AcknowledgementsChunk acks, sent after the data is durable

The stock CloudFormation stack doesn’t open port 24224. Add an inbound security group rule from your shipper subnets first. See Network configuration.

Fluent Bit configuration

[SERVICE]
    Flush        1
    Log_Level    info

[INPUT]
    Name              tail
    Path              /var/log/app/*.log
    Tag               checkout
    # Assemble multiline events here. Without this, a Java stack trace
    # arrives as one event per line.
    multiline.parser  java

# OBSESC destination (added). Your existing [OUTPUT] stays below.
[OUTPUT]
    Name                  forward
    Match                 *
    Host                  obsesc.your-domain.internal
    Port                  24224
    # Ask for an ack per chunk so retries are safe (see below):
    Require_ack_response  On
    # When the node sets security.fluent_shared_key:
    # Shared_Key          ${OBSESC_FLUENT_SHARED_KEY}
    # Self_Hostname       my-host

# Existing destination, unchanged
# [OUTPUT]
#     Name   splunk
#     Match  *
#     ...

The tag is the service

The Fluent tag becomes the OBSESC service for every record in the frame. Tag deliberately, with one tag per service rather than one per file. If you tail several services with a wildcard input, use Tag_Regex or a rewrite_tag filter so that each service gets its own tag.

Records under a generic tag can still be split. Set ingest.service_from to an attribute key such as kubernetes.namespace_name, and it’ll be used for events that would otherwise have no service.

Fluentd configuration

<match **>
  @type forward
  require_ack_response true
  <server>
    host obsesc.your-domain.internal
    port 24224
  </server>
  # When the node sets security.fluent_shared_key:
  # <security>
  #   self_hostname my-host
  #   shared_key "#{ENV['OBSESC_FLUENT_SHARED_KEY']}"
  # </security>
</match>

To dual-write from Fluentd, wrap this and your existing <store> in a copy output.

How records are mapped

Forward fieldOBSESC field
Tagservice
Entry time (integer seconds or EventTime with nanoseconds)timestamp
message or log keybody
Every other keyAttributes. Nested maps are flattened to dotted keys, such as kubernetes.pod_name

With the Fluent Bit Kubernetes filter, kubernetes.host and kubernetes.namespace_name are also read into the built-in host and namespace dimensions.

Authentication

Set security.fluent_shared_key on the node (or put fluent_shared_key in the node’s Secrets Manager secret). Every connection must then complete the Forward protocol’s shared-key handshake before it can send events. The node doesn’t offer username and password authentication, so leave those fields empty on the client.

If no shared key is set, connections skip the handshake and anyone who can reach the port can send events. In that case, limit access to port 24224 with security groups.

For encryption in transit, configure TLS on the node (see Encryption) and turn on TLS in the output:

[OUTPUT]
    Name        forward
    Match       *
    Host        obsesc.your-domain.internal
    Port        24224
    tls         On
    tls.verify  On

Delivery and retries

  • With Require_ack_response On, the node replies with {"ack": "<chunk>"} only after the chunk is durably stored. Under backpressure, while draining or on a write error, it holds the ack back, and Fluent Bit resends the chunk.
  • A resent chunk is recognised as a retry and isn’t stored twice, provided it arrives soon after the original.
  • Without acks, delivery is at-least-once, and a reconnect-and-resend can store a chunk twice.
  • A malformed frame closes the connection. Fluent Bit reconnects and retries, which is its normal backpressure behaviour.

Alternative: Elasticsearch output

If you’d rather use HTTP, Fluent Bit’s es output also works against the Elasticsearch bulk listener on port 9200:

[OUTPUT]
    Name                es
    Match               *
    Host                obsesc.your-domain.internal
    Port                9200
    Index               logs
    Suppress_Type_Name  On

Fluent Bit’s es output can’t send an ApiKey or Bearer header, though. If the node enforces security.ingest_tokens, use forward with a shared key instead.

Node-side multiline (fallback)

Assemble multiline events in Fluent Bit wherever you can. If a source can’t have a multiline parser in front of it, the node can join continuation lines for Fluent Forward records itself (ingest.multiline.enabled: true). See Configuration examples for the trade-offs.