# rsyslog Forward syslog messages from rsyslog to Kopai via the OpenTelemetry Collector # Integration Ship logs from any application that writes to `/dev/log` — the standard Unix syslog socket — to Kopai via [rsyslog](https://www.rsyslog.com) 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. ## Prerequisites - rsyslog (standard on Debian, Ubuntu, and most RHEL-family distributions) - [`otelcol-contrib`](https://github.com/open-telemetry/opentelemetry-collector-releases) - Kopai running locally: **npm:** ```bash npx @kopai/app start ``` **pnpm:** ```bash pnpm dlx @kopai/app start ``` **yarn:** ```bash yarn dlx @kopai/app start ``` ## Configure the collector Create `otel-collector/rsyslog.yaml` with a `syslog` receiver on port 54527: ```yaml 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. ## Run the collector ```bash 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`). ## Quick smoke test Before touching rsyslog, you can validate the collector and Kopai end-to-end by piping a synthetic RFC 3164 message at the listener: ```bash 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. ## Forward from rsyslog 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" ) ``` :::note **Timestamp accuracy**: RFC 3164 syslog messages contain no year and no timezone. The collector parses the wall-clock timestamp as UTC, so logs ingested this way will appear shifted by your local UTC offset in Kopai. If you need accurate timestamps (for trace correlation, incident timelines, etc.), use RFC 5424 instead by changing the rsyslog rule to `RSYSLOG_SyslogProtocol23Format` and setting `protocol: rfc5424` in the collector receiver. ::: The `linkedList` queue buffers messages if the collector is briefly unreachable. Reload rsyslog: ```bash 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. ## Verify Confirm logs arrived using the Kopai CLI: **npm:** ```bash # 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 ``` **pnpm:** ```bash # Recent entries with timestamps pnpm dlx @kopai/cli logs search --service my-service \ --fields Timestamp,Body --sort ASC # Filter to errors only (severity-min 17 = ERROR) pnpm dlx @kopai/cli logs search --service my-service --severity-min 17 --json ``` **yarn:** ```bash # Recent entries with timestamps yarn dlx @kopai/cli logs search --service my-service \ --fields Timestamp,Body --sort ASC # Filter to errors only (severity-min 17 = ERROR) yarn dlx @kopai/cli logs search --service my-service --severity-min 17 --json ``` ## Sending to Kopai.app in the cloud Swap the exporter endpoint and add a bearer token: ```yaml 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. ## Working Example For a complete runnable example with a demo Python app, rsyslog, and the collector all wired up under Docker Compose: **[Rsyslog Example](https://github.com/kopai-app/kopai-integration-examples/tree/main/syslog/python-rsyslog)**