Skip to content

Span reference

All spans emitted by the gateway and relay. Every span carries the service.name resource attribute (gatewai/gateway or gatewai/relay) and inherits service.version from the binary build version.

W3C TraceContext propagation is enabled globally. Incoming HTTP requests extract a parent span from the traceparent header; the relay continues the trace via the trace_context field in the Redis job record.

gateway.http.server — HTTP server (middleware)

Section titled “gateway.http.server — HTTP server (middleware)”

Created for every incoming HTTP request by OtelMiddleware.

AttributeTypeValue
http.methodstringGET, POST, …
http.routestringchi route pattern, e.g. /jobs/{service_type}
http.status_codeintresponse status
net.host.namestringHost header value

Span kind: Server. Status set to Error when http.status_code >= 500.


gateway.job.submit — async job submission

Section titled “gateway.job.submit — async job submission”

Created inside POST /jobs/{service_type} after rate-limit checks pass and the file is uploaded to S3. This is the root span for the async job lifecycle — its traceparent is stored in job.trace_context so the relay can continue the trace.

AttributeTypeValue
job_idstringUUID of the created job
service_typestringe.g. audio, llm
modelstringresolved model name
consumerstringvalue of server.consumer_header

AttributeTypeValue
s3.operationstringupload
s3.keystringobject key, e.g. {job_id}/input.wav

AttributeTypeValue
s3.operationstringget
s3.keystringobject key

AttributeTypeValue
s3.operationstringdelete
s3.keystringobject key

gateway.redis.enqueue — Redis queue enqueue

Section titled “gateway.redis.enqueue — Redis queue enqueue”

Created inside SaveJob when the job record is written and pushed onto relay:{model}:pending.

AttributeTypeValue
job_idstringUUID
service_typestring
modelstring
queuestringrelay:{model}:pending

Created for every LLM proxy request (POST /v1/* with a configured provider).

AttributeTypeValue
service_typestring
modelstringalias model name
providerstringopenai, anthropic, ollama, passthrough
consumerstring
http.status_codeintfinal response status (set after response)
llm.backend_modelstringrewritten model name sent to the backend

Status set to Error on backend failure or translation error.


gateway.consumer.job_completed — async job completion

Section titled “gateway.consumer.job_completed — async job completion”

Created by the Redis pub/sub subscriber when a job completion notification is received on jobs:{model}:completed.

AttributeTypeValue
job_idstring
modelstring

Created by WebhookSender.Send. Restores the original trace context from job.trace_context so this span appears as a child of the original submit span in the same trace.

AttributeTypeValue
job_idstring
service_typestring
job_statusstringcompleted or failed

Status set to Error after all retries are exhausted.


Root span for relay processing. Extracts the gateway’s trace context from job.trace_context so this span becomes a child of gateway.job.submit in the same distributed trace.

AttributeTypeValue
job_idstring
service_typestring
modelstring

Child spans: relay.inference_call.


relay.inference_call — HTTP call to inference API

Section titled “relay.inference_call — HTTP call to inference API”

Created inside runInference. After building the multipart request, the relay injects the active traceparent as a W3C HTTP header — the inference API can create child spans if it is OTel-instrumented.

AttributeTypeValue
job_idstring
modelstring
inference_urlstringpath appended to inference.base_url, e.g. /v1/audio/transcriptions

Status set to Error on inference failure. Retried once; both attempts appear as separate spans under relay.process_job.


Client request
│
│ HTTP (traceparent header optional — extracted by OtelMiddleware)
▼
[gateway.http.server] ← SpanKind: Server
└─ [gateway.job.submit] ← job.trace_context = traceparent stored in Redis
├─ [gateway.s3.upload]
└─ [gateway.redis.enqueue]
┊ (async, via Redis queue)
[relay.process_job] ← context restored from job.trace_context
└─ [relay.inference_call] ← traceparent injected in HTTP header
│
│ HTTP (traceparent header → inference API)
▼
Inference API (optional child spans)
┊ (async, via Redis pub/sub)
[gateway.consumer.job_completed]
└─ [gateway.webhook.send] ← context restored from job.trace_context

Common queries for the GatewAI — Traces dashboard or Grafana Explore.

# All GatewAI spans in the last hour
{service.name=~"gatewai.*"}
# Slow job submissions (> 500ms total)
{span.name="gateway.job.submit", duration > 500ms}
# Error traces only
{status=error, service.name=~"gatewai.*"}
# Full end-to-end trace for a specific job
{span.job_id="<job-uuid>"}
# Slow inference calls (> 30s)
{span.name="relay.inference_call", duration > 30s}
# Failed webhook deliveries
{span.name="gateway.webhook.send", status=error}
# LLM requests by backend model
{span.name="gateway.llm.request"} | select(span.llm.backend_model, duration, status)

With Tempo 2.3+ you can derive rate, error, and duration metrics directly from traces without a separate metrics pipeline:

# Request rate per service
{service.name=~"gatewai.*"} | rate() by(resource.service.name)
# Error rate
{status=error, service.name=~"gatewai.*"} | rate()
# p95 duration per operation
{service.name=~"gatewai.*"} | quantile_over_time(duration, 0.95) by(span.name)

These queries power the RED — Métriques par opération row in gatewai-traces-v1.