24observe works with the stock OpenTelemetry Collector (contrib) — no custom image, no fork. Drop in the config below and the collector accepts telemetry over OTLP/gRPC (the SDK and collector default) and OTLP/HTTP, then forwards it to 24observe authenticated and gzip-compressed.
Use the collector when your apps export over gRPC, when you don't want the API token in every app's environment, or when you have legacy sources (syslog, Fluent Bit). If your SDK already exports OTLP/HTTP, you can also target our endpoint directly — we accept JSON and binary protobuf natively.
Save as config.yaml:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch: {}
exporters:
otlphttp:
endpoint: https://api.24observe.com/api/v1/otlp
compression: gzip
headers:
authorization: "Bearer ${env:OBSERVE24_PAT}"
service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
The otlphttp exporter appends /v1/logs,
/v1/traces, /v1/metrics to the endpoint automatically —
don't add them yourself. The PAT needs the logs:write scope
(plus metrics:write if you ship metrics). Mint one with:
curl -X POST https://api.24observe.com/api/v1/me/tokens \
-H 'Authorization: Bearer obs_<your-existing-admin-token>' \
-H 'Content-Type: application/json' \
-d '{ "name": "collector", "scopes": ["logs:write", "metrics:write"] }' docker run -d --name otelcol \ -e OBSERVE24_PAT=obs_xxxxxxxxxxxxxxxxxxxx \ -v $(pwd)/config.yaml:/etc/otelcol-contrib/config.yaml:ro \ -p 4317:4317 -p 4318:4318 \ otel/opentelemetry-collector-contrib:latest
services:
otelcol:
image: otel/opentelemetry-collector-contrib:latest
environment:
OBSERVE24_PAT: ${OBSERVE24_PAT}
volumes:
- ./config.yaml:/etc/otelcol-contrib/config.yaml:ro
ports:
- "4317:4317"
- "4318:4318"
restart: unless-stopped OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 # gRPC, the default # That's it — no protocol override, no auth headers in your apps. # The collector adds the 24observe PAT on the outbound hop.
This is the zero-config path: every official OTel SDK and every existing
collector deployment exports OTLP/gRPC to localhost:4317 by
default, and this config bridges it to 24observe unchanged.
The collector project ships telemetrygen for exactly this. Send five
test traces through your collector, then check the Logs view:
docker run --rm --network host \ ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest \ traces --otlp-endpoint localhost:4317 --otlp-insecure --traces 5 # Then search: service:telemetrygen (in the dashboard or via the API)
This whole page is tested exactly as written — collector
contrib:latest, gRPC in, gzip out — against the live API.
The contrib image includes receivers for syslog and Fluent Forward; extend the same config:
# Add to the receivers block:
syslog/rfc5424:
tcp:
listen_address: 0.0.0.0:5414
protocol: rfc5424
syslog/rfc3164:
udp:
listen_address: 0.0.0.0:5413
protocol: rfc3164
fluentforward:
endpoint: 0.0.0.0:24224
# And widen the logs pipeline:
# receivers: [otlp, syslog/rfc5424, syslog/rfc3164, fluentforward]
Then point rsyslog at @@collector-host:5414 (RFC5424/TCP) or
Fluent Bit's forward output at port 24224.
compression: gzip is in the config and our API decompresses natively — large log batches typically shrink 20×+ on the wire.partialSuccess response (full histogram support is on the roadmap).gen_ai.*) flowing through this collector get the full treatment: searchable content, cost analytics, and the AI-agent security detection pack.