Skip to content

Spans

Span capture, per-trace span viewing, span deletion, and the HTTP span diagnostic command are provided by the native_observability_spans submodule. It is part of the RAW install tier; enable it with drush no:preset:raw, or directly with drush en native_observability_spans -y.

Routes

Route Path Permission
native_observability_spans.trace_spans /admin/reports/native-observability/traces/{id}/spans view native observability traces
native_observability_spans.trace_spans_delete /admin/reports/native-observability/trace/{id}/spans/delete administer native observability traces
native_observability_spans.spans_delete_all /admin/reports/native-observability/spans/delete-all administer native observability traces

The permission administer native observability traces is required by both delete routes but is not declared in any *.permissions.yml file in the codebase, so it cannot be assigned to a role through the standard Permissions UI. In practice only user 1 (which bypasses permission checks) can reach these two forms until this permission is added to a .permissions.yml file.

Span capture

Spans record timed units of work inside a request. They are written through SpanRecorderInterface::startSpan() / endSpan(), and correlated to a trace by request_id. Three sources feed the span table:

  • Outbound HTTP calls. GuzzleSpanMiddleware is pushed onto the shared Guzzle handler stack (tagged http_client_middleware), so every outbound request made through Drupal's http_client produces a span under the http.client category. Callers can pass a native_observability request option with a subtype and/or name to get a more specific category (http.client.<subtype>) and a custom span name. A call made from cron or from drush produces a span too, with no request id, because no HTTP request is behind it. Those spans carry no trace either, so they never appear under a single trace, but they are counted in the Response Time breakdown on the Overview tab. That is how an outbound call started from the command line shows up at all.
  • Request summary. RequestSummarySpanSubscriber writes one synthetic HTTP request summary span per response, enriched through tagged RequestSummaryEnrichmentProviderInterface providers contributed by other modules.
  • Database summary. DatabaseSummarySpanSubscriber optionally writes one synthetic database summary span per response when native_observability_database_observer is enabled. It has no hard dependency on that module: if it is absent, span capture continues without it.

Viewing spans for a trace

Open a trace detail page and follow through to /admin/reports/native-observability/traces/{id}/spans, or navigate there directly with the trace's numeric ID. TraceSpansController::build() loads the trace, then loads its spans by request_id (falling back to loadByTraceId() when no request-ID match exists), and renders a table with span ID, parent span ID, name, category, duration, start and end timestamps.

The page exposes two actions: Back to trace and Delete spans.

Deleting spans

For a single trace

/admin/reports/native-observability/trace/{id}/spans/delete opens DeleteTraceSpansForm. It loads the trace, resolves its request_id, and on confirmation deletes every span matching that request_id via SpanStorageInterface::deleteByRequestId(). It redirects back to the trace detail page.

All spans

/admin/reports/native-observability/spans/delete-all opens DeleteAllSpansForm, which deletes every stored span via SpanStorageInterface::deleteAll(). Confirming or cancelling returns to the trace listing. Spans have no listing of their own, and nothing in the interface links to this route, so reaching it means typing the URL.

Drush: HTTP span diagnostic

native-observability-span:http-test (alias nos:http-test) drives a fixed set of outbound HTTP requests through Drupal's global http_client service to verify that span generation is wired up correctly. It is a diagnostic tool, not a data source: it does not read or write trace data directly, it only exercises the same code path outbound application traffic uses.

drush native-observability-span:http-test
drush nos:http-test --timeout=15 --connect-timeout=5

Options:

  • --timeout: request timeout in seconds. Defaults to 8.
  • --connect-timeout: connection timeout in seconds. Defaults to 4.

The command calls five targets (a 200 response, a 204 response, a 200 and a 503 from httpbin, and one request to a domain designed to fail DNS resolution) and prints a table with status code, error, and a truncated response body for each. Check /admin/reports/native-observability/execution or the spans list of a fresh trace afterward to confirm each call produced an http.client span.