Skip to main content

OTLP bridge

If your services already emit OpenTelemetry, add Avuru Obs as an OTLP destination. Keep the instrumentation and validate endpoint, protocol, service identity and ingest authentication before changing the production pipeline.

# OTLP/HTTP
export OTEL_EXPORTER_OTLP_ENDPOINT=http://avuruobs-gateway:4318
# OTLP/gRPC
export OTEL_EXPORTER_OTLP_ENDPOINT=http://avuruobs-gateway:4317
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc

This works for traces, metrics and logs. Spans you export land next to the eBPF-discovered map and share the same service.name resource identity.

Adopt alongside an existing backend​

A sender or collector can export to more than one destination. That does not mean a historical backend can re-export stored telemetry. For tool-specific notes, see Compare.

Senders that do not speak OTLP​

Since v0.6 the gateway also accepts four other push protocols natively, so a fleet that already emits them needs no re-instrumentation to try avuru obs. Each is a single values flag and all are off by default — an install that enables none renders exactly as before.

# Jaeger — collector-compatible ports; senders change the endpoint only.
helm upgrade avuruobs ... --reuse-values --set gateway.receivers.jaeger.enabled=true
# gRPC -> avuruobs-gateway:14250
# thrift over HTTP -> http://avuruobs-gateway:14268/api/traces

# Zipkin — any sender that emits the Zipkin span format.
helm upgrade avuruobs ... --reuse-values --set gateway.receivers.zipkin.enabled=true
# -> http://avuruobs-gateway:9411/api/v2/spans

# Prometheus remote_write — protocol v2 only; needs the infra-metrics module.
helm upgrade avuruobs ... --reuse-values --set gateway.receivers.prometheusRemoteWrite.enabled=true
# prometheus.yml:
# remote_write:
# - url: http://avuruobs-gateway:9291/api/v1/write

# Loki push (Promtail, Alloy, anything that speaks it) — needs the logs module.
# Same port Loki uses, so the sender's hostname is the only edit.
helm upgrade avuruobs ... --reuse-values --set gateway.receivers.loki.enabled=true
# -> http://avuruobs-gateway:3100/loki/api/v1/push

What to know before you point traffic at one:

  • Ingest keys apply identically. Enabled receivers go through the same tenant stage as OTLP, so auth.ingest.mode: enforce and per-project keys behave the same whatever the wire protocol. Senders pass the key as Authorization: Bearer avuruk_…. The one limitation: a legacy sender that cannot set request headers has nowhere to put a key, so under enforce it is rejected — give that environment its own gateway with gateway.tenant set, or keep it on log mode.
  • A receiver follows its signal's module. Remote-write requires infra metrics and Loki push requires logs; enabling one for a signal you do not store is a silent no-op rather than a later surprise.
  • Remote-write is v2 only. A v1 sender is refused with 415 rather than having its samples dropped quietly.
  • Jaeger over UDP is not offered — that transport has no authentication hook, and the agent it belongs to is deprecated upstream.
  • Loki stream labels become log record attributes, not resource identity. A pushed line is found by its body or its attributes; the service filter is backed by service.name, which a Loki push does not carry.
  • Only Service ports are opened. Exposing a receiver publicly needs its own ingress host — in-cluster senders need nothing.

Dual-writing during a migration​

Adopting a backend should be reversible, and evaluating one usually means running both for a while. The gateway can forward everything it ingests to a second destination — your current backend, or a Kafka topic another team owns:

helm upgrade avuruobs ... --reuse-values \
--set gateway.forward.otlp.enabled=true \
--set gateway.forward.otlp.endpoint=old-collector.observability:4317 \
--set gateway.forward.otlp.insecure=true \
--set "gateway.forward.otlp.signals={traces,logs}"

Forwarders always render with a bounded sending queue and retry, so a second backend going down cannot backpressure the write path into storage. Kafka SASL credentials come only from an existing Secret, never inline. A forwarder enabled with no endpoint or brokers fails the render instead of forwarding nowhere.

Validate a reversible rollout​

Start with one test service or collector pipeline. This fragment illustrates trace dual export from an existing OTel Collector; merge it into your current configuration rather than replacing receivers, processors or authentication. Both destinations must accept OTLP/HTTP. Define the two environment variables using your deployment's secret/configuration mechanism.

exporters:
otlphttp/avuru:
endpoint: http://avuruobs-gateway.avuruobs.svc.cluster.local:4318
headers:
Authorization: "Bearer ${env:AVURU_INGEST_KEY}"
sending_queue:
enabled: true
queue_size: 1024
retry_on_failure:
enabled: true
otlphttp/existing:
endpoint: ${env:EXISTING_OTLP_HTTP_ENDPOINT}
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp/existing, otlphttp/avuru]

This is a fragment: the referenced otlp receiver and batch processor must already be defined. Keep any existing authentication and queue settings on the original exporter. Remove the Avuru authorization header only if your ingest mode does not use keys. For logs and metrics, configure and validate their pipelines separately. Do not create a forwarding loop between backends.

Check in both destinations:

  1. Stable service.name, expected project and recent timestamps.
  2. The same test trace ID, span count and parent relationships.
  3. Expected logs/metrics if those signals were enabled; no doubled stdout logs.
  4. Queue health, dropped exports and collector resource use under representative load.

A bounded queue cannot guarantee delivery during a prolonged outage. Decide how much buffering you need and monitor failures. To roll back evaluation, remove only the Avuru exporter from the pipeline, retain the original destination and verify it continues receiving data. Keep the original configuration available.

Historical storage, alert rules, dashboards and access policies are separate migration work. Use the Go integration or the synthetic checkout to validate a first trace.