OpenTelemetry (Tracing)
ZinTrust supports optional OpenTelemetry tracing to enable distributed request traces across services.
Important design choice: the ZinTrust core only depends on @opentelemetry/api and does not ship an SDK or exporter. Your application owns the exporter configuration.
Enable tracing
- Configure an OpenTelemetry SDK + exporter in your app entrypoint (before starting the server).
Example (OTLP over HTTP):
npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-httpimport { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
}),
instrumentations: [getNodeAutoInstrumentations()],
});
await sdk.start();- Enable ZinTrust tracing:
export OTEL_ENABLED=trueWhat ZinTrust records
When enabled, ZinTrust creates spans in the request pipeline and propagates trace context.
Incoming HTTP spans
- A
SpanKind.SERVERspan is created per request. - The span name is updated to
METHOD /route/templatewhen a route is matched. - The span records (best-effort) attributes such as:
http.method,http.target,http.route,http.status_codeservice.name(fromEnv.APP_NAME)zintrust.request_idenduser.idandzintrust.tenant_id(when available on the request context)zintrust.trace_id(late-bound fromRequestContext.traceIdwhen available)
On errors, ZinTrust also records:
zintrust.error(best-effort string attribute)
Implementation lives in:
OpenTelemetry.startHttpServerSpan(...)and friends:src/observability/OpenTelemetry.ts- Request lifecycle wiring:
src/http/Kernel.ts
Outgoing HTTP propagation
ZinTrust injects W3C trace headers (traceparent, tracestate) into outgoing requests made via HttpClient.
This uses the active OpenTelemetry context, so it is most useful when called inside an incoming request span.
Implementation:
src/tools/http/Http.ts
Database spans
ZinTrust records a short-lived db.query span for each DB query when a request span is active (to avoid creating orphan DB traces).
Recorded attributes (best-effort):
db.system(mapped from the configured driver)db.operation(query)zintrust.db.driver
Implementation:
- Hook:
src/orm/Database.ts(after-queryevent) - Span helper:
OpenTelemetry.recordDbQuerySpan(...)insrc/observability/OpenTelemetry.ts
Notes
- Tracing is intentionally best-effort: failures in tracing must never break request handling.
- If
OTEL_ENABLEDis not set, ZinTrust does not create spans or inject headers.