Join us from October 8-10 in New York City to learn the latest tips, trends, and news about GraphQL Federation and API platform engineering.Join us for GraphQL Summit 2024 in NYC
Docs
Start for Free

Spans

Add router lifecycle context to traces


A span captures contextual information about requests and responses as they're processed through the router's request lifecycle (pipeline). The information from spans can be used when displaying traces in your application performance monitors (APM).

Spans configuration

Router request lifecycle services

A 's request lifecycle has three major services:

  • Router service - Handles an incoming request before it is parsed. Works within a context of opaque bytes.
  • Supergraph service - Handles a request after it has been parsed and before it is sent to the . Works within a context.
  • Subgraph service - Handles a request after it has been sent to the subgraph. Works within a GraphQL context.

The router, supergraph and subgraph sections are used to define custom span configuration for each service:

router.yaml
telemetry:
instrumentation:
spans:
router:
attributes: {}
# ...
supergraph:
attributes: {}
# ...
subgraph:
attributes: {}
# ...

attributes

Spans may have attributes attached to them from the router pipeline. These attributes are used to filter and group spans in your APM.

Attributes may be drawn from standard attributes or selectors.

The attributes that are available depend on the service of the pipeline.

desc.router.yaml
telemetry:
instrumentation:
spans:
router:
attributes:
# Standard attributes
http.response.status_code: true
# Custom attributes
"my_attribute":
response_header: "x-my-header"

You can also have conditions on custom attributes using selectors. You can only have conditions on a selector at the same execution level. Example you can't have a condition on response_header if you want to set an attribute from request_header.

desc.router.yaml
telemetry:
instrumentation:
spans:
router:
attributes:
on_error:
response_status: reason
condition:
not:
eq:
- response_status: code
- 200

default_attribute_requirement_level

The default_attribute_requirement_level option sets the default attributes to attach to spans, as defined by OpenTelemetry semantic conventions.

Valid values:

  • required (default)
  • recommended
router.yaml
telemetry:
instrumentation:
spans:
# Set the default requirement level
default_attribute_requirement_level: required

Attributes can be configured individually, so that required attributes can be overridden or disabled. For example, http.response.status_code is set individually to override the standard value:

desc.router.yaml
telemetry:
instrumentation:
spans:
# Set the default requirement level
default_attribute_requirement_level: required
router:
attributes:
# Disable standard attribute
http.response.status_code: false

NOTE

The attributes that the OpenTelemetry spec defines as opt-in must be configured individually.

mode

The mode option enables the router spans to either use legacy attributes in the router, or those defined in the OpenTelemetry specification.

Valid values:

  • spec_compliant
  • deprecated (default)

spec_compliant

This mode follows the OpenTelemetry spec. Attributes that were previously added to spans that did not follow conventions are now removed.

You will likely gain a significant performance improvement by using this mode as it reduces the number of attributes that are added to spans.

router.yaml
telemetry:
instrumentation:
spans:
mode: spec_compliant

For now this is not the default, however it will be in a future release.

deprecated

This mode is the default and follows the previous behavior if you have not configured the mode option to spec_compliant.

router.yaml
telemetry:
instrumentation:
spans:
mode: deprecated

Attributes are added to spans that do not follow OpenTelemetry conventions.

NOTE

The mode option will be defaulted to spec_compliant in a future release, and eventually removed.

Span status

By default spans are marked in error only if the http status code is different than 200. If you want to mark a span in error for other reason you can override the otel.status_code attribute which is responsible to mark a span in error or not. If it's in error then otel.status_code = error, if not it will be ok.

Naming

By default, we will use a span naming convention that aligns with the current semantinc conventions for GraphQL server in OpenTelemetry which means the root span name must be of format <graphql.operation.type> <graphql.operation.name> provided that graphql.operation.type and graphql.operation.name are available.

If you want to change the name of spans we're creating for each services you can override this value by setting the otel.name attribute using any selectors you want.

Here is an example if you want to mark the router and supergraph span in error if you have a error in the payload and you want to enforce the router span name to be graphql_router.

router.yaml
telemetry:
instrumentation:
spans:
router:
attributes:
otel.name:
static: graphql_router # Override the span name to graphql_router
otel.status_code:
static: error
condition:
eq:
- true
- on_graphql_error: true
supergraph:
attributes:
otel.status_code:
static: error
condition:
exists:
response_errors: $[0].extensions.code # Here is an example to get the first error code, `on_graphql_error` is also available for supergraph

Span configuration example

An example configuration of telemetry.spans in router.yaml sets both standard and custom attributes for the router service:

router.yaml
telemetry:
instrumentation:
spans:
default_attribute_requirement_level: required
mode: spec_compliant
router:
attributes:
# Standard attributes (http)
dd.trace_id: false
http.request.body.size: false
http.response.body.size: false
http.request.method: false
# ...
# Conditional custom attribute
otel.status_description: # You can conditionally put a status description attribute on your span if it respect the condition
static: "there was an error"
condition: # http response status code != 200 or it contains a graphql error in the payload
any:
- not:
eq:
- response_status: code
- 200
- eq:
- on_graphql_error
- true
# Custom attributes
"acme.custom_1":
trace_id: datadog
"acme.custom_2":
response_header: "X-CUSTOM2"
default: "unknown"
"acme.custom_3":
env: "ENV_VAR"
"static_attribute":
static: "my_static_value"
# ...
supergraph:
attributes: {}
# ...
subgraph:
attributes: {}
# ...

Spans configuration reference

OptionValuesDefaultDescription
<attribute-name>The name of the custom attribute.
attributesstandard attributes|selectorsThe attributes of the span.
conditionconditionsThe condition for adding a custom attribute.
default_attribute_requirement_levelrequired|recommendedrequiredThe default attribute requirement level.
modespec_compliant | deprecateddeprecatedThe attributes of the span.
Previous
Conditions
Next
Selectors
Rate articleRateEdit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc., d/b/a Apollo GraphQL.

Privacy Policy

Company