Skip to content
Last9
Book demo

Cloudflare Tunnel Logs

Send Cloudflare Tunnel (cloudflared) logs to Last9 via the OpenTelemetry Collector journald receiver with correct severity mapping.

Send logs from the Cloudflare Tunnel daemon (cloudflared) to Last9 using the OpenTelemetry Collector’s journald receiver.

Prerequisites

  1. Create a Last9 account by following Getting Started.
  2. Keep the following from the Integrations page:
    • $last9_otlp_endpoint — Last9’s OTLP endpoint
    • $last9_basic_auth_header — OpenTelemetry Basic authorization header
  3. cloudflared installed and running as a systemd service on your host.

Verify cloudflared is active before proceeding:

systemctl status cloudflared
journalctl -u cloudflared -n 10 --no-pager

Install OpenTelemetry Collector

Install otelcol-contrib on the same host as cloudflared:

sudo apt-get update && sudo apt-get install -y wget
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.120.0/otelcol-contrib_0.120.0_linux_amd64.deb
sudo dpkg -i otelcol-contrib_0.120.0_linux_amd64.deb

More installation options: OpenTelemetry Collector installation.

Configuration

Edit /etc/otelcol-contrib/config.yaml:

receivers:
journald:
directory: /var/log/journal
units:
- cloudflared
priority: info
operators:
# Tag logs with tunnel identity
- type: add
field: attributes["connector.id"]
value: "<your_connector_id>"
- type: add
field: attributes["tunnel.name"]
value: "<your_tunnel_name>"
# cloudflared sets PRIORITY=6 for all log levels regardless of actual severity.
# Parse the level token from the message body instead (INF/WRN/ERR/DBG/FTL).
- type: regex_parser
parse_from: body["MESSAGE"]
regex: '^\d{4}-\d{2}-\d{2}T[\d:Z]+ (?P<log_level>[A-Z]{2,4})'
on_error: send
- type: severity_parser
parse_from: attributes.log_level
mapping:
debug: DBG
info: INF
warn: WRN
error: ERR
fatal: FTL
processors:
resource:
attributes:
- key: service.name
value: "cloudflare-tunnel"
action: upsert
- key: service.namespace
value: "<your_namespace>"
action: upsert
batch:
timeout: 5s
send_batch_size: 200
exporters:
otlphttp/last9:
endpoint: "$last9_otlp_endpoint"
headers:
Authorization: "$last9_basic_auth_header"
service:
pipelines:
logs:
receivers: [journald]
processors: [resource, batch]
exporters: [otlphttp/last9]

Why parse severity from the message body?

cloudflared does not set the journald PRIORITY field correctly — it emits PRIORITY=6 (INFO) for all log entries including warnings and errors. Severity must be extracted from the level token embedded in the message body:

2026-04-22T01:45:13Z ERR failed to accept incoming stream requests error="..."
^^^
actual level token

The regex_parser operator extracts this token and severity_parser maps it to the OTel severity scale:

cloudflared tokenOTel severity
DBGDebug
INFInfo
WRNWarn
ERRError
FTLFatal

Start the collector

sudo systemctl start otelcol-contrib
sudo systemctl enable otelcol-contrib
sudo systemctl status otelcol-contrib

Check collector logs:

sudo journalctl -u otelcol-contrib -f

Verification

Visit Log Explorer and filter by service.name = cloudflare-tunnel. You should see logs with populated severity levels (Info, Warn, Error).

Running with Docker

If you prefer to run the collector in Docker instead of installing it directly, mount the host’s journald directories:

services:
otelcol:
image: otel/opentelemetry-collector-contrib:0.120.0
command: ["--config=/etc/otelcol-contrib/config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml:ro
- /run/log/journal:/run/log/journal:ro
- /var/log/journal:/var/log/journal:ro
- /etc/machine-id:/etc/machine-id:ro
group_add:
- "systemd-journal"
restart: unless-stopped

A complete working example is available at l9_otel_examples/cloudflare-tunnel.


Troubleshooting

No logs in Last9

  • Confirm cloudflared is writing to journald: journalctl -u cloudflared -n 5
  • Check collector can read the unit: add debug exporter temporarily to see what’s being received

All logs appear as INFO severity

  • Verify cloudflared log format matches the regex: journalctl -u cloudflared -n 5 --output=cat
  • Expected format: 2026-01-01T00:00:00Z ERR message text

Please get in touch with us on Discord or Email if you have any questions.