@graphql-yoga/plugin-apollo-usage-report 0.13.0 → 0.13.1-alpha-20260116132159-d18a95d04a1e11d197fdf672a8be4836ceed0818

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,122 +0,0 @@
1
- import { YogaLogger, YogaServer, type Maybe, type Plugin, type YogaInitialContext } from 'graphql-yoga';
2
- import { calculateReferencedFieldsByType } from '@apollo/utils.usagereporting';
3
- import { ApolloInlineGraphqlTraceContext, ApolloInlineRequestTraceContext, ApolloInlineTracePluginOptions } from '@graphql-yoga/plugin-apollo-inline-trace';
4
- import { Reporter } from './reporter.js';
5
- export type ApolloUsageReportOptions = ApolloInlineTracePluginOptions & {
6
- /**
7
- * The graph ref of the managed federation graph.
8
- * It is composed of the graph ID and the variant (`<YOUR_GRAPH_ID>@<VARIANT>`).
9
- *
10
- * If not provided, `APOLLO_GRAPH_REF` environment variable is used.
11
- *
12
- * You can find a a graph's ref at the top of its Schema Reference page in Apollo Studio.
13
- */
14
- graphRef?: string;
15
- /**
16
- * The API key to use to authenticate with the managed federation up link.
17
- * It needs at least the `service:read` permission.
18
- *
19
- * If not provided, `APOLLO_KEY` environment variable will be used instead.
20
- *
21
- * [Learn how to create an API key](https://www.apollographql.com/docs/federation/v1/managed-federation/setup#4-connect-the-gateway-to-studio)
22
- */
23
- apiKey?: string;
24
- /**
25
- * Usage report endpoint
26
- *
27
- * Defaults to GraphOS endpoint (https://usage-reporting.api.apollographql.com/api/ingress/traces)
28
- */
29
- endpoint?: string;
30
- /**
31
- * Agent Version to report to the usage reporting API
32
- */
33
- agentVersion?: string;
34
- /**
35
- * Client name to report to the usage reporting API
36
- */
37
- clientName?: StringFromRequestFn;
38
- /**
39
- * Client version to report to the usage reporting API
40
- */
41
- clientVersion?: StringFromRequestFn;
42
- /**
43
- * The version of the runtime (like 'node v23.7.0')
44
- * @default empty string.
45
- */
46
- runtimeVersion?: string;
47
- /**
48
- * The hostname of the machine running this server
49
- * @default $HOSTNAME environment variable
50
- */
51
- hostname?: string;
52
- /**
53
- * The OS identification string.
54
- * The format is `${os.platform()}, ${os.type()}, ${os.release()}, ${os.arch()})`
55
- * @default empty string
56
- */
57
- uname?: string;
58
- /**
59
- * The maximum estimated size of each traces in bytes. If the estimated size is higher than this threshold,
60
- * the complete trace will not be sent and will be reduced to aggregated stats.
61
- *
62
- * Note: GraphOS only allow for traces of 10mb maximum
63
- * @default 10 * 1024 * 1024 (10mb)
64
- */
65
- maxTraceSize?: number;
66
- /**
67
- * The maximum uncompressed size of a report in bytes.
68
- * The report will be sent once this threshold is reached, even if the delay between send is not
69
- * yet expired.
70
- *
71
- * @default 4Mb
72
- */
73
- maxBatchUncompressedSize?: number;
74
- /**
75
- * The maximum time in ms between reports.
76
- * @default 20s
77
- */
78
- maxBatchDelay?: number;
79
- /**
80
- * Control if traces should be always sent.
81
- * If false, the traces will be batched until a delay or size is reached.
82
- * Note: This is highly not recommended in a production environment
83
- *
84
- * @default false
85
- */
86
- alwaysSend?: boolean;
87
- /**
88
- * Timeout in ms of a trace export tentative
89
- * @default 30s
90
- */
91
- exportTimeout?: number;
92
- /**
93
- * The class to be used to keep track of traces and send them to the GraphOS endpoint
94
- * Note: This option is aimed to be used for testing purposes
95
- */
96
- reporter?: (options: ApolloUsageReportOptions, yoga: YogaServer<Record<string, unknown>, Record<string, unknown>>, logger: YogaLogger) => Reporter;
97
- /**
98
- * Called when all retry attempts to send a report to GraphOS endpoint failed.
99
- * By default, the error is logged.
100
- */
101
- onError?: (err: Error) => void;
102
- /**
103
- * If false, unexecutable operation (with parsing or validation error) will not be sent
104
- * @default false
105
- */
106
- sendUnexecutableOperationDocuments?: boolean;
107
- };
108
- export interface ApolloUsageReportRequestContext extends ApolloInlineRequestTraceContext {
109
- traces: Map<YogaInitialContext, ApolloUsageReportGraphqlContext>;
110
- }
111
- export interface ApolloUsageReportGraphqlContext extends ApolloInlineGraphqlTraceContext {
112
- referencedFieldsByType?: ReturnType<typeof calculateReferencedFieldsByType>;
113
- operationKey?: string;
114
- schemaId?: string;
115
- }
116
- type StringFromRequestFn = (req: Request) => Maybe<string>;
117
- export declare function useApolloUsageReport(options?: ApolloUsageReportOptions): Plugin;
118
- export declare function hashSHA256(text: string, api?: {
119
- crypto: Crypto;
120
- TextEncoder: (typeof globalThis)['TextEncoder'];
121
- }): Promise<string>;
122
- export {};
@@ -1,21 +0,0 @@
1
- import { YogaLogger, YogaServer } from 'graphql-yoga';
2
- import { google } from '@apollo/usage-reporting-protobuf';
3
- import type { ApolloUsageReportOptions } from './index';
4
- import { OurReport } from './stats.cjs';
5
- export declare class Reporter {
6
- private yoga;
7
- private logger;
8
- private reportHeaders;
9
- private options;
10
- private reportsBySchema;
11
- private nextSendAfterDelay?;
12
- private sending;
13
- constructor(options: ApolloUsageReportOptions, yoga: YogaServer<Record<string, unknown>, Record<string, unknown>>, logger: YogaLogger);
14
- addTrace(schemaId: string, options: Parameters<OurReport['addTrace']>[0]): Promise<void> | undefined;
15
- flush(): Promise<PromiseSettledResult<unknown>[]>;
16
- sendReport(schemaId: string): Promise<void>;
17
- private _sendReport;
18
- private getReport;
19
- }
20
- export declare function getEnvVar<T>(name: string, defaultValue?: T): string | T | undefined;
21
- export declare function dateToProtoTimestamp(date: Date): google.protobuf.Timestamp;
@@ -1,21 +0,0 @@
1
- import { YogaLogger, YogaServer } from 'graphql-yoga';
2
- import { google } from '@apollo/usage-reporting-protobuf';
3
- import type { ApolloUsageReportOptions } from './index';
4
- import { OurReport } from './stats.js';
5
- export declare class Reporter {
6
- private yoga;
7
- private logger;
8
- private reportHeaders;
9
- private options;
10
- private reportsBySchema;
11
- private nextSendAfterDelay?;
12
- private sending;
13
- constructor(options: ApolloUsageReportOptions, yoga: YogaServer<Record<string, unknown>, Record<string, unknown>>, logger: YogaLogger);
14
- addTrace(schemaId: string, options: Parameters<OurReport['addTrace']>[0]): Promise<void> | undefined;
15
- flush(): Promise<PromiseSettledResult<unknown>[]>;
16
- sendReport(schemaId: string): Promise<void>;
17
- private _sendReport;
18
- private getReport;
19
- }
20
- export declare function getEnvVar<T>(name: string, defaultValue?: T): string | T | undefined;
21
- export declare function dateToProtoTimestamp(date: Date): google.protobuf.Timestamp;
@@ -1,136 +0,0 @@
1
- import type { NonFtv1ErrorPath } from '@apollo/server-gateway-interface';
2
- import { Trace, type google, type IContextualizedStats, type IFieldStat, type IPathErrorStats, type IQueryLatencyStats, type IReport, type IStatsContext, type ITracesAndStats, type ITypeStat, type ReportHeader } from '@apollo/usage-reporting-protobuf';
3
- import type { ReferencedFieldsByType } from '@apollo/utils.usagereporting';
4
- export declare class SizeEstimator {
5
- bytes: number;
6
- }
7
- export declare class OurReport implements Required<IReport> {
8
- readonly header: ReportHeader;
9
- tracesPreAggregated: boolean;
10
- constructor(header: ReportHeader);
11
- readonly tracesPerQuery: Record<string, OurTracesAndStats>;
12
- endTime: google.protobuf.ITimestamp | null;
13
- operationCount: number;
14
- readonly sizeEstimator: SizeEstimator;
15
- ensureCountsAreIntegers(): void;
16
- addTrace({ statsReportKey, trace, asTrace, referencedFieldsByType, maxTraceBytes, nonFtv1ErrorPaths, }: {
17
- statsReportKey: string;
18
- trace: Trace;
19
- asTrace: boolean;
20
- referencedFieldsByType: ReferencedFieldsByType;
21
- maxTraceBytes?: number;
22
- nonFtv1ErrorPaths: NonFtv1ErrorPath[];
23
- }): void;
24
- private getTracesAndStats;
25
- }
26
- declare class OurTracesAndStats implements Required<ITracesAndStats> {
27
- readonly referencedFieldsByType: ReferencedFieldsByType;
28
- constructor(referencedFieldsByType: ReferencedFieldsByType);
29
- readonly trace: Uint8Array[];
30
- readonly statsWithContext: StatsByContext;
31
- readonly internalTracesContributingToStats: Uint8Array[];
32
- ensureCountsAreIntegers(): void;
33
- }
34
- declare class StatsByContext {
35
- readonly map: {
36
- [k: string]: OurContextualizedStats;
37
- };
38
- /**
39
- * This function is used by the protobuf generator to convert this map into
40
- * an array of contextualized stats to serialize
41
- */
42
- toArray(): IContextualizedStats[];
43
- ensureCountsAreIntegers(): void;
44
- addTrace(trace: Trace, sizeEstimator: SizeEstimator, nonFtv1ErrorPaths: NonFtv1ErrorPath[]): void;
45
- private getContextualizedStats;
46
- }
47
- export declare class OurContextualizedStats implements Required<IContextualizedStats> {
48
- readonly context: IStatsContext;
49
- queryLatencyStats: OurQueryLatencyStats;
50
- perTypeStat: {
51
- [k: string]: OurTypeStat;
52
- };
53
- constructor(context: IStatsContext);
54
- ensureCountsAreIntegers(): void;
55
- addTrace(trace: Trace, sizeEstimator: SizeEstimator, nonFtv1ErrorPaths?: NonFtv1ErrorPath[]): void;
56
- getTypeStat(parentType: string, sizeEstimator: SizeEstimator): OurTypeStat;
57
- }
58
- declare class OurQueryLatencyStats implements Required<IQueryLatencyStats> {
59
- latencyCount: DurationHistogram;
60
- requestCount: number;
61
- requestsWithoutFieldInstrumentation: number;
62
- cacheHits: number;
63
- persistedQueryHits: number;
64
- persistedQueryMisses: number;
65
- cacheLatencyCount: DurationHistogram;
66
- rootErrorStats: OurPathErrorStats;
67
- requestsWithErrorsCount: number;
68
- publicCacheTtlCount: DurationHistogram;
69
- privateCacheTtlCount: DurationHistogram;
70
- registeredOperationCount: number;
71
- forbiddenOperationCount: number;
72
- }
73
- declare class OurPathErrorStats implements Required<IPathErrorStats> {
74
- children: {
75
- [k: string]: OurPathErrorStats;
76
- };
77
- errorsCount: number;
78
- requestsWithErrorsCount: number;
79
- getChild(subPath: string, sizeEstimator: SizeEstimator): OurPathErrorStats;
80
- }
81
- declare class OurTypeStat implements Required<ITypeStat> {
82
- perFieldStat: {
83
- [k: string]: OurFieldStat;
84
- };
85
- getFieldStat(fieldName: string, returnType: string, sizeEstimator: SizeEstimator): OurFieldStat;
86
- ensureCountsAreIntegers(): void;
87
- }
88
- declare class OurFieldStat implements Required<IFieldStat> {
89
- readonly returnType: string;
90
- errorsCount: number;
91
- observedExecutionCount: number;
92
- estimatedExecutionCount: number;
93
- requestsWithErrorsCount: number;
94
- latencyCount: DurationHistogram;
95
- constructor(returnType: string);
96
- ensureCountsAreIntegers(): void;
97
- }
98
- export interface DurationHistogramOptions {
99
- initSize?: number;
100
- buckets?: number[];
101
- }
102
- export declare class DurationHistogram {
103
- private readonly buckets;
104
- static readonly BUCKET_COUNT = 384;
105
- static readonly EXPONENT_LOG: number;
106
- toArray(): number[];
107
- static durationToBucket(durationNs: number): number;
108
- incrementDuration(durationNs: number, value?: number): DurationHistogram;
109
- incrementBucket(bucket: number, value?: number): void;
110
- combine(otherHistogram: DurationHistogram): void;
111
- constructor(options?: DurationHistogramOptions);
112
- }
113
- /**
114
- * Iterates over the entire trace, calling `f` on each Trace.Node found. It
115
- * looks under the "root" node as well as any inside the query plan. If any `f`
116
- * returns true, it stops walking the tree.
117
- *
118
- * Each call to `f` will receive an object that implements ResponseNamePath. If
119
- * `includePath` is true, `f` can call `toArray()` on it to convert the
120
- * linked-list representation to an array of the response name (field name)
121
- * nodes that you navigate to get to the node (including a "service:subgraph"
122
- * top-level node if this is a federated trace). Note that we don't add anything
123
- * to the path for index (list element) nodes. This is because the only use case
124
- * we have (error path statistics) does not care about list indexes (it's not
125
- * that interesting to know that sometimes an error was at foo.3.bar and
126
- * sometimes foo.5.bar, vs just generally foo.bar).
127
- *
128
- * If `includePath` is false, we don't bother to build up the linked lists, and
129
- * calling `toArray()` will throw.
130
- */
131
- export declare function iterateOverTrace(trace: Trace, f: (node: Trace.INode, path: ResponseNamePath) => boolean, includePath: boolean): void;
132
- export interface ResponseNamePath {
133
- toArray(): string[];
134
- child(responseName: string): ResponseNamePath;
135
- }
136
- export {};
@@ -1,136 +0,0 @@
1
- import type { NonFtv1ErrorPath } from '@apollo/server-gateway-interface';
2
- import { Trace, type google, type IContextualizedStats, type IFieldStat, type IPathErrorStats, type IQueryLatencyStats, type IReport, type IStatsContext, type ITracesAndStats, type ITypeStat, type ReportHeader } from '@apollo/usage-reporting-protobuf';
3
- import type { ReferencedFieldsByType } from '@apollo/utils.usagereporting';
4
- export declare class SizeEstimator {
5
- bytes: number;
6
- }
7
- export declare class OurReport implements Required<IReport> {
8
- readonly header: ReportHeader;
9
- tracesPreAggregated: boolean;
10
- constructor(header: ReportHeader);
11
- readonly tracesPerQuery: Record<string, OurTracesAndStats>;
12
- endTime: google.protobuf.ITimestamp | null;
13
- operationCount: number;
14
- readonly sizeEstimator: SizeEstimator;
15
- ensureCountsAreIntegers(): void;
16
- addTrace({ statsReportKey, trace, asTrace, referencedFieldsByType, maxTraceBytes, nonFtv1ErrorPaths, }: {
17
- statsReportKey: string;
18
- trace: Trace;
19
- asTrace: boolean;
20
- referencedFieldsByType: ReferencedFieldsByType;
21
- maxTraceBytes?: number;
22
- nonFtv1ErrorPaths: NonFtv1ErrorPath[];
23
- }): void;
24
- private getTracesAndStats;
25
- }
26
- declare class OurTracesAndStats implements Required<ITracesAndStats> {
27
- readonly referencedFieldsByType: ReferencedFieldsByType;
28
- constructor(referencedFieldsByType: ReferencedFieldsByType);
29
- readonly trace: Uint8Array[];
30
- readonly statsWithContext: StatsByContext;
31
- readonly internalTracesContributingToStats: Uint8Array[];
32
- ensureCountsAreIntegers(): void;
33
- }
34
- declare class StatsByContext {
35
- readonly map: {
36
- [k: string]: OurContextualizedStats;
37
- };
38
- /**
39
- * This function is used by the protobuf generator to convert this map into
40
- * an array of contextualized stats to serialize
41
- */
42
- toArray(): IContextualizedStats[];
43
- ensureCountsAreIntegers(): void;
44
- addTrace(trace: Trace, sizeEstimator: SizeEstimator, nonFtv1ErrorPaths: NonFtv1ErrorPath[]): void;
45
- private getContextualizedStats;
46
- }
47
- export declare class OurContextualizedStats implements Required<IContextualizedStats> {
48
- readonly context: IStatsContext;
49
- queryLatencyStats: OurQueryLatencyStats;
50
- perTypeStat: {
51
- [k: string]: OurTypeStat;
52
- };
53
- constructor(context: IStatsContext);
54
- ensureCountsAreIntegers(): void;
55
- addTrace(trace: Trace, sizeEstimator: SizeEstimator, nonFtv1ErrorPaths?: NonFtv1ErrorPath[]): void;
56
- getTypeStat(parentType: string, sizeEstimator: SizeEstimator): OurTypeStat;
57
- }
58
- declare class OurQueryLatencyStats implements Required<IQueryLatencyStats> {
59
- latencyCount: DurationHistogram;
60
- requestCount: number;
61
- requestsWithoutFieldInstrumentation: number;
62
- cacheHits: number;
63
- persistedQueryHits: number;
64
- persistedQueryMisses: number;
65
- cacheLatencyCount: DurationHistogram;
66
- rootErrorStats: OurPathErrorStats;
67
- requestsWithErrorsCount: number;
68
- publicCacheTtlCount: DurationHistogram;
69
- privateCacheTtlCount: DurationHistogram;
70
- registeredOperationCount: number;
71
- forbiddenOperationCount: number;
72
- }
73
- declare class OurPathErrorStats implements Required<IPathErrorStats> {
74
- children: {
75
- [k: string]: OurPathErrorStats;
76
- };
77
- errorsCount: number;
78
- requestsWithErrorsCount: number;
79
- getChild(subPath: string, sizeEstimator: SizeEstimator): OurPathErrorStats;
80
- }
81
- declare class OurTypeStat implements Required<ITypeStat> {
82
- perFieldStat: {
83
- [k: string]: OurFieldStat;
84
- };
85
- getFieldStat(fieldName: string, returnType: string, sizeEstimator: SizeEstimator): OurFieldStat;
86
- ensureCountsAreIntegers(): void;
87
- }
88
- declare class OurFieldStat implements Required<IFieldStat> {
89
- readonly returnType: string;
90
- errorsCount: number;
91
- observedExecutionCount: number;
92
- estimatedExecutionCount: number;
93
- requestsWithErrorsCount: number;
94
- latencyCount: DurationHistogram;
95
- constructor(returnType: string);
96
- ensureCountsAreIntegers(): void;
97
- }
98
- export interface DurationHistogramOptions {
99
- initSize?: number;
100
- buckets?: number[];
101
- }
102
- export declare class DurationHistogram {
103
- private readonly buckets;
104
- static readonly BUCKET_COUNT = 384;
105
- static readonly EXPONENT_LOG: number;
106
- toArray(): number[];
107
- static durationToBucket(durationNs: number): number;
108
- incrementDuration(durationNs: number, value?: number): DurationHistogram;
109
- incrementBucket(bucket: number, value?: number): void;
110
- combine(otherHistogram: DurationHistogram): void;
111
- constructor(options?: DurationHistogramOptions);
112
- }
113
- /**
114
- * Iterates over the entire trace, calling `f` on each Trace.Node found. It
115
- * looks under the "root" node as well as any inside the query plan. If any `f`
116
- * returns true, it stops walking the tree.
117
- *
118
- * Each call to `f` will receive an object that implements ResponseNamePath. If
119
- * `includePath` is true, `f` can call `toArray()` on it to convert the
120
- * linked-list representation to an array of the response name (field name)
121
- * nodes that you navigate to get to the node (including a "service:subgraph"
122
- * top-level node if this is a federated trace). Note that we don't add anything
123
- * to the path for index (list element) nodes. This is because the only use case
124
- * we have (error path statistics) does not care about list indexes (it's not
125
- * that interesting to know that sometimes an error was at foo.3.bar and
126
- * sometimes foo.5.bar, vs just generally foo.bar).
127
- *
128
- * If `includePath` is false, we don't bother to build up the linked lists, and
129
- * calling `toArray()` will throw.
130
- */
131
- export declare function iterateOverTrace(trace: Trace, f: (node: Trace.INode, path: ResponseNamePath) => boolean, includePath: boolean): void;
132
- export interface ResponseNamePath {
133
- toArray(): string[];
134
- child(responseName: string): ResponseNamePath;
135
- }
136
- export {};