systemd service on a Linux host: it tails files under /var/log/, batches the records, and ships them to Logwiz’s OTLP endpoint with a Bearer token. Records land in your otel-logs-v0_9 index, the same index every OpenTelemetry SDK writes to.
Setup
Pick the target index and create an ingest token
The default index for OTLP traffic is
otel-logs-v0_9 — see Indexes for its
schema. In Administration → Tokens, click Create Token, pick otel-logs-v0_9, and
copy the token value from the new row. Tokens are scoped to one index — you cannot reuse a
token across indexes.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, container images, 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-logwiz-host> with the
hostname of your Logwiz deployment, <port> with 443 (HTTPS) or 80 (HTTP) or whatever
custom port you serve on, <your-ingest-token> with the token 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.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. The result is that rows show up under (unknown service) in the Logwiz 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 Logwiz 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 — Logwiz’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 Logwiz — theAuthorizationheader is missing or malformed. Confirm the value on theHeaderline reads exactlyAuthorization Bearer <token>, with one space betweenAuthorizationandBearerand one betweenBearerand the token.403from Logwiz — the token’s index scope does not matchotel-logs-v0_9, or the token was revoked. Mint a fresh token forotel-logs-v0_9in Administration → Tokens.413from Logwiz — a single batch exceeded 10 MB on the wire. Lower the output batch size by settingWorkers 1and reducingMem_Buf_Limiton the[INPUT]block, or split the upstream load across multiple[INPUT]instances.415from Logwiz — wrong output plugin selected. TheNameline on the[OUTPUT]block must readopentelemetry, nothttp. Thehttpplugin sends a content type Logwiz’s OTLP endpoint rejects.- Fluent Bit starts cleanly but no logs appear in Logwiz —
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
- OTLP reference — endpoint URL, response codes, body limits.
- Indexes — the
otel-logs-v0_9schema, so you know what you can search. - Manage indexes — token lifecycle and per-index permissions.
