Overview
This guide sends the logs that Fluent Bit collects to SigNoz. Fluent Bit sends the logs with its forward output to the OpenTelemetry Collector. The Collector receives them with the fluentforward receiver and exports them to SigNoz. On Kubernetes, the Collector also turns the pod metadata that Fluent Bit adds into separate k8s.* attributes.
Prerequisites
- Fluent Bit. This guide uses Fluent Bit v5.1.5.
- An instance of SigNoz (either Cloud or Self-Hosted).
- The OpenTelemetry Collector on a VM, or the
k8s-infrachart on Kubernetes.
Send Fluent Bit logs to SigNoz
Step 1. Add the fluentforward receiver to the Collector
Add the fluentforward receiver to the receivers section of the Collector configuration (/etc/otelcol-contrib/config.yaml). Then add it to the logs pipeline:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
# On Collector v0.151.0 and newer, use "fluent_forward" to avoid a deprecation warning.
fluentforward:
endpoint: 0.0.0.0:24224
service:
pipelines:
logs:
receivers: [otlp, fluentforward]
processors: [batch, resourcedetection]
exporters: [otlphttp]The receiver listens on port 24224 for the Fluent Forward protocol. Keep the other sections of the file from the install guide.
Restart the Collector:
sudo systemctl restart otelcol-contribThe path and the command apply to the DEB and RPM packages. For macOS and Windows, use the configuration path and the restart steps in the install guide.
Step 2. Add a forward output to Fluent Bit
Add a forward output to the Fluent Bit configuration (fluent-bit.yaml):
pipeline:
outputs:
- name: forward
match: '*'
host: <collector-host>
port: 24224
retain_metadata_in_forward_mode: falseVerify these values:
<collector-host>: The host where the Collector runs. Use127.0.0.1when Fluent Bit runs on the same host.
Set retain_metadata_in_forward_mode to false. Fluent Bit v5.0.4 and newer set it to true by default, and the fluentforward receiver cannot read that format. The receiver then drops every log, and Fluent Bit still reports a successful flush.
Restart Fluent Bit so that it loads the new output.
The Fluent Bit Helm chart runs Fluent Bit as a DaemonSet. Fluent Bit reads the container log files on each node, and its kubernetes filter adds the pod metadata to each log as one nested kubernetes map. This step sends the logs to the k8s-infra OpenTelemetry Collector agent, which splits that map into k8s.* resource attributes.
Step 1. Add the receiver and the mapping to k8s-infra
Add these values to the override-values.yaml file of your k8s-infra release:
presets:
logsCollection:
enabled: false
otelAgent:
ports:
fluentforward:
enabled: true
containerPort: 24224
servicePort: 24224
protocol: TCP
config:
receivers:
fluentforward:
endpoint: 0.0.0.0:24224
processors:
transform/fluentbit_k8s:
error_mode: ignore
log_statements:
- set(log.attributes["k8s.pod.name"], log.attributes["kubernetes"]["pod_name"]) where log.attributes["kubernetes"] != nil
- set(log.attributes["k8s.namespace.name"], log.attributes["kubernetes"]["namespace_name"]) where log.attributes["kubernetes"] != nil
- set(log.attributes["k8s.pod.uid"], log.attributes["kubernetes"]["pod_id"]) where log.attributes["kubernetes"] != nil
- set(log.attributes["k8s.container.name"], log.attributes["kubernetes"]["container_name"]) where log.attributes["kubernetes"] != nil
- set(log.attributes["k8s.node.name"], log.attributes["kubernetes"]["host"]) where log.attributes["kubernetes"] != nil
- delete_key(log.attributes, "kubernetes")
groupbyattrs/fluentbit_k8s:
keys: [k8s.pod.name, k8s.namespace.name, k8s.pod.uid, k8s.container.name, k8s.node.name]
service:
pipelines:
logs:
receivers: [otlp, fluentforward]
processors: [transform/fluentbit_k8s, groupbyattrs/fluentbit_k8s, batch]These values do the following:
presets.logsCollection.enabled: falsestops thek8s-infraagent from reading the container log files. Fluent Bit reads them, so without this line each log arrives twice.otelAgent.ports.fluentforwardopens port 24224 on the agent pods and on the agent Service.- The
transform/fluentbit_k8sprocessor copies the fields of thekubernetesmap tok8s.*attributes, then deletes the map. - The
groupbyattrs/fluentbit_k8sprocessor moves those attributes to the resource. SigNoz then shows the logs under the correct pod, namespace, and container.
The chart adds its own processors before these, so you only list the new ones.
Apply the values:
helm upgrade <release-name> signoz/k8s-infra -n <namespace> -f override-values.yamlVerify these values:
<release-name>: The name of yourk8s-infrarelease.<namespace>: The namespace of yourk8s-infrarelease.
Step 2. Install Fluent Bit with a forward output
Save these values as fluent-bit-values.yaml:
config:
inputs: |
[INPUT]
Name tail
Path /var/log/containers/*.log
Exclude_Path /var/log/containers/*-otel-agent-*_<namespace>_*.log
multiline.parser docker, cri
Tag kube.*
Mem_Buf_Limit 5MB
Skip_Long_Lines On
outputs: |
[OUTPUT]
Name forward
Match kube.*
Host <release-name>-k8s-infra-otel-agent.<namespace>.svc.cluster.local
Port 24224
Retain_Metadata_In_Forward_Mode falseVerify these values:
<release-name>: The name of yourk8s-infrarelease. If the release name already containsk8s-infra, the Service is<release-name>-otel-agent. Runkubectl get svc -n <namespace>to see the name.<namespace>: The namespace of yourk8s-infrarelease. TheExclude_Pathline stops Fluent Bit from reading the logs of the agent pods. Other pods in that namespace still send their logs.
The chart keeps its default kubernetes filter, which adds the pod metadata. Set Retain_Metadata_In_Forward_Mode to false. Fluent Bit v5.0.4 and newer set it to true by default, and the fluentforward receiver drops logs in that format.
Install the chart:
helm repo add fluent https://fluent.github.io/helm-charts
helm repo update
helm install fluent-bit fluent/fluent-bit -n logging --create-namespace -f fluent-bit-values.yamlIf you already run the Fluent Bit chart, add the forward output and the Exclude_Path line to your values file instead, then upgrade that release:
helm upgrade <fluent-bit-release> fluent/fluent-bit -n <fluent-bit-namespace> -f <your-values-file>Link logs to traces (Optional)
If your logs carry trace_id and span_id fields, the Collector stores them as plain attributes. Move them to the trace context of the log, so that SigNoz links each log to its trace.
Add a transform processor to the processors section of the Collector configuration:
processors:
transform/trace_context:
error_mode: ignore
log_statements:
- set(log.trace_id.string, log.attributes["trace_id"]) where log.attributes["trace_id"] != nil
- set(log.span_id.string, log.attributes["span_id"]) where log.attributes["span_id"] != nil
- delete_key(log.attributes, "trace_id")
- delete_key(log.attributes, "span_id")Add the processor to the start of the logs pipeline:
service:
pipelines:
logs:
receivers: [otlp, fluentforward]
processors: [transform/trace_context, batch, resourcedetection]
exporters: [otlphttp]On Kubernetes, add the same processor under otelAgent.config.processors and to the logs pipeline in override-values.yaml.
Send logs without a Collector (Optional)
Fluent Bit can send logs to SigNoz Cloud over OTLP with its opentelemetry output. Use this path when you do not run a Collector. The Kubernetes mapping above needs the Collector, so this path fits a VM or Docker host. This path sends logs to SigNoz Cloud. For Self-Hosted SigNoz, use the Collector path.
pipeline:
inputs:
- name: tail
path: <log-file-path>
processors:
logs:
- name: opentelemetry_envelope
- name: content_modifier
context: otel_resource_attributes
action: upsert
key: service.name
value: <service-name>
outputs:
- name: opentelemetry
match: '*'
host: ingest.<region>.signoz.cloud
port: 443
tls: on
tls.verify: on
logs_uri: /v1/logs
header: signoz-ingestion-key <your-ingestion-key>Verify these values:
<log-file-path>: The log file that Fluent Bit reads, for example/var/log/app/*.log.<service-name>: The name that SigNoz shows for these logs. Theopentelemetry_envelopeandcontent_modifierprocessors set it as theservice.nameresource attribute.<region>: Your SigNoz Cloud region.<your-ingestion-key>: Your SigNoz ingestion key.
Validate
- In SigNoz, open Logs > Logs Explorer.
- Filter by
fluent.tag EXISTS. Thefluentforwardreceiver adds the Fluent Bit tag of each log as thefluent.tagattribute. If you send logs without a Collector, filter byservice.nameinstead. - On Kubernetes, open a log and make sure that it has the
k8s.pod.name,k8s.namespace.name, andk8s.container.nameresource attributes, and nokubernetesattribute.

Troubleshooting
Fluent Bit reports a successful flush, but no logs arrive
Fluent Bit v5.0.4 and newer send metadata in forward mode by default. The fluentforward receiver cannot read it and drops the logs. It logs the error only at the debug level:
failed to parse forward mode e: unknown type of value: [... map[]] at Time at Entries/0Set retain_metadata_in_forward_mode: false in the forward output, then restart Fluent Bit.
Fluent Bit cannot connect to the Collector
Fluent Bit logs no upstream connections available.
- Make sure that the Collector runs and that the
logspipeline lists thefluentforwardreceiver. - Make sure that the
hostandportof theforwardoutput match the Collector. On Kubernetes, runkubectl get svc -n <namespace>and make sure that the agent Service lists port 24224.
Kubernetes metadata stays in one attribute
Logs show a single kubernetes attribute when the transform/fluentbit_k8s processor does not run. Make sure that the logs pipeline in override-values.yaml lists transform/fluentbit_k8s and groupbyattrs/fluentbit_k8s, then run helm upgrade again.
Each Kubernetes log appears twice
The k8s-infra agent and Fluent Bit both read the container log files. Set presets.logsCollection.enabled to false in override-values.yaml, then run helm upgrade again.
Next steps
- Create log pipelines to parse fields or change severity after ingestion.
- Correlate traces and logs to jump from a log to its trace.
- Set up log-based alerts on error logs.
Get Help
If you need help with the steps in this topic, please reach out to us on SigNoz Community Slack. If you are a SigNoz Cloud user, please use in product chat support located at the bottom right corner of your SigNoz instance or contact us at cloud-support@signoz.io.