UNPKG

@graphql-hive/plugin-opentelemetry

Version:
203 lines (199 loc) • 7.47 kB
import { GatewayConfigContext, GatewayPlugin } from '@graphql-hive/gateway-runtime'; import { ExecutionRequest } from '@graphql-tools/utils'; import { Tracer, Context } from '@opentelemetry/api'; import { DocumentNode, GraphQLSchema } from 'graphql'; type OperationHashingFn = (input: { document: DocumentNode; operationName?: string | null; variableValues?: Record<string, unknown> | null; schema: GraphQLSchema; }) => string | null; type BooleanOrPredicate<TInput = never> = boolean | ((input: TInput) => boolean); type OpenTelemetryGatewayPluginOptions = { /** * Whether to rely on OTEL context api for span correlation. * - `true`: the plugin will rely on OTEL context manager for span parenting. * - `false`: the plugin will rely on request context for span parenting, * which implies that parenting with user defined may be broken. * * By default, it is enabled if the registered Context Manager is compatible with async calls, * or if it is possible to register an `AsyncLocalStorageContextManager`. * * Note: If `true`, an error is thrown if it fails to obtain an async calls compatible Context Manager. */ useContextManager?: boolean; /** * Whether to inherit the context from the calling service (default: true). * * This process is done by extracting the context from the incoming request headers. If disabled, a new context and a trace-id will be created. * * See https://opentelemetry.io/docs/languages/js/propagation/ */ inheritContext?: boolean; /** * Whether to propagate the context to the outgoing requests (default: true). * * This process is done by injecting the context into the outgoing request headers. If disabled, the context will not be propagated. * * See https://opentelemetry.io/docs/languages/js/propagation/ */ propagateContext?: boolean; /** * The TraceProvider method to call on Gateway's disposal. By default, it tries to run `forceFlush` method on * the registered trace provider if it exists. * Set to `false` to disable this behavior. * @default 'forceFlush' */ flushOnDispose?: string | false; /** * Function to be used to compute the hash of each operation (graphql.operation.hash attribute). * Note: pass `null` to disable operation hashing * * @default `hashOperation` from @graphql-hive/core */ hashOperation?: OperationHashingFn | null; /** * Tracing configuration */ traces?: boolean | TracesConfig; }; type TracesConfig = { /** * Tracer instance to use for creating spans (default: a tracer with name 'gateway'). */ tracer?: Tracer; /** * Options to control which spans to create. * By default, all spans are enabled. * * You may specify a boolean value to enable/disable all spans, or a function to dynamically enable/disable spans based on the input. */ spans?: SpansConfig; events?: { /** * Enable/Disable cache related span events (default: true). */ cache?: BooleanOrPredicate<{ key: string; action: 'read' | 'write'; }>; }; }; type SpansConfig = { /** * Enable/disable HTTP request spans (default: true). * * Disabling the HTTP span will also disable all other child spans. */ http?: BooleanOrPredicate<{ request: Request; ignoredRequests: WeakSet<Request>; }>; /** * Enable/disable GraphQL operation spans (default: true). * * Disabling the GraphQL operation spa will also disable all other child spans. */ graphql?: BooleanOrPredicate<{ context: unknown; }>; /** * Enable/disable GraphQL context building phase (default: true). */ graphqlContextBuilding?: BooleanOrPredicate<{ context: unknown; }>; /** * Enable/disable GraphQL parse spans (default: true). */ graphqlParse?: BooleanOrPredicate<{ context: unknown; }>; /** * Enable/disable GraphQL validate spans (default: true). */ graphqlValidate?: BooleanOrPredicate<{ context: unknown; }>; /** * Enable/disable GraphQL execute spans (default: true). * * Disabling the GraphQL execute spans will also disable all other child spans. */ graphqlExecute?: BooleanOrPredicate<{ context: unknown; }>; /** * Enable/disable subgraph execute spans (default: true). * * Disabling the subgraph execute spans will also disable all other child spans. */ subgraphExecute?: BooleanOrPredicate<{ executionRequest: ExecutionRequest; subgraphName: string; }>; /** * Enable/disable upstream HTTP fetch calls spans (default: true). */ upstreamFetch?: BooleanOrPredicate<{ executionRequest: ExecutionRequest | undefined; }>; /** * Enable/disable schema loading spans (default: true if context manager available). * * Note: This span requires an Async compatible context manager */ schema?: boolean; /** * Enable/disable initialization span (default: true). */ initialization?: boolean; }; type ContextMatcher = { request?: Request; context?: any; executionRequest?: ExecutionRequest; }; type OpenTelemetryPluginUtils = { tracer: Tracer; /** * Returns the current active OTEL context. * * Note: Defaults to `otel.context.active()` if no plugin is registered. */ getActiveContext: (payload: ContextMatcher) => Context; /** * Returns the http request root span context. * Returns `undefined` if the current request is not being traced. * * Note: Defaults to `otel.context.active()` if no plugin is registered. */ getHttpContext: (request: Request) => Context | undefined; /** * Returns the current GraphQL operation root span context. * Returns `undefined` if the current GraphQL operation is not being traced. * * Note: Defaults to `otel.context.active()` if no plugin is registered. */ getOperationContext: (context: any) => Context | undefined; /** * Returns the current subgraph Execution Request root span context. * Returns `undefined` if the current subgraph Execution Request is not being traced. * * Note: Defaults to `otel.context.active()` if no plugin is registered. */ getExecutionRequestContext: (ExecutionRequest: ExecutionRequest) => Context | undefined; ignoreRequest: (request: Request) => void; }; type OpenTelemetryContextExtension = { openTelemetry: { tracer: Tracer; getActiveContext: (payload?: ContextMatcher) => Context; getHttpContext: (request?: Request) => Context | undefined; getOperationContext: (context?: any) => Context | undefined; getExecutionRequestContext: (ExecutionRequest: ExecutionRequest) => Context | undefined; }; }; type OpenTelemetryPlugin = GatewayPlugin<OpenTelemetryContextExtension> & OpenTelemetryPluginUtils; declare function useOpenTelemetry(options: OpenTelemetryGatewayPluginOptions & Partial<GatewayConfigContext>): OpenTelemetryPlugin; export { type OpenTelemetryContextExtension as O, type OpenTelemetryGatewayPluginOptions as a, type OpenTelemetryPlugin as b, type OpenTelemetryPluginUtils as c, useOpenTelemetry as u };