Carlquist is OpenTelemetry-native. Every request through the platform generates distributed traces, structured logs, and Prometheus-compatible metrics. Correlation IDs flow end-to-end from adapter query through delivery.
Carlquist propagates W3C Trace Context (traceparent header) on all outbound requests. If your system sends a traceparent header, Carlquist creates child spans under your existing trace. If no trace context is provided, Carlquist generates a root trace automatically.
Every response also includes an X-Request-Id header for correlation in logs and support requests.
Carlquist creates the following span hierarchy for each request flowing through the pipeline:
adapter.query (source system query)
└── mapping.transform (schema transformation)
└── policy.evaluate (auth, rate limit, masking)
└── delivery.send (target delivery)
└── delivery.retry (if needed)
Each span carries structured attributes for filtering and analysis:
adapter.type — Source system type (sqlserver, oracle, rest, etc.)adapter.name — Human-readable adapter namemapping.schema_version — Active schema version for the mappingendpoint.path — API endpoint pathdelivery.target — Target URL or identifierdelivery.status_code — HTTP status code from the targetdelivery.duration_ms — End-to-end delivery time in millisecondsCarlquist exposes Prometheus-compatible metrics. All metrics use the carlquist_ prefix and include labels for filtering and aggregation.
| Metric | Type | Description |
|---|---|---|
carlquist_adapter_query_duration_seconds | histogram | Adapter query latency |
carlquist_adapter_query_total | counter | Total adapter queries (labels: adapter, status) |
carlquist_delivery_duration_seconds | histogram | End-to-end delivery latency |
carlquist_delivery_total | counter | Deliveries (labels: stream, target, status) |
carlquist_delivery_retry_total | counter | Retry attempts (labels: stream, attempt) |
carlquist_dlq_depth | gauge | Current DLQ depth (labels: stream) |
carlquist_mapping_duration_seconds | histogram | Schema transformation time |
carlquist_policy_evaluation_duration_seconds | histogram | Policy check time |
carlquist_endpoint_request_total | counter | API endpoint requests (labels: path, method, status) |
carlquist_endpoint_request_duration_seconds | histogram | API response time |
Example Prometheus query for delivery error rate over the last hour:
rate(carlquist_delivery_total{status!="2xx"}[1h])
/ rate(carlquist_delivery_total[1h])
All Carlquist logs are JSON-formatted with consistent fields across the platform:
{
"timestamp": "2026-02-25T14:32:01.847Z",
"level": "info",
"message": "delivery.success",
"request_id": "req_7f3a9b2c",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"span_id": "00f067aa0ba902b7",
"adapter": "orders-db",
"stream": "orders.created",
"delivery_target": "https://your-app.com/hooks/orders",
"status_code": 200,
"duration_ms": 142
}
Log levels follow standard severity:
Export traces via OTLP/gRPC or OTLP/HTTP to your OpenTelemetry collector:
carlquist config set observability.traces.exporter otlp
carlquist config set observability.traces.endpoint \
https://otel-collector.internal:4317
Metrics are available via a Prometheus scrape endpoint at /metrics (Enterprise plans) or can be pushed to your OTLP endpoint:
carlquist config set observability.metrics.exporter otlp
carlquist config set observability.metrics.endpoint \
https://otel-collector.internal:4317
Logs are written to stdout in containerized deployments. Forward them to your log aggregator (Datadog, Elastic, Splunk) using your container runtime's log driver or a sidecar collector.
Carlquist includes built-in observability views in the dashboard for:
Correlation: Every dashboard view supports filtering by request_id or trace_id, making it straightforward to investigate a single request across traces, metrics, and logs.