Skip to main content

Telemetry

Gotenberg integrates OpenTelemetry for distributed tracing, metrics export, and structured log shipping. All three signals are configured via standard OTEL environment variables.

Traces

Every HTTP request creates a server span. External tool calls (Chromium, LibreOffice, QPDF, pdfcpu, PDFtk, ExifTool) and outbound HTTP calls (webhooks, download-from) create child spans with client semantics. Trace context propagates to outbound requests via W3C Trace Context headers.

Asynchronous webhook requests stay in the caller's trace. Since 8.34.0, the background work runs under a webhook.Async span that links back to the originating request span, and the webhook delivery spans nest under it instead of starting a new trace. The span covers the whole background delivery, retries included.

Since 8.34.0, traces carry richer detail:

SpanAttributes and events
chromium.Pdf, chromium.Screenshot, libreoffice.PdfEngine version (gotenberg.chromium.version, gotenberg.libreoffice.version), queue depth at arrival (gotenberg.queue.depth_at_arrival), conversions since the last engine restart (gotenberg.conversions_since_last_restart), and on failure a bounded error.type (e.g., timeout, invalid_input, chromium_unavailable, libreoffice_exception).
chromium.Pdf, chromium.ScreenshotPer-conversion network attributes and a chromium.heaviest_resource event with a redacted URL. chromium.Pdf also records gotenberg.conversion.input.files.count, gotenberg.conversion.input.html.bytes, and gotenberg.conversion.output.bytes.
libreoffice.Pdfgotenberg.conversion.input.bytes and gotenberg.conversion.output.bytes.
chromium.queue.wait, libreoffice.queue.waitTime spent waiting for an engine slot.
chromium.process.start, libreoffice.process.startEngine starts and restarts, tagged with gotenberg.process.start.reason (first_start, unhealthy, or max_requests). Restarts triggered by max_requests run in the background, so their spans appear as standalone root traces.
chromium.print_to_pdfChromium's print call.
process.execClient span around every external binary call. PDF engine spans record the backing binary version (gotenberg.qpdf.version, gotenberg.pdftk.version, gotenberg.pdfcpu.version, gotenberg.exiftool.version), captured at image build time.
qpdf.InjectFacturXXMP, qpdf.ReadPdfAConformancegotenberg.facturx.conformance_level and gotenberg.facturx.document_type; gotenberg.pdfa.part and gotenberg.pdfa.conformance.

Configure tracing with standard OTEL environment variables:

Environment variableDescriptionDefault
OTEL_TRACES_EXPORTERTrace exporter. Options: none, otlp, jaeger, zipkin.none
OTEL_EXPORTER_OTLP_ENDPOINTOTLP endpoint for all signals (traces, metrics, logs).None
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTOTLP endpoint specifically for traces. Overrides the generic endpoint.None
OTEL_EXPORTER_OTLP_PROTOCOLOTLP transport protocol. Options: grpc, http/protobuf.grpc
OTEL_EXPORTER_OTLP_HEADERSHeaders to send with OTLP requests (e.g., Authorization=Bearer token).None
OTEL_SERVICE_NAMELogical service name attached to all telemetry.gotenberg
compose.yaml
services:
gotenberg:
image: gotenberg/gotenberg:8
environment:
OTEL_SERVICE_NAME: "gotenberg"
OTEL_TRACES_EXPORTER: "otlp"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-collector:4317"

otel-collector:
image: otel/opentelemetry-collector-contrib
# Configure your collector pipeline as needed.

Sampling

Gotenberg configures no sampler, so the SDK default parentbased_always_on applies: every trace is recorded and exported. Tune sampling with the standard environment variables:

Environment variableDescriptionDefault
OTEL_TRACES_SAMPLERTrace sampler (e.g., parentbased_traceidratio, always_off).parentbased_always_on
OTEL_TRACES_SAMPLER_ARGSampler argument (e.g., 0.1 for a 10% ratio).None

Head sampling drops whole traces up front, including the rare slow or failed conversions that matter most for diagnosis. For high-throughput deployments, keep head sampling permissive and apply tail sampling in the collector, sampling on error or high latency. Since 8.34.0, Gotenberg attaches trace-based exemplars to histograms: as long as some traces are sampled, conversion metrics link to a representative trace.

Metrics

HTTP server metrics (request count, duration, size) follow OTEL semantic conventions. Module-specific metrics (conversion duration, output size, queue size, restarts) are exposed as OTEL observable gauges.

Since 8.34.0, Chromium conversions also record per-conversion network metrics: chromium.network.requests.total (a counter with an outcome label, ok or failed) and chromium.network.bytes (a histogram). LibreOffice counts conversion retries after a crash in libreoffice.conversion.retries.total. Histograms attach trace-based exemplars by default, linking each measurement to a representative trace.

Configure metrics export with standard OTEL environment variables:

Environment variableDescriptionDefault
OTEL_METRICS_EXPORTERMetrics exporter. Options: none, otlp, prometheus.none
OTEL_EXPORTER_OTLP_ENDPOINTOTLP endpoint for all signals (traces, metrics, logs).None
OTEL_EXPORTER_OTLP_METRICS_ENDPOINTOTLP endpoint specifically for metrics. Overrides the generic endpoint.None
OTEL_METRICS_EXEMPLAR_FILTERExemplar filter. Options: trace_based, always_on, always_off.trace_based

Migrating from Prometheus

The Prometheus metrics endpoint is deprecated as of Gotenberg 8.29.0. Replace it with OTEL-based metrics export.

Option 1: OTLP to a Prometheus-compatible backend

Send metrics via OTLP to a collector that writes to Prometheus, Mimir, or any compatible backend:

compose.yaml
services:
gotenberg:
image: gotenberg/gotenberg:8
environment:
OTEL_METRICS_EXPORTER: "otlp"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-collector:4317"

otel-collector:
image: otel/opentelemetry-collector-contrib
volumes:
- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317

exporters:
prometheusremotewrite:
endpoint: "http://prometheus:9090/api/v1/write"

service:
pipelines:
metrics:
receivers: [otlp]
exporters: [prometheusremotewrite]

Option 2: Built-in Prometheus exporter

Expose a Prometheus-compatible scrape endpoint directly from Gotenberg via the OTEL SDK. By default, metrics are served at localhost:9464/metrics.

compose.yaml
services:
gotenberg:
image: gotenberg/gotenberg:8
ports:
- "3000:3000"
- "9464:9464"
environment:
OTEL_METRICS_EXPORTER: "prometheus"
# Required when Prometheus scrapes from another container or host:
# the exporter binds localhost by default.
OTEL_EXPORTER_PROMETHEUS_HOST: "0.0.0.0"
# Optional: customize the port.
# OTEL_EXPORTER_PROMETHEUS_PORT: "9464"

prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
prometheus.yml
scrape_configs:
- job_name: "gotenberg"
scrape_interval: 10s
static_configs:
- targets: ["gotenberg:9464"]

This is separate from the legacy /prometheus/metrics route and does not require the Prometheus module flags.

Logs

Gotenberg uses slog-based structured logging. An OTEL log bridge exports logs to configured OTEL backends alongside stdout output.

Configure log export with standard OTEL environment variables:

Environment variableDescriptionDefault
OTEL_LOGS_EXPORTERLogs exporter. Options: none, otlp.none
OTEL_EXPORTER_OTLP_ENDPOINTOTLP endpoint for all signals (traces, metrics, logs).None
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTOTLP endpoint specifically for logs. Overrides the generic endpoint.None

Stdout Configuration

The following flags control stdout log output. See the Logging configuration for the full list.

FlagEnvironment variableDescriptionDefault
--log-std-formatLOG_STD_FORMATSpecify the format of logging. Options: auto, json, text.auto
--log-std-enable-gcp-fieldsLOG_STD_ENABLE_GCP_FIELDSUse GCP-compatible field names (time, message, severity).false
warning

As of Gotenberg 8.29.0, --log-format has been deprecated in favor of --log-std-format, and --log-enable-gcp-fields has been deprecated in favor of --log-std-enable-gcp-fields.

Telemetry Control

Telemetry (traces, metrics, logs) on high-frequency system routes is disabled by default to reduce noise. Set these flags to false to re-enable it.

FlagEnvironment variableDescriptionDefault
--api-disable-root-route-telemetryAPI_DISABLE_ROOT_ROUTE_TELEMETRYDisable telemetry for the root route.true
--api-disable-debug-route-telemetryAPI_DISABLE_DEBUG_ROUTE_TELEMETRYDisable telemetry for the debug route.true
--api-disable-version-route-telemetryAPI_DISABLE_VERSION_ROUTE_TELEMETRYDisable telemetry for the version route.true
--api-disable-health-check-route-telemetryAPI_DISABLE_HEALTH_CHECK_ROUTE_TELEMETRYDisable telemetry for the health check route.true
--prometheus-disable-route-telemetryPROMETHEUS_DISABLE_ROUTE_TELEMETRYDisable telemetry for the Prometheus metrics route.true
warning

As of Gotenberg 8.29.0, --api-trace-header has been deprecated in favor of --api-correlation-id-header, and --api-disable-health-check-logging has been deprecated in favor of --api-disable-health-check-route-telemetry.

Example

A complete Docker Compose setup with Gotenberg exporting traces, metrics, and logs to an OTEL Collector:

compose.yaml
services:
gotenberg:
image: gotenberg/gotenberg:8
ports:
- "3000:3000"
environment:
OTEL_SERVICE_NAME: "gotenberg"
OTEL_TRACES_EXPORTER: "otlp"
OTEL_METRICS_EXPORTER: "otlp"
OTEL_LOGS_EXPORTER: "otlp"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-collector:4317"

otel-collector:
image: otel/opentelemetry-collector-contrib
ports:
- "4317:4317"
volumes:
- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317

exporters:
# Replace with your preferred backend (Jaeger, Grafana Cloud, Datadog, etc.).
debug:
verbosity: detailed

service:
pipelines:
traces:
receivers: [otlp]
exporters: [debug]
metrics:
receivers: [otlp]
exporters: [debug]
logs:
receivers: [otlp]
exporters: [debug]

What's Next?

Tune the instance in Configuration, or work through common issues in Troubleshooting.