v1.48.0
Important
If you have enabled Distributed query plan caching, this release has a Federation version bump, which will result in ordinary/expected changes to the hashing algorithm used for the distributed cache keys. On account of this, you should anticipate additional cache regeneration cost when updating to this version while the new hashing algorithm comes into service.
🚀 Features
Demand control preview (PR #5317)
⚠️ This is a preview for an Enterprise feature of the Apollo Router. It requires an organization with a GraphOS Enterprise plan. If your organization doesn't currently have an Enterprise plan, you can test out this functionality with a free Enterprise trial.As a preview feature, it's subject to our Preview launch stage expectations and configuration and performance may change in future releases.
Demand control allows you to control the cost of operations in the router, potentially rejecting requests that are too expensive that could bring down the Router or subgraphs.
# Demand control enabled, but in measure mode.
preview_demand_control:
enabled: true
# `measure` or `enforce` mode. Measure mode will analyze cost of operations but not reject them.
mode: measure
strategy:
# Static estimated strategy has a fixed cost for elements and when set to enforce will reject
# requests that are estimated as too high before any execution takes place.
static_estimated:
# The assumed returned list size for operations. This should be set to the maximum number of items in graphql list
list_size: 10
# The maximum cost of a single operation.
max: 1000
Telemetry is emitted for demand control, including the estimated cost of operations and whether they were rejected or not.
Full details will be included in the documentation for demand control which will be finalized before the next release.
By @BrynCooke in #5317
Ability to include Apollo Studio trace ID on tracing spans (Issue #3803), (Issue #5172)
Add support for a new trace ID selector kind, the apollo
trace ID, which represents the trace ID on Apollo GraphOS Studio.
An example configuration using trace_id: apollo
:
telemetry:
instrumentation:
spans:
router:
"studio.trace.id":
trace_id: apollo
Add ability for router to deal with query plans with contextual rewrites (PR #5097)
Adds the ability for the router to execute query plans with context rewrites. A context is generated by the @fromContext
directive, and each context maps values in the collected data JSON onto a variable that's used as an argument to a field resolver. To learn more, see Saving and referencing data with contexts.
🐛 Fixes
Fix custom attributes for spans and histogram when used with response_event
(PR #5221)
This release fixes multiple issues related to spans and selectors:
- Custom attributes based on response_event in spans are properly added.
- Histograms using response_event selectors are properly updated.
- Static selectors that set a static value are now able to take a Value.
- Static selectors that set a static value are now set at every stage.
- The
on_graphql_error
selector is available on the supergraph stage. - The status of a span can be overridden with the
otel.status_code
attribute.
As an example of using these fixes, the configuration below uses spans with static selectors to mark spans as errors when GraphQL errors occur:
telemetry:
instrumentation:
spans:
router:
attributes:
otel.status_code:
static: error
condition:
eq:
- true
- on_graphql_error: true
supergraph:
attributes:
otel.status_code:
static: error
condition:
eq:
- true
- on_graphql_error: true
Fix instrument incrementing on aborted request when condition is not fulfilled (PR #5215)
Previously when a telemetry instrument was dropped it would be incremented even if the associated condition was not fulfilled. For instance:
telemetry:
instrumentation:
instruments:
router:
http.server.active_requests: false
http.server.request.duration: false
"custom_counter":
description: "count of requests"
type: counter
unit: "unit"
value: unit
# This instrument should not be triggered as the condition is never true
condition:
eq:
- response_header: "never-received"
- static: "true"
In the case where a request was started, but the client aborted the request before the response was sent, the response_header
would never be set to "never-received"
,
and the instrument would not be triggered. However, the instrument would still be incremented.
Conditions are now checked for aborted requests, and the instrument is only incremented if the condition is fulfilled.
By @BrynCooke in #5215
🛠 Maintenance
Send query planner and lifecycle metrics to Apollo (PR #5267, PR #5270)
To enable the performance measurement of the router's new query planner implementation, the router transmits to Apollo the following new metrics:
apollo.router.query_planning.*
provides metrics on the query planner that help improve the query planning implementation.apollo.router.lifecycle.api_schema
provides feedback on the experimental Rust-based API schema generation.apollo.router.lifecycle.license
provides metrics on license expiration that help improve the reliability of the license check mechanism.
These metrics don't leak any sensitive data.
By @BrynCooke in #5267, @goto-bus-stop
📚 Documentation
Add Rhai API constants reference
The Rhai API documentation now includes a list of available constants that are available in the Rhai runtime.
🧪 Experimental
GraphQL instruments (PR #5215, PR #5257)
This PR adds experimental GraphQL instruments to telemetry.
The new instruments are configured in the following:
telemetry:
instrumentation:
instruments:
graphql:
# The number of times a field was executed (counter)
field.execution: true
# The length of list fields (histogram)
list.length: true
# Custom counter of field execution where field name = name
"custom_counter":
description: "count of name field"
type: counter
unit: "unit"
value: field_unit
attributes:
graphql.type.name: true
graphql.field.type: true
graphql.field.name: true
condition:
eq:
- field_name: string
- "name"
# Custom histogram of list lengths for topProducts
"custom_histogram":
description: "histogram of review length"
type: histogram
unit: "unit"
attributes:
graphql.type.name: true
graphql.field.type: true
graphql.field.name: true
value:
field_custom:
list_length: value
condition:
eq:
- field_name: string
- "topProducts"
Using the new instruments consumes significant performance resources from the router. Their performance will be improved in a future release.
Large numbers of metrics may also be generated by using the instruments, so make sure to not incur excessively large APM costs.
⚠ Use these instruments only in development. Don't use them in production.
By @BrynCooke in #5215 and #5257