Skip to content

rsyslog

Ship logs from any application that writes to /dev/log — the standard Unix syslog socket — to Kopai via rsyslog and the OpenTelemetry Collector. The application needs no code changes: it already uses syslog(3) or a language equivalent, and rsyslog is already reading from /dev/log on every Debian, Ubuntu, and RHEL-family host.

This is the classic migration path — a Linux server with legacy services that already log via syslog, and you want their output in Kopai without touching a line of their code.

  • rsyslog (standard on Debian, Ubuntu, and most RHEL-family distributions)
  • otelcol-contrib
  • Kopai running locally:
Terminal window
npx @kopai/app start

Create otel-collector/rsyslog.yaml with a syslog receiver on port 54527:

receivers:
syslog:
tcp:
listen_address: "0.0.0.0:54527"
protocol: rfc3164
operators:
- type: move
from: attributes.message
to: body
processors:
batch: {}
resource:
attributes:
- key: service.name
value: "my-service"
action: insert
exporters:
otlphttp/kopai:
endpoint: http://localhost:4318
tls:
insecure: true
service:
pipelines:
logs:
receivers: [syslog]
processors: [resource, batch]
exporters: [otlphttp/kopai]

The receiver parses the RFC 3164 envelope, lifts the payload into the log body, and preserves facility, severity, and timestamp as attributes.

Terminal window
otelcol-contrib --config otel-collector/rsyslog.yaml

When the collector is healthy you’ll see a final log line like Everything is ready. Begin running and processing data. and port 54527 will be listening (ss -ltn | grep 54527).

Before touching rsyslog, you can validate the collector and Kopai end-to-end by piping a synthetic RFC 3164 message at the listener:

Terminal window
printf '<14>%s testhost kopai-test: hello-from-smoke-test\n' "$(date '+%b %e %H:%M:%S')" \
| nc -q1 127.0.0.1 54527

Then run the verification commands below and look for hello-from-smoke-test in the body.

Add one rule to /etc/rsyslog.conf (or drop a file in /etc/rsyslog.d/) to forward all syslog traffic to the collector over TCP:

*.* action(
type="omfwd"
target="127.0.0.1"
port="54527"
protocol="tcp"
action.resumeRetryCount="10"
queue.type="linkedList"
queue.size="10000"
)

The linkedList queue buffers messages if the collector is briefly unreachable. Reload rsyslog:

Terminal window
sudo systemctl restart rsyslog

Any process on the host that calls syslog(3), writes to /dev/log, or uses a language syslog handler (Python’s SysLogHandler, Java’s SyslogAppender, etc.) now flows through to Kopai.

Confirm logs arrived using the Kopai CLI:

Terminal window
# Recent entries with timestamps
npx @kopai/cli logs search --service my-service \
--fields Timestamp,Body --sort ASC
# Filter to errors only (severity-min 17 = ERROR)
npx @kopai/cli logs search --service my-service --severity-min 17 --json

Swap the exporter endpoint and add a bearer token:

exporters:
otlphttp/kopai:
endpoint: https://otlp-http.kopai.app
headers:
authorization: "Bearer YOUR_BACKEND_TOKEN"

Drop the tls: insecure: true block — the cloud endpoint uses real TLS.

For a complete runnable example with a demo Python app, rsyslog, and the collector all wired up under Docker Compose:

Rsyslog Example