Sending KrakenD telemetry to Sluicio (Community Edition)
Get OpenTelemetry traces and metrics from the open-source KrakenD API gateway into Sluicio by placing an OpenTelemetry Collector in between to attach the ingest key — with verified KrakenD and Collector configuration.
KrakenD is an open-source API gateway with built-in OpenTelemetry. This guide gets its traces and metrics into Sluicio.
The constraint that shapes everything: KrakenD Community Edition’s OTLP exporter cannot attach authentication headers, and Sluicio’s ingest requires an ingest key on any production cell. So instead of exporting straight to Sluicio, you send KrakenD’s telemetry to an OpenTelemetry Collector that adds the key and forwards it on:
KrakenD → OpenTelemetry Collector → Sluicio ingest (attaches the ingest key)The Collector is a small, stateless hop. It’s also the natural place to batch, add metadata, or fan out to other backends later.
Prerequisites
Section titled “Prerequisites”- KrakenD ≥ 2.8. Plaintext export to a local Collector isn’t possible on ≤ 2.7; these instructions were verified against 2.13.8. Use the official
docker.io/library/krakendimage — the olderdevopsfaith/krakendimage is deprecated and stale. - A running Sluicio cell and admin access to mint an ingest key.
- Docker with the Compose plugin (the examples wire the pieces together with Compose).
1 · Mint a Sluicio ingest key
Section titled “1 · Mint a Sluicio ingest key”Ingest keys are per-organisation and admin-only. In Sluicio, open Settings → Ingestion, create a key, and copy it — the value is shown once. The same screen shows your cell’s ingest URL (e.g. https://<your-cell>-ingest.example.com); you’ll need both.
2 · Configure the OpenTelemetry Collector
Section titled “2 · Configure the OpenTelemetry Collector”The Collector receives OTLP from KrakenD, batches it, and forwards it to Sluicio with the ingest key attached. The core otel/opentelemetry-collector image is enough — no contrib build is needed.
# Receives OTLP from KrakenD, batches, and forwards to Sluicio with the# ingest key attached.receivers: otlp: protocols: http: endpoint: 0.0.0.0:4318 grpc: endpoint: 0.0.0.0:4317 # optional — for other gRPC-only emitters
processors: batch: send_batch_size: 512 timeout: 5s
exporters: otlphttp: # The cell's ingest base URL (Settings → Ingestion). The exporter # appends /v1/traces, /v1/metrics, /v1/logs itself. endpoint: https://<your-cell>-ingest.example.com headers: Authorization: "Bearer ${env:SLUICIO_INGEST_KEY}"
service: pipelines: traces: receivers: [otlp] processors: [batch] exporters: [otlphttp] metrics: receivers: [otlp] processors: [batch] exporters: [otlphttp] logs: receivers: [otlp] processors: [batch] exporters: [otlphttp]A few things worth calling out:
otlphttp, nototlp. Sluicio ingests OTLP over HTTP/protobuf only — there is no gRPC ingest — so the exporter must beotlphttp. It appends/v1/traces,/v1/metricsand/v1/logstoendpointfor you.endpointis your cell’s ingest base URL from Settings → Ingestion.- The key travels in the
Authorizationheader asBearer ${env:SLUICIO_INGEST_KEY}. Sluicio also acceptsX-Sluicio-Ingest-Key: <key>if you prefer. - The gRPC receiver on
4317is optional — useful if other gRPC-only emitters share this Collector. KrakenD uses the HTTP receiver on4318.
3 · Configure KrakenD
Section titled “3 · Configure KrakenD”KrakenD’s OpenTelemetry lives under extra_config.telemetry/opentelemetry. Add this to your krakend.json (alongside version, endpoints, …) and point its otlp exporter at the Collector by its network name:
"extra_config": { "telemetry/opentelemetry": { "service_name": "krakend-gateway", "metric_reporting_period": 30, "trace_sample_rate": 1, "exporters": { "otlp": [ { "name": "collector", "host": "http://otel-collector", "port": 4318, "use_http": true } ] }, "layers": { "global": { "report_headers": true }, "proxy": { "report_headers": true }, "backend": { "metrics": { "detailed_connection": true, "read_payload": true, "round_trip": true }, "traces": { "report_headers": true, "read_payload": true, "round_trip": true } } } }}The report_headers / read_payload / round_trip flags enrich the spans with headers, payloads and backend round-trips. Turn them down if you’d rather not capture headers or payloads in traces.
4 · Wire it together (Docker Compose)
Section titled “4 · Wire it together (Docker Compose)”services: krakend: image: docker.io/library/krakend:2.13.8 command: ["run", "-c", "/etc/krakend/krakend.json"] volumes: - ./krakend.json:/etc/krakend/krakend.json:ro ports: - "8080:8080" # the gateway depends_on: - otel-collector
otel-collector: image: otel/opentelemetry-collector:latest command: ["--config=/etc/otelcol/config.yaml"] volumes: - ./otel-collector-config.yaml:/etc/otelcol/config.yaml:ro environment: # fails fast if unset — never inline the key SLUICIO_INGEST_KEY: ${SLUICIO_INGEST_KEY:?set SLUICIO_INGEST_KEY in your environment}
# add your backend services here; KrakenD routes requests to themThen start it with the key in your environment:
export SLUICIO_INGEST_KEY="<the key you copied>"docker compose up -dSend a request through the gateway (http://localhost:8080/…) and, within a few seconds, a krakend-gateway service appears in Sluicio.
What you’ll see in Sluicio
Section titled “What you’ll see in Sluicio”- One service named after
service_name— here,krakend-gateway. - Roughly five spans per gateway request:
- a Server span for the inbound request (with headers when
report_headersis on), - an Internal span per endpoint pipe, carrying
http.route, - Internal + Client spans per backend call — an aggregation endpoint shows several Client spans under one Server span,
- a payload-read tracker span carrying
krakend.endpoint.route/krakend.endpoint.method.
- a Server span for the inbound request (with headers when
- Metrics: the
http.client.*family — duration, request and response sizes, and DNS / TLS / connection timings — reported everymetric_reporting_periodseconds (30s above).
Making gateway 5xx count as errors
Section titled “Making gateway 5xx count as errors”KrakenD records a failed backend request only as the span attribute http.response.status_code: 500 and leaves the OpenTelemetry span status at Ok/Unset — a deviation from the OpenTelemetry semantic conventions, which say a server span should carry status Error on a 5xx. Because Sluicio derives trace errors from span status, an unconfigured cell shows a KrakenD gateway as healthy even while it returns 500s.
The fix: “Treat HTTP 5xx as errors”
Section titled “The fix: “Treat HTTP 5xx as errors””Sluicio v0.11.15 and later has a first-class setting for exactly this.
- Where — Settings → System → General → “Treat HTTP 5xx as errors” (organization admins only; the change is audited). It’s off by default: enabling it is a deliberate choice, because error counts will visibly increase for affected services.
- What it does — at ingest, any span carrying an HTTP 5xx status attribute (
http.response.status_code, or the legacyhttp.status_code) whose span status isn’t alreadyErroris stored as an error span. Sluicio stamps these withsluicio.status_mapped: trueand an explanatory status message, so a mapped error is always distinguishable from one the instrumentation reported natively. - Effect — gateway failures then count everywhere span status counts: service and integration health, error counts, the Errors tab, and failed-trace alert rules — with no further configuration.
Worth knowing:
- It applies to newly ingested spans only — anything stored before you enable it keeps its original status — and takes effect within about 30 seconds of saving (an ingest-side cache).
- Spans already marked
Errorare never modified. - The setting travels with configuration export/import, so it carries from a staging cell to production with the rest of your org config.
- It isn’t KrakenD-specific: it normalizes any emitter that reports an HTTP 5xx only as an attribute.
Complementary: attribute conditions on failed-trace alerts
Section titled “Complementary: attribute conditions on failed-trace alerts”Failed-trace alert rules also accept attribute conditions — the same operator vocabulary as log rules — which is useful with a gateway beyond the 5xx case. For example, you can have a rule fire only for failed traces where http.route = /checkout, or scope it with http.response.status_code ≥ 500. It’s in the alert drawer (“Only count error spans where…”) and via the API (trace_error_spec.attrs). This complements the setting rather than replacing it.
Troubleshooting
Section titled “Troubleshooting”http: server gave HTTP response to HTTPS clientin the KrakenD logs — the exporter is attempting TLS. Add thehttp://scheme tohostand setuse_http: true(KrakenD ≥ 2.8).401in the Collector logs — the ingest key is missing or wrong. CheckSLUICIO_INGEST_KEYand the exporter’sAuthorizationheader.415from Sluicio — something is sending JSON or gRPC. The Collector must export withotlphttp(protobuf), which it does by default.- Nothing arrives — confirm KrakenD can resolve
otel-collector:4318on the Compose network, and that the Collector’sendpointis your real ingest URL from Settings → Ingestion.
Where to go next
Section titled “Where to go next”- Point the Collector at Sluicio — the general Collector → Sluicio reference (auth headers, signal paths, giving each source a
service.name). - What you get from your telemetry — what Sluicio does with these traces and metrics once they arrive.