You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
The Kafka protocol and Fluent Bit's bundled librdkafka client support message headers, but the out_kafka plugin doesn't provide a general way to create those headers from a record field.
Some pipelines receive a variable set of per-record transport attributes, such as correlation identifiers, routing metadata, or content metadata. These values need to be Kafka message headers rather than fields in the serialized message body. Keeping them in the payload isn't equivalent because Kafka consumers, interceptors, and routing infrastructure access message headers separately from the value.
librdkafka already exposes the required producer APIs through rd_kafka_headers_new(), rd_kafka_header_add(), and RD_KAFKA_V_HEADERS. The missing part is the Fluent Bit out_kafka configuration and record-mapping layer.
Describe the solution you'd like
Add a headers_key option to out_kafka. Its value identifies a top-level record field whose MessagePack map is converted to Kafka message headers for that record.
Proposed behavior:
An empty or ASCII-whitespace-only headers_key disables the feature.
Nonblank field names are matched exactly and aren't trimmed.
The selected field must be a MessagePack map.
Header names must be strings.
Header values can be strings, binary values, or null values.
Empty values, null values, insertion order, and duplicate names are preserved on the Kafka record.
Unsupported map entries are skipped with a warning.
A valid selected map is removed from the serialized payload by default.
A preserve_headers_key boolean option, defaulting to false, retains the original map in the payload when enabled.
A missing selected field leaves payload processing unchanged.
A selected field with a non-map value remains in the payload to avoid data loss.
An empty map is valid and follows the configured preservation behavior.
If duplicate top-level map fields match, the first map supplies the Kafka headers and later fields remain in the payload.
The feature applies to the avro, gelf, json, msgpack, and raw formats. A nonblank headers_key is rejected for otlp_json and otlp_proto, whose serialization path doesn't expose an individual source map.
Kafka 0.11-compatible brokers or later are required for message-header support.
This produces trace-id and content-type as Kafka message headers. The kafka_headers field isn't included in the JSON value unless preserve_headers_key is set to true.
Describe alternatives you've considered
Keep the attributes in the serialized payload. This doesn't make them available through Kafka's message-header interface.
Configure individual headers explicitly. PR out_kafka: Add dynamic/static headers support #8583 proposes repeated header options with static values or individual record-field references. That interface is useful when the header names are known in configuration, but it doesn't cover records that already contain a variable header map. The two interfaces are complementary.
Transform the record with a filter or Lua script. Filters can reshape the payload, but they can't attach Kafka producer headers through the existing output interface.
Patch librdkafka. This isn't necessary because librdkafka already implements the required protocol and ownership semantics.
Additional context
This request is a focused out_kafka implementation of the record-map use case discussed in #1673, #8334, and #9448. Those broader requests are closed as stale; #8334 and #9448 also cover both Kafka input and output, while this request deliberately defines and tests the output-side contract. It is intended to coexist with the explicit per-header configuration proposed in #8583:
header: configure one known header at a time, optionally sourcing its value from a record field.
headers_key: convert all supported entries from one record map at runtime.
The implementation can remain confined to Fluent Bit-owned plugins/out_kafka code and tests. It doesn't require changes to bundled librdkafka sources or to the Kafka wire protocol.
A tested implementation and separate documentation change are prepared locally. Coverage includes payload removal and preservation, empty/missing/non-map sources, null and binary values, duplicate names, MessagePack, raw, GELF, Avro with Schema Registry resolution, queue-full retry ownership, configured message-size rejection, startup validation, and strict Valgrind execution.
Related work: #1673, #8334, and #9448 (closed requests); #8583 and #9057 (open, conflicting implementations of individually configured headers).
Is your feature request related to a problem? Please describe.
The Kafka protocol and Fluent Bit's bundled librdkafka client support message headers, but the
out_kafkaplugin doesn't provide a general way to create those headers from a record field.Some pipelines receive a variable set of per-record transport attributes, such as correlation identifiers, routing metadata, or content metadata. These values need to be Kafka message headers rather than fields in the serialized message body. Keeping them in the payload isn't equivalent because Kafka consumers, interceptors, and routing infrastructure access message headers separately from the value.
librdkafka already exposes the required producer APIs through
rd_kafka_headers_new(),rd_kafka_header_add(), andRD_KAFKA_V_HEADERS. The missing part is the Fluent Bitout_kafkaconfiguration and record-mapping layer.Describe the solution you'd like
Add a
headers_keyoption toout_kafka. Its value identifies a top-level record field whose MessagePack map is converted to Kafka message headers for that record.Proposed behavior:
headers_keydisables the feature.preserve_headers_keyboolean option, defaulting tofalse, retains the original map in the payload when enabled.avro,gelf,json,msgpack, andrawformats. A nonblankheaders_keyis rejected forotlp_jsonandotlp_proto, whose serialization path doesn't expose an individual source map.Sanitized YAML example:
This produces
trace-idandcontent-typeas Kafka message headers. Thekafka_headersfield isn't included in the JSON value unlesspreserve_headers_keyis set totrue.Describe alternatives you've considered
headeroptions with static values or individual record-field references. That interface is useful when the header names are known in configuration, but it doesn't cover records that already contain a variable header map. The two interfaces are complementary.Additional context
This request is a focused
out_kafkaimplementation of the record-map use case discussed in #1673, #8334, and #9448. Those broader requests are closed as stale; #8334 and #9448 also cover both Kafka input and output, while this request deliberately defines and tests the output-side contract. It is intended to coexist with the explicit per-header configuration proposed in #8583:header: configure one known header at a time, optionally sourcing its value from a record field.headers_key: convert all supported entries from one record map at runtime.The implementation can remain confined to Fluent Bit-owned
plugins/out_kafkacode and tests. It doesn't require changes to bundled librdkafka sources or to the Kafka wire protocol.A tested implementation and separate documentation change are prepared locally. Coverage includes payload removal and preservation, empty/missing/non-map sources, null and binary values, duplicate names, MessagePack, raw, GELF, Avro with Schema Registry resolution, queue-full retry ownership, configured message-size rejection, startup validation, and strict Valgrind execution.
Related work: #1673, #8334, and #9448 (closed requests); #8583 and #9057 (open, conflicting implementations of individually configured headers).