/var/log/, batches the records, and ships them to Rootprint’s OTLP endpoint with a Bearer token. Records land in the index your ingest token is scoped to: otel-logs-v0_9 in this guide. Run Fluent Bit on bare metal or in Docker — pick the tab below.
Prerequisites
- A running Rootprint instance and its base URL — you’ll substitute it for
<your-rootprint>. - A Linux host. The Bare Metal tab uses
systemd; the Docker tab uses Docker Compose. - An ingest API key scoped to your target index. In Settings → API keys, click Create ingest key, give it a name, and pick the index (
otel-logs-v0_9here; see Indexes for its schema). See API keys.
- Bare Metal
- Docker
Install Fluent Bit
Install the Fluent Bit package for your platform from the official downloads
page. Per-distro instructions
(Debian/Ubuntu apt, RHEL/Fedora dnf, Windows installer) are maintained upstream.
Pin to a recent release so the
opentelemetry output is mature.Write the Fluent Bit config
Save the following at
/etc/fluent-bit/fluent-bit.conf. Replace <your-rootprint-host> with the
hostname of your Rootprint deployment, <port> with 443 (HTTPS) or 80 (HTTP) or whatever
custom port you serve on, <your-ingest-token> with the API key you copied in step 1, and
/var/log/myapp/*.log with the glob that matches your application’s log files.Read_from_Head False skips existing content on first start, so installing Fluent Bit against
an existing log file does not replay everything that was already there. Flip it to True if
you want a one-time backfill. Without a DB parameter (covered below), Fluent Bit re-applies
Read_from_Head on every restart. Fine for the first install, worth revisiting once the
setup is in production.Grant read access to the log files
The Fluent Bit package installs a
fluent-bit service user that may not be able to read
files under /var/log/. Add it to the group that owns them, or sudo chmod a+r the log
files (which loosens permissions for every user on the host).Restart Fluent Bit
active (running) and the most recent log lines should not
contain config-parse or output-startup errors.Send a test log line
Create the application log directory if it doesn’t exist yet and append a single line:
Setting service.name and host.name
The minimum config above does not populate OTLP resource attributes. Fluent Bit’s opentelemetry output has no resource-attributes parameter. The upstream plugin treats every record-level field as an OTLP log-record attribute, not a resource attribute. Rows then show up under (unknown service) in the Rootprint service filter, and host.name is empty.
To fix this, add a record_modifier filter that injects the fields. Insert this [FILTER] block between [INPUT] and [OUTPUT]:
myapp with the value you want to see in the Rootprint service filter. ${HOSTNAME} is expanded from the Fluent Bit process environment; if you run Fluent Bit under systemd, set Environment=HOSTNAME=%H in the unit override or pass the value through.
These fields land as OTLP log-record attributes rather than resource attributes. Rootprint’s service filter falls back to log-record service.name when the resource attribute is missing, so the filter populates correctly. If you need a true resource-attribute split (different services multiplexed through the same Fluent Bit instance), an OpenTelemetry Collector sidecar in front of Fluent Bit is the cleaner option.
Persisting tail offsets across restarts
By default the wizard config does not persist file offsets, so every Fluent Bit restart re-appliesRead_from_Head. With False, that means lines written between stop and restart are skipped. For production, add a DB parameter to the [INPUT] block so Fluent Bit checkpoints offsets in SQLite:
/var/lib/fluent-bit/, so create it first or the tail input fails to initialize with cannot open database ...:
sudo chown -R fluent-bit:fluent-bit /var/lib/fluent-bit.
Troubleshooting
401from Rootprint: theAuthorizationheader is missing or malformed. Confirm the value on theHeaderline reads exactlyAuthorization Bearer <token>, with one space betweenAuthorizationandBearerand one betweenBearerand the token.403from Rootprint: the API key’s index scope does not matchotel-logs-v0_9, or the key has been deleted. Mint a fresh ingest API key forotel-logs-v0_9in Settings → API keys.413from a proxy in front of Rootprint: a single batch was too large on the wire. Rootprint itself sets no OTLP body-size limit, but a reverse proxy may. Lower the output batch size by settingWorkers 1and reducingMem_Buf_Limiton the[INPUT]block, or split the upstream load across multiple[INPUT]instances.415from Rootprint: wrong output plugin selected. TheNameline on the[OUTPUT]block must readopentelemetry, nothttp. Thehttpplugin sends a content type Rootprint’s OTLP endpoint rejects.- Fluent Bit starts cleanly but no logs appear in Rootprint:
Read_from_Head Falseskipped the existing file content. Either append a new line to trigger a read, or setRead_from_Head Truefor a one-time replay (Fluent Bit remembers the offset inDBafter the first read). permission deniedreading/var/log/...: the Fluent Bit package installs afluent-bitservice user that owns the daemon. Eithersudo chmod a+rthe log files, or addfluent-bitto the group that owns them.cannot open database /var/lib/fluent-bit/myapp.db/failed initialize input tail.0: you added aDBparameter (see Persisting tail offsets across restarts) but the directory does not exist.sudo mkdir -p /var/lib/fluent-bitand restart.- Records arrive but
bodyis empty: confirm theLogs_body_keyvalue matches the field thetailinput emits. Thetailinput writes the raw line under the keylog, soLogs_body_key $logis the correct mapping. If you inserted a parser earlier in the chain that renames or unwraps the field, pointLogs_body_keyat the new key.
Related
- Send logs from Docker: collect every container’s stdout via the Docker daemon, rather than tailing specific files.
- Send logs from Kubernetes: run the Collector as a DaemonSet across a cluster.
- OTLP reference: endpoint URL, response codes, body limits.
- Indexes: the
otel-logs-v0_9schema, so you know what you can search. - Manage indexes: API key lifecycle and per-index permissions.
