Skip to main content
Version: 0.16

OpenTelemetry

OpenTelemetry is an open-source standard for distributed tracing and metrics. It defines a common set of APIs, SDKs, and collector services that applications use to emit traces, logs, and metrics to an observability backend.

Directing Stalwart's traces and logs to an OpenTelemetry collector lets them be correlated with signals from the rest of the infrastructure in a single observability stack, which helps with diagnosing distributed issues and monitoring the health of the mail service.

OpenTelemetry output is represented by two variants of the Tracer object (found in the WebUI under Settings › Telemetry › Tracers): OtelHttp for the HTTP transport and OtelGrpc for the gRPC transport. Both variants share the same set of fields:

  • endpoint: endpoint URL of the collector. Required for OtelHttp; optional for OtelGrpc (when omitted, the SDK default endpoint is used).
  • enableLogExporter: whether logs are exported. Default true.
  • enableSpanExporter: whether spans are exported. Default true.
  • throttle: minimum interval between batches. Default "1s".
  • timeout: maximum time to wait for a response. Default "10s".
  • httpAuth: HTTP authentication used by the exporter. A nested type with variants Unauthenticated, Basic, and Bearer.
  • httpHeaders: additional HTTP headers to include on each request.

The common tracer fields (enable, level, lossy, events, eventsPolicy) also apply.

gRPC transport

The OtelGrpc variant sends traces and logs over gRPC. For example:

{
"@type": "OtelGrpc",
"endpoint": "https://127.0.0.1/otel",
"httpAuth": {"@type": "Unauthenticated"},
"enable": true,
"level": "info"
}

HTTP transport

The OtelHttp variant sends traces and logs over HTTP. Use httpHeaders for any custom headers the collector requires, and httpAuth for bearer or basic credentials. For example:

{
"@type": "OtelHttp",
"endpoint": "https://tracing.mydomain.test/v1/otel",
"httpAuth": {
"@type": "Bearer",
"bearerToken": {"@type": "Value", "secret": "<token>"}
},
"enable": true,
"level": "debug"
}

Authorization tokens are supplied through httpAuth rather than as an Authorization entry in httpHeaders; httpHeaders is reserved for additional custom headers.