Docs
Launch GraphOS Studio

API Reference: Usage reporting plugin


Sending metrics from to requires an

. If your organization doesn't currently have an , you can test out this functionality by signing up for a free
Enterprise trial
.

Apollo Server's built-in usage reporting plugin gathers data on how your clients use the and in your . The plugin also handles pushing this usage data to

, as described in
Metrics and logging
.

This plugin is designed to be used in an Apollo Gateway or in a monolithic server; it is not designed to be used from a . In a running , the Apollo Gateway or will send usage reports to Apollo's cloud. Subgraphs don't need to also send usage reports to Apollo's cloud; instead, they send it to the Router via

and the combines execution information across all and sends summarized reports to the cloud.

Default installation

📣 New in Apollo Server 4: error details are not included in traces by default. For more details, see

.

Apollo Server automatically installs and enables this plugin with default settings if you

and your server is not a federated subgraph. You usually do this by setting the APOLLO_KEY and APOLLO_GRAPH_REF (or APOLLO_GRAPH_ID and APOLLO_GRAPH_VARIANT) environment variables. No other action is required.

If you don't provide an API key and , or if your server is a federated subgraph, this plugin is not automatically installed.

If you provide an API key but don't provide a graph ref, a warning is logged. You can

to hide the warning.

If you provide an API key and graph ref but your server is a federated subgraph, a warning is logged. You can

to hide the warning.

Custom installation

If you want to configure the usage reporting plugin, import it and pass it to your ApolloServer constructor's plugins array:

import { ApolloServer } from '@apollo/server';
import { ApolloServerPluginUsageReporting } from '@apollo/server/plugin/usageReporting';
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [
ApolloServerPluginUsageReporting({
fieldLevelInstrumentation: 0.5,
}),
],
});
import { ApolloServer } from '@apollo/server';
import { ApolloServerPluginUsageReporting } from '@apollo/server/plugin/usageReporting';
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [
ApolloServerPluginUsageReporting({
fieldLevelInstrumentation: 0.5,
}),
],
});

While you can install the usage reporting plugin in a server that is a federated subgraph, this is not recommended, and a warning will be logged.

Supported configuration options are listed below.

Options

Name /
Type
Description

Configuring which data is sent to Apollo Studio

sendVariableValues

Object

Provide this object to configure which values are included in trace data that's sent to Apollo Studio. Valid options are described in

.

The default value is { none: true }, which means no variable values are sent to Studio. This is a security measure to prevent sensitive data from potentially reaching .

sendHeaders

Object

Provide this object to configure which request header names and values are included in trace data that's sent to Apollo Studio. Valid options are described in

.

The default value is { none: true }, which means no header names or values are sent to Studio. This is a security measure to prevent sensitive data from potentially reaching Apollo servers.

sendErrors

Object

Provide this object to modify GraphQL errors before Apollo Server reports those errors to Apollo Studio. Valid options are described in

.

The default value is { masked: true }, which means error messages are masked and are omitted in the traces that Apollo Server sends to Apollo Studio. This is a security measure to prevent sensitive data from potentially reaching Apollo servers.

Note: If this ApolloServer instance is acting as the gateway in an

architecture, this option does not modify errors that originate in subgraphs. To modify those errors, instead configure the
includeErrors option in the inline trace plugin
, which you install in the subgraph's ApolloServer instance.

fieldLevelInstrumentation

async Function or number

This option enables you to configure whether Apollo Server calculates detailed per- statistics for each operation. It is used only for operations that reach execution without encountering an error (such as during parsing, validation, or resolving the ). It is not used if you provide an

hook that returns false.

You can provide either a number or an an async function.

If you provide a number, that number must be between 0 and 1, inclusive. This number specifies the probability that Apollo Server calculates per-field statistics for each incoming operation.

For example, if you pass 0.01, then Apollo Server calculates statistics for approximately 1% of operations. When Apollo Server reports these statistics to Apollo Studio, it also provides an "estimation multiplier" of each field's actual number of executions (for example, with a probability of 0.01, the estimation multiplier is 100).

Providing a number x is equivalent to passing this function:

async () => Math.random() < x ? 1/x : 0

If you pass a function, the function is called once for each operation, and it's passed a corresponding GraphQLRequestContext object. The function can return either a boolean or a number. Returning false is equivalent to returning 0, and returning true is equivalent to returning 1.

If the function returns false (or 0):

  • Apollo Server doesn't calculate per-field statistics for the associated operation.
  • The operation doesn't contribute to the "field executions" statistic on the Fields page in Studio, or to the execution timing hints displayed in the Explorer or in VS Code.
  • The operation doesn't produce a trace that can be viewed in the Traces section of the page in Studio.
  • The operation does still contribute to most features of Studio, such as , the Operations page, and the "referencing operations" statistic on the page.

(For more information about the difference between the "referencing operations" and "field executions" statistics, see

.)

Returning false (or 0) for some or all operations can improve your server's performance, because calculating complete traces can introduce significant overhead. This is especially true for a federated , because traces are transmitted from the subgraph to the Gateway in-band inside the actual GraphQL response.

If the function returns a positive number:

  • Apollo Server does calculate per-field statistics for the associated operation, and it sends those statistics to Apollo Studio.
  • Apollo Server sends Studio both an observed execution count and an estimated total execution count for each field.
  • The observed execution count is exactly how many times each field was resolved in the associated operation.
  • The estimated total execution count is the observed execution count, multiplied by the number returned by this function. You can think of this returned number as an "estimation multiplier".

To determine the "estimation multiplier" that the function should return, take the reciprocal of the frequency with which the function returns a non-zero number for the associated operation.

For example, if the function returns a non-zero number one out of every ten times for a particular operation, then the number it returns should be 10. Your function can use different logic for different operations, such as to more frequently report rare operations than common operations.

Note that returning true here does not mean that the data derived from field-level instrumentation must be transmitted to Apollo Studio's servers in the form of a trace. The data can still be aggregated locally to statistics. Either way, this operation contributes to the "field executions" statistic in Studio, along with timing hints.

The default value is a function that always returns true.

includeRequest

async Function

Specify this asynchronous function to configure which requests are included in usage reports sent to Apollo Studio. For example, you can omit requests that execute a particular operation or requests that include a particular HTTP header.

Note that returning false here means that the operation is completely ignored by all Apollo Studio features. If you want to improve performance by skipping the field-level execution trace, set the

option instead of this one.

This function is called for each received request. It takes a

object and must return a Promise<Boolean> that indicates whether to include the request. It's called either after the operation is successfully resolved (via
the didResolveOperation event
), or when sending the final error response if the operation was not successfully resolved (via
the willSendResponse event
).

If you don't want any usage reporting at all, don't use this option: instead, either avoid specifying an Apollo API key or explicitly

.

By default, all requests are included in usage reports.

generateClientInfo

Function

Specify this function to provide Apollo Studio with client details for each processed request. Apollo Studio uses this information to

.

This function is passed a

object containing all available information about the request. It should return an object with clientName and clientVersion fields that identify the associated client.

By default, the plugin attempts to obtain these values from the incoming request's HTTP headers (specifically, apollographql-client-name and apollographql-client-version).

overrideReportedSchema

string

If you're using the overrideReportedSchema option with the

, you should provide the same value for this option. This ensures that the schema ID associated with a request in this plugin's usage reports matches the schema ID that the other plugin reports.

sendUnexecutableOperationDocuments

Boolean

Statistics about operations that your server cannot execute are not reported under each separately to Apollo Studio, but are grouped together as "parse failure", "validation failure", or "unknown operation name". By default, the usage reporting plugin does not include the full operation document in reported traces, because it is challenging to strip potential private information (like string constants) from invalid operations. If you'd like the usage reporting plugin to send the full operation document and operation name so you can view it in Apollo Studio's trace view, set this to true.

Configuring communication protocol

sendReportsImmediately

boolean

If true, the plugin sends a usage report to Apollo Studio after every request instead of sending batched reports. By default, this option is set to false.

This option is useful for stateless environments like Amazon Lambda where processes terminate after handling a small number of requests.

Note that "immediately" does not mean synchronously with completing the response, but rather "very soon", such as after a setImmediate call.

fetcher

typeof fetch

Specifies which

function implementation to use when sending usage reports.

reportIntervalMs

number

The interval at which Apollo Server should send batched trace reports to Studio, in milliseconds.

Regardless of this value, Apollo Server sends a trace report whenever the size of a pending batch exceeds the value of maxUncompressedReportSize (default 4MB).

maxUncompressedReportSize

number

Apollo Server sends a trace report whenever the size of a pending batched trace report exceeds this value (in bytes), regardless of its standard reporting interval.

Note that this is a rough limit that includes the size of serialized traces and signatures. It ignores the size of the report's header and some other top-level bytes.

The default value is 4MB (4194304).

maxAttempts

number

The maximum number of times Apollo Server should attempt to report each trace report, performing exponential backoff between attempts.

The default value is 5.

minimumRetryDelayMs

number

The minimum amount of backoff (in milliseconds) Apollo Server should perform before retrying a failed trace report.

The default value is 100.

requestTimeoutMs

number

Timeout for each individual attempt to send a report to Apollo. (This is for each HTTP POST, not for all potential retries.)

The default value is 30000 (30 seconds).

logger

If you provide this object, the plugin sends it all log messages related to Apollo Studio communication, instead of sending them to the default logger. The object must implement all methods of

.

reportErrorFunction

Function

If you provide this function, the plugin calls it whenever it encounters an error while reporting usage data. The details of the error are passed to the function.

By default, the plugin logs these errors to its specified logger. Unlike the logger, this function receives the actual Error object instead of only an error message.

Internal and non-recommended options

endpointUrl

string

The URL base that the plugin sends reports to (not including the path). This option only needs to be set for testing and Apollo-internal uses.

debugPrintReports

boolean

If set, prints all reports as JSON when they are sent. (Note that for technical reasons, traces embedded in a report are printed separately when they are added to a report.)

calculateSignature

Function

Specify this function to create a signature for a . This option is not recommended, because Apollo's servers make assumptions about how the signature relates to the operation you executed.

Valid sendVariableValues object signatures

ObjectDescription
{ none: true }If you provide this object, no GraphQL variable values are sent to Apollo Studio. This is the default behavior.
{ all: true }If you provide this object, all GraphQL variable values are sent to Apollo Studio.
{ onlyNames: ["apple", "orange"]}If you provide an object with this structure, only values of the GraphQL variables with names that appear in the array are sent to Apollo Studio. To filter individual fields of a variable that contains an input type, use the transform function below instead. Case-sensitive.
{ exceptNames: ["apple", "orange"]}If you provide an object with this structure, all GraphQL variable values except values of the variables with names that appear in the array are sent to Apollo Studio. To filter individual fields of a variable that contains an input type, use the transform function below instead. Case-sensitive.
{ transform: ({ variables, operationString)} => { ... } }

The value of transform is a function that takes the values of all GraphQL for an operation and the operation string. The function returns a new variables map containing values for the operation's variables that should be sent to Apollo Studio. This map does not need to contain all of the operation's variables, but it cannot add variables to the map. You should not mutate variables itself or any of the values contained in it.

For security reasons, if an error occurs in the transform function, all variable values are replaced with [PREDICATE_FUNCTION_ERROR].

Valid sendHeaders object signatures

ObjectDescription
{ none: true }If you provide this object, no request header names or values are sent to Apollo Studio. This is the default behavior.
{ all: true }If you provide this object, all GraphQL header names and values are sent to Apollo Studio, except for the protected headers listed below.
{ onlyNames: ["apple", "orange"]}If you provide an object with this structure, only names and values of the request headers with names that appear in the array are sent to Apollo Studio. Case-insensitive.
{ exceptNames: ["apple", "orange"]}If you provide an object with this structure, all GraphQL header values except values of headers with names that appear in the array are sent to Apollo Studio. Case-insensitive.

Note: Regardless of your configuration, Apollo Server never sends the values of the following headers to Apollo Studio:

  • authorization
  • cookie
  • set-cookie

Valid sendErrors object signatures

ObjectDescription
{ masked: true }

If you provide this object, error messages are masked and extensions omitted in the traces sent to Apollo Studio. This is the default behavior.

{ unmodified: true }

If you provide this object, all error messages and extensions are included in the traces sent to Apollo Studio.

{ transform: (err: GraphQLError) => { GraphQLError | null }}

The value of transform is a function that receives each error (GraphQLError) and must also return a GraphQLError object (or null to prevent Apollo Server from reporting a particular error entirely).

The only properties of the reported error you can modify are its message and its extensions. See

for more details.

Disabling the plugin

If you don't want to install the usage reporting plugin and you are providing an API key to Apollo Server for other purposes, you can disable usage reporting by installing the ApolloServerPluginUsageReportingDisabled plugin, like so:

import { ApolloServer } from '@apollo/server';
import { ApolloServerPluginUsageReportingDisabled } from '@apollo/server/plugin/disabled';
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [ApolloServerPluginUsageReportingDisabled()],
});
import { ApolloServer } from '@apollo/server';
import { ApolloServerPluginUsageReportingDisabled } from '@apollo/server/plugin/disabled';
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [ApolloServerPluginUsageReportingDisabled()],
});

This also disables the warning log if you provide an API key but do not provide a graph ref, or if you provide an API key and graph ref and your server is a federated subgraph.

Previous
Overview
Next
Schema reporting
Edit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc.

Privacy Policy

Company