@envelop/opentelemetry 6.2.1 → 6.3.0-alpha-20240402093155-a99b4960

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.
package/README.md CHANGED
@@ -35,8 +35,53 @@ const getEnveloped = envelop({
35
35
  })
36
36
  ```
37
37
 
38
- If you wish to use custom tracer/exporter, create it and pass it. This example integrates Jaeger
39
- tracer:
38
+ ## Integration with `@opentelemetry` packages
39
+
40
+ By default, this plugin is creating a console exporter for exporting the `Span`s.
41
+
42
+ If you wish to use custom tracer/exporter, create it and pass it to the plugin factory function.
43
+
44
+ The following example is taking the current global tracer:
45
+
46
+ ```ts
47
+ import { execute, parse, specifiedRules, subscribe, validate } from 'graphql'
48
+ import { envelop, useEngine } from '@envelop/core'
49
+ import { useOpenTelemetry } from '@envelop/opentelemetry'
50
+ import { trace } from '@opentelemetry/api'
51
+ import { BasicTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'
52
+
53
+ const getEnveloped = envelop({
54
+ plugins: [
55
+ useEngine({ parse, validate, specifiedRules, execute, subscribe }),
56
+ // ... other plugins ...
57
+ useOpenTelemetry(
58
+ {
59
+ resolvers: true, // Tracks resolvers calls, and tracks resolvers thrown errors
60
+ variables: true, // Includes the operation variables values as part of the metadata collected
61
+ result: true // Includes execution result object as part of the metadata collected
62
+ },
63
+ trace.getTracerProvider()
64
+ )
65
+ ]
66
+ })
67
+ ```
68
+
69
+ This example integrates Jaeger tracer. To use this example, start by running Jaeger locally in a
70
+ Docker container (or, follow
71
+ [other options to run Jaeger locally](https://www.npmjs.com/package/@opentelemetry/exporter-jaeger#prerequisites)):
72
+
73
+ ```
74
+ docker run -d --name jaeger \
75
+ -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
76
+ -p 5775:5775/udp \
77
+ -p 6831:6831/udp \
78
+ -p 6832:6832/udp \
79
+ -p 5778:5778 \
80
+ -p 16686:16686 \
81
+ -p 14268:14268 \
82
+ -p 9411:9411 \
83
+ jaegertracing/all-in-one:latest
84
+ ```
40
85
 
41
86
  ```ts
42
87
  import { execute, parse, specifiedRules, subscribe, validate } from 'graphql'
@@ -45,10 +90,14 @@ import { useOpenTelemetry } from '@envelop/opentelemetry'
45
90
  import { JaegerExporter } from '@opentelemetry/exporter-jaeger'
46
91
  import { BasicTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'
47
92
 
93
+ // Create your exporter
48
94
  const exporter = new JaegerExporter({
49
- serviceName: 'my-service-name'
95
+ serviceName: 'my-service-name',
96
+ host: 'localhost',
97
+ port: 6832
50
98
  })
51
99
 
100
+ // Configure opentelmetry to run for your service
52
101
  const provider = new BasicTracerProvider()
53
102
  provider.addSpanProcessor(new SimpleSpanProcessor(exporter))
54
103
  provider.register()
package/cjs/index.js CHANGED
@@ -88,6 +88,14 @@ const useOpenTelemetry = (options, tracingProvider, spanKind = api_1.SpanKind.SE
88
88
  if (!operationAst) {
89
89
  return;
90
90
  }
91
+ const shouldReport = options.excludedOperationNames
92
+ ? typeof options.excludedOperationNames === 'function'
93
+ ? !options.excludedOperationNames(operationAst.name?.value)
94
+ : !options.excludedOperationNames.includes(operationAst.name?.value || '')
95
+ : true;
96
+ if (!shouldReport) {
97
+ return;
98
+ }
91
99
  const operationType = operationAst.operation;
92
100
  let isDocumentLoggable;
93
101
  if (options.document == null || options.document === true) {
@@ -106,6 +114,13 @@ const useOpenTelemetry = (options, tracingProvider, spanKind = api_1.SpanKind.SE
106
114
  }
107
115
  const operationName = operationAst.name?.value || 'anonymous';
108
116
  const currOtelContext = getCurrentOtelContext(args.contextValue);
117
+ const variablesAttribute = options.variables
118
+ ? {
119
+ [AttributeName.EXECUTION_VARIABLES]: typeof options.variables === 'function'
120
+ ? options.variables(args.variableValues)
121
+ : JSON.stringify(args.variableValues ?? {}),
122
+ }
123
+ : {};
109
124
  const executionSpan = tracer.startSpan(`${spanPrefix}${operationType}.${operationName}`, {
110
125
  kind: spanKind,
111
126
  attributes: {
@@ -115,9 +130,7 @@ const useOpenTelemetry = (options, tracingProvider, spanKind = api_1.SpanKind.SE
115
130
  [AttributeName.EXECUTION_OPERATION_DOCUMENT]: isDocumentLoggable
116
131
  ? (0, core_1.getDocumentString)(args.document, graphql_1.print)
117
132
  : undefined,
118
- ...(options.variables
119
- ? { [AttributeName.EXECUTION_VARIABLES]: JSON.stringify(args.variableValues ?? {}) }
120
- : {}),
133
+ ...variablesAttribute,
121
134
  },
122
135
  }, currOtelContext);
123
136
  setCurrentOtelContext(args.contextValue, opentelemetry.trace.setSpan(currOtelContext, executionSpan));
@@ -162,6 +175,14 @@ const useOpenTelemetry = (options, tracingProvider, spanKind = api_1.SpanKind.SE
162
175
  if (!operationAst) {
163
176
  return;
164
177
  }
178
+ const shouldReport = options.excludedOperationNames
179
+ ? typeof options.excludedOperationNames === 'function'
180
+ ? !options.excludedOperationNames(operationAst.name?.value)
181
+ : !options.excludedOperationNames.includes(operationAst.name?.value || '')
182
+ : true;
183
+ if (!shouldReport) {
184
+ return;
185
+ }
165
186
  const operationType = 'subscription';
166
187
  let isDocumentLoggable;
167
188
  if (options.variables) {
@@ -175,6 +196,13 @@ const useOpenTelemetry = (options, tracingProvider, spanKind = api_1.SpanKind.SE
175
196
  }
176
197
  const currOtelContext = getCurrentOtelContext(args.contextValue);
177
198
  const operationName = operationAst.name?.value || 'anonymous';
199
+ const variablesAttribute = options.variables
200
+ ? {
201
+ [AttributeName.EXECUTION_VARIABLES]: typeof options.variables === 'function'
202
+ ? options.variables(args.variableValues)
203
+ : JSON.stringify(args.variableValues ?? {}),
204
+ }
205
+ : {};
178
206
  const subscriptionSpan = tracer.startSpan(`${operationType}.${operationName}`, {
179
207
  kind: spanKind,
180
208
  attributes: {
@@ -184,9 +212,7 @@ const useOpenTelemetry = (options, tracingProvider, spanKind = api_1.SpanKind.SE
184
212
  [AttributeName.EXECUTION_OPERATION_DOCUMENT]: isDocumentLoggable
185
213
  ? (0, core_1.getDocumentString)(args.document, graphql_1.print)
186
214
  : undefined,
187
- ...(options.variables
188
- ? { [AttributeName.EXECUTION_VARIABLES]: JSON.stringify(args.variableValues ?? {}) }
189
- : {}),
215
+ ...variablesAttribute,
190
216
  },
191
217
  }, currOtelContext);
192
218
  setCurrentOtelContext(args.contextValue, opentelemetry.trace.setSpan(currOtelContext, subscriptionSpan));
package/esm/index.js CHANGED
@@ -82,6 +82,14 @@ export const useOpenTelemetry = (options, tracingProvider, spanKind = SpanKind.S
82
82
  if (!operationAst) {
83
83
  return;
84
84
  }
85
+ const shouldReport = options.excludedOperationNames
86
+ ? typeof options.excludedOperationNames === 'function'
87
+ ? !options.excludedOperationNames(operationAst.name?.value)
88
+ : !options.excludedOperationNames.includes(operationAst.name?.value || '')
89
+ : true;
90
+ if (!shouldReport) {
91
+ return;
92
+ }
85
93
  const operationType = operationAst.operation;
86
94
  let isDocumentLoggable;
87
95
  if (options.document == null || options.document === true) {
@@ -100,6 +108,13 @@ export const useOpenTelemetry = (options, tracingProvider, spanKind = SpanKind.S
100
108
  }
101
109
  const operationName = operationAst.name?.value || 'anonymous';
102
110
  const currOtelContext = getCurrentOtelContext(args.contextValue);
111
+ const variablesAttribute = options.variables
112
+ ? {
113
+ [AttributeName.EXECUTION_VARIABLES]: typeof options.variables === 'function'
114
+ ? options.variables(args.variableValues)
115
+ : JSON.stringify(args.variableValues ?? {}),
116
+ }
117
+ : {};
103
118
  const executionSpan = tracer.startSpan(`${spanPrefix}${operationType}.${operationName}`, {
104
119
  kind: spanKind,
105
120
  attributes: {
@@ -109,9 +124,7 @@ export const useOpenTelemetry = (options, tracingProvider, spanKind = SpanKind.S
109
124
  [AttributeName.EXECUTION_OPERATION_DOCUMENT]: isDocumentLoggable
110
125
  ? getDocumentString(args.document, print)
111
126
  : undefined,
112
- ...(options.variables
113
- ? { [AttributeName.EXECUTION_VARIABLES]: JSON.stringify(args.variableValues ?? {}) }
114
- : {}),
127
+ ...variablesAttribute,
115
128
  },
116
129
  }, currOtelContext);
117
130
  setCurrentOtelContext(args.contextValue, opentelemetry.trace.setSpan(currOtelContext, executionSpan));
@@ -156,6 +169,14 @@ export const useOpenTelemetry = (options, tracingProvider, spanKind = SpanKind.S
156
169
  if (!operationAst) {
157
170
  return;
158
171
  }
172
+ const shouldReport = options.excludedOperationNames
173
+ ? typeof options.excludedOperationNames === 'function'
174
+ ? !options.excludedOperationNames(operationAst.name?.value)
175
+ : !options.excludedOperationNames.includes(operationAst.name?.value || '')
176
+ : true;
177
+ if (!shouldReport) {
178
+ return;
179
+ }
159
180
  const operationType = 'subscription';
160
181
  let isDocumentLoggable;
161
182
  if (options.variables) {
@@ -169,6 +190,13 @@ export const useOpenTelemetry = (options, tracingProvider, spanKind = SpanKind.S
169
190
  }
170
191
  const currOtelContext = getCurrentOtelContext(args.contextValue);
171
192
  const operationName = operationAst.name?.value || 'anonymous';
193
+ const variablesAttribute = options.variables
194
+ ? {
195
+ [AttributeName.EXECUTION_VARIABLES]: typeof options.variables === 'function'
196
+ ? options.variables(args.variableValues)
197
+ : JSON.stringify(args.variableValues ?? {}),
198
+ }
199
+ : {};
172
200
  const subscriptionSpan = tracer.startSpan(`${operationType}.${operationName}`, {
173
201
  kind: spanKind,
174
202
  attributes: {
@@ -178,9 +206,7 @@ export const useOpenTelemetry = (options, tracingProvider, spanKind = SpanKind.S
178
206
  [AttributeName.EXECUTION_OPERATION_DOCUMENT]: isDocumentLoggable
179
207
  ? getDocumentString(args.document, print)
180
208
  : undefined,
181
- ...(options.variables
182
- ? { [AttributeName.EXECUTION_VARIABLES]: JSON.stringify(args.variableValues ?? {}) }
183
- : {}),
209
+ ...variablesAttribute,
184
210
  },
185
211
  }, currOtelContext);
186
212
  setCurrentOtelContext(args.contextValue, opentelemetry.trace.setSpan(currOtelContext, subscriptionSpan));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@envelop/opentelemetry",
3
- "version": "6.2.1",
3
+ "version": "6.3.0-alpha-20240402093155-a99b4960",
4
4
  "sideEffects": false,
5
5
  "peerDependencies": {
6
6
  "@envelop/core": "^5.0.0",
@@ -15,12 +15,15 @@ export declare enum AttributeName {
15
15
  EXECUTION_VARIABLES = "graphql.execute.variables"
16
16
  }
17
17
  declare const tracingSpanSymbol: unique symbol;
18
+ export type ResolveVariablesAttributesFn = (variableValues: any) => opentelemetry.AttributeValue;
19
+ export type ExcludeOperationNamesFn = (operationName: string | undefined) => boolean;
18
20
  export type TracingOptions = {
19
21
  document?: boolean;
20
22
  resolvers?: boolean;
21
- variables?: boolean;
23
+ variables?: boolean | ResolveVariablesAttributesFn;
22
24
  result?: boolean;
23
25
  traceIdInResult?: string;
26
+ excludedOperationNames?: string[] | ExcludeOperationNamesFn;
24
27
  };
25
28
  type PluginContext = {
26
29
  [tracingSpanSymbol]: opentelemetry.Span;
@@ -15,12 +15,15 @@ export declare enum AttributeName {
15
15
  EXECUTION_VARIABLES = "graphql.execute.variables"
16
16
  }
17
17
  declare const tracingSpanSymbol: unique symbol;
18
+ export type ResolveVariablesAttributesFn = (variableValues: any) => opentelemetry.AttributeValue;
19
+ export type ExcludeOperationNamesFn = (operationName: string | undefined) => boolean;
18
20
  export type TracingOptions = {
19
21
  document?: boolean;
20
22
  resolvers?: boolean;
21
- variables?: boolean;
23
+ variables?: boolean | ResolveVariablesAttributesFn;
22
24
  result?: boolean;
23
25
  traceIdInResult?: string;
26
+ excludedOperationNames?: string[] | ExcludeOperationNamesFn;
24
27
  };
25
28
  type PluginContext = {
26
29
  [tracingSpanSymbol]: opentelemetry.Span;