Skip to content

Commit

Permalink
docs: instrumentation examples (#6487)
Browse files Browse the repository at this point in the history
Co-authored-by: Bryn Cooke <[email protected]>
  • Loading branch information
shorgi and BrynCooke authored Jan 10, 2025
1 parent a80938d commit 553083e
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changesets/docs_eh_instrumentation_examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Add instrumentation configuration examples ([PR #6487](https://github.com/apollographql/router/pull/6487))

The docs for router telemetry have new example configurations for common use cases for [selectors](https://www.apollographql.com/docs/graphos/reference/router/telemetry/instrumentation/selectors) and [condition](https://www.apollographql.com/docs/graphos/reference/router/telemetry/instrumentation/conditions).

By [@shorgi](https://github.com/shorgi) in https://github.com/apollographql/router/pull/6487
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,77 @@ The available basic conditions:
| `any` | A list of conditions of which at least one must be true |

You can create complex conditions by using these basic conditions as building blocks.

## Example condition configurations

Some example configuration of common use cases for conditions.

### Event for a specific subgraph

You can trigger an event for a specific subgraph by configuring a condition with the subgraph's name.

The example below uses the [`subgraph_name`](/router/configuration/telemetry/instrumentation/selectors#subgraph) selector to log subgraph responses for the subgraph named "products":

```yaml title=router.yaml
telemetry:
instrumentation:
events:
subgraph:
response:
level: info
condition:
eq:
- subgraph_name: true
- "products"
```

### On GraphQL error

You can use the [`on_graphql_error`](/router/configuration/telemetry/instrumentation/selectors#supergraph) selector to create a condition based on whether or not a GraphQL error is present.

The example configuration below uses `on_graphql_error` to log only supergraph responses that contain GraphQL errors:

```yaml title="router.yaml"
telemetry:
instrumentation:
events:
router:
request:
level: info
condition: # Only log the router request if you sent `x-log-request` with the value `enabled`
eq:
- request_header: x-log-request
- "enabled"
response: off
error: error
supergraph:
response:
level: info
condition: # Only log supergraph response containing GraphQL errors
eq:
- on_graphql_error: true
- true
error: error
```
### On large payloads
For observability of large payloads, you can set attributes using conditions that indicate whether the length of a request or response exceeds a threshold.
The example below sets a custom attribute to `true` if the length of a request is greater than 100:

```yaml
telemetry:
instrumentation:
spans:
mode: spec_compliant
router:
attributes:
trace_id: true
payload_is_to_big: # Set this attribute to true if the value of content-length header is > than 100
static: true
condition:
gt:
- request_header: "content-length"
- 100
```
141 changes: 124 additions & 17 deletions docs/source/reference/router/telemetry/instrumentation/selectors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ An example of a selector, `request_header`, of the router service on a custom sp
telemetry:
instrumentation:
spans:
mode: spec_compliant
router:
attributes:
"my_attribute":
Expand All @@ -31,17 +32,17 @@ The router service is the initial entrypoint for all requests. It is HTTP centri

| Selector | Defaultable | Values | Description |
|-----------------------|-------------|-----------------------------|----------------------------------------------------------------------|
| `trace_id` | Yes | `open_telemetry`\|`datadog` | The trace ID |
| `operation_name` | Yes | `string`\|`hash` | The operation name from the query |
| `studio_operation_id` | Yes | `true`\|`false` | The Apollo Studio operation id |
| `trace_id` | Yes | `open_telemetry` \| `datadog` | The trace ID |
| `operation_name` | Yes | `string` \| `hash` | The operation name from the query |
| `studio_operation_id` | Yes | `true` \| `false` | The Apollo Studio operation id |
| `request_header` | Yes | | The name of the request header |
| `request_context` | Yes | | The name of a request context key |
| `response_header` | Yes | | The name of a response header |
| `response_status` | Yes | `code`\|`reason` | The response status |
| `response_status` | Yes | `code` \| `reason` | The response status |
| `response_context` | Yes | | The name of a response context key |
| `baggage` | Yes | | The name of a baggage item |
| `env` | Yes | | The name of an environment variable |
| `on_graphql_error` | No | `true`\|`false` | Boolean set to true if the response payload contains a GraphQL error |
| `on_graphql_error` | No | `true` \| `false` | Boolean set to true if the response payload contains a GraphQL error |
| `static` | No | | A static string value |
| `error` | No | `reason` | a string value containing error reason when it's a critical error |

Expand All @@ -51,18 +52,18 @@ The supergraph service is executed after query parsing but before query executio

| Selector | Defaultable | Values | Description |
|--------------------|-------------|-------------------------------------------------------|-----------------------------------------------------------------------------------|
| `operation_name` | Yes | `string`\|`hash` | The operation name from the query |
| `operation_name` | Yes | `string` \| `hash` | The operation name from the query |
| `operation_kind` | No | `string` | The operation kind from the query |
| `query` | Yes | `string`\|`aliases`\|`depth`\|`height`\|`root_fields` | The GraphQL query |
| `query` | Yes | `string` \| `aliases` \| `depth` \| `height` \| `root_fields` | The GraphQL query |
| `query_variable` | Yes | | The name of a GraphQL query variable |
| `request_header` | Yes | | The name of a request header |
| `response_header` | Yes | | The name of a response header |
| `is_primary_response` | No | `true`\|`false` | Boolean returning true if it's the primary response and not events like subscription events or deferred responses |
| `is_primary_response` | No | `true` \| `false` | Boolean returning true if it's the primary response and not events like subscription events or deferred responses |
| `response_data` | Yes | | JSON Path into the supergraph response body data (it might impact performance) |
| `response_errors` | Yes | | JSON Path into the supergraph response body errors (it might impact performance) |
| `request_context` | Yes | | The name of a request context key |
| `response_context` | Yes | | The name of a response context key |
| `on_graphql_error` | No | `true`\|`false` | Boolean set to true if the response payload contains a GraphQL error |
| `on_graphql_error` | No | `true` \| `false` | Boolean set to true if the response payload contains a GraphQL error |
| `baggage` | Yes | | The name of a baggage item |
| `env` | Yes | | The name of an environment variable |
| `static` | No | | A static string value |
Expand All @@ -74,30 +75,30 @@ The subgraph service executes multiple times during query execution, with each e

| Selector | Defaultable | Values | Description |
|-----------------------------|-------------|------------------|--------------------------------------------------------------------------------|
| `subgraph_operation_name` | Yes | `string`\|`hash` | The operation name from the subgraph query |
| `subgraph_operation_name` | Yes | `string` \| `hash` | The operation name from the subgraph query |
| `subgraph_operation_kind` | No | `string` | The operation kind from the subgraph query |
| `subgraph_query` | Yes | `string` | The GraphQL query to the subgraph |
| `subgraph_name` | No | `true`\|`false` | The subgraph name |
| `subgraph_name` | No | `true` \| `false` | The subgraph name |
| `subgraph_query_variable` | Yes | | The name of a subgraph query variable |
| `subgraph_response_data` | Yes | | JSON Path into the subgraph response body data (it might impact performance) |
| `subgraph_response_errors` | Yes | | JSON Path into the subgraph response body errors (it might impact performance) |
| `subgraph_request_header` | Yes | | The name of a subgraph request header |
| `subgraph_response_header` | Yes | | The name of a subgraph response header |
| `subgraph_response_status` | Yes | `code`\|`reason` | The status of a subgraph response |
| `subgraph_on_graphql_error` | No | `true`\|`false` | Boolean set to true if the subgraph response payload contains a GraphQL error |
| `supergraph_operation_name` | Yes | `string`\|`hash` | The operation name from the supergraph query |
| `subgraph_response_status` | Yes | `code` \| `reason` | The status of a subgraph response |
| `subgraph_on_graphql_error` | No | `true` \| `false` | Boolean set to true if the subgraph response payload contains a GraphQL error |
| `supergraph_operation_name` | Yes | `string` \| `hash` | The operation name from the supergraph query |
| `supergraph_operation_kind` | Yes | `string` | The operation kind from the supergraph query |
| `supergraph_query` | Yes | `string` | The graphql query to the supergraph |
| `supergraph_query_variable` | Yes | | The name of a supergraph query variable |
| `supergraph_request_header` | Yes | | The name of a supergraph request header |
| `subgraph_resend_count` | Yes | `true`\|`false` | Number of retries for an http request to a subgraph |
| `subgraph_resend_count` | Yes | `true` \| `false` | Number of retries for an http request to a subgraph |
| `request_context` | Yes | | The name of a request context key |
| `response_context` | Yes | | The name of a response context key |
| `baggage` | Yes | | The name of a baggage item |
| `env` | Yes | | The name of an environment variable |
| `static` | No | | A static string value |
| `error` | No | `reason` | A string value containing error reason when it's a critical error |
| `cache` | No | `hit`\|`miss` | Returns the number of cache hit or miss for this subgraph request |
| `cache` | No | `hit` \| `miss` | Returns the number of cache hit or miss for this subgraph request |

### GraphQL

Expand All @@ -109,5 +110,111 @@ GraphQL metrics are extracted from the response data the router returns to clien
| `field_name` | No | `string` | The name of a field from the response data |
| `field_type` | No | `string` | The type of a field from the response data |
| `type_name` | No | | The GraphQL type from the response data |
| `operation_name` | Yes | `string`\|`hash` | The operation name of the query |
| `operation_name` | Yes | `string` \| `hash` | The operation name of the query |
| `static` | No | | A static string value |


## Example selector configurations

Some example configurations of common use cases for selectors:

### Configuring trace ID

Logging the trace ID of a request that has GraphQL errors:

```yaml title="router.yaml"
telemetry:
instrumentation:
events:
router:
my.event:
message: 'An event occurred'
level: error
on: response
condition:
eq:
- on_graphql_error: true
- true
attributes:
# The trace ID from the request
id_from_header:
trace_id: open_telemetry
```

### Setting JSON paths

Configuring selectors with JSON paths, such as supergraph `response_data` and `response_errors`:

```yaml title="router.yaml"
telemetry:
exporters:
metrics:
prometheus:
enabled: true
instrumentation:
instruments:
supergraph:
my.request.on_graphql_error:
value: event_unit
type: counter
unit: error
description: my description
condition:
exists:
response_errors: "$.[0].extensions.code"
attributes:
response_errors:
response_errors: "$.[0].extensions.code"
```

### Getting GraphQL operation info

Configuring the `query` selector to get information about GraphQL operations, with an example for a custom view of operation limits:

```yaml
telemetry:
exporters:
metrics:
common:
views:
# Define a custom view because operation limits are different than the default latency-oriented view of OpenTelemetry
- name: oplimits.*
aggregation:
histogram:
buckets:
- 0
- 5
- 10
- 25
- 50
- 100
- 500
- 1000
instrumentation:
instruments:
supergraph:
oplimits.aliases:
value:
query: aliases
type: histogram
unit: number
description: "Aliases for an operation"
oplimits.depth:
value:
query: depth
type: histogram
unit: number
description: "Depth for an operation"
oplimits.height:
value:
query: height
type: histogram
unit: number
description: "Height for an operation"
oplimits.root_fields:
value:
query: root_fields
type: histogram
unit: number
description: "Root fields for an operation"
```

0 comments on commit 553083e

Please sign in to comment.