|
1 | 1 | import {handleStreamOrSingleExecutionResult, type ExecutionArgs} from '@envelop/core'
|
| 2 | +import {useOnResolve} from '@envelop/on-resolve' |
2 | 3 | import tracer, {type opentelemetry, type Span} from 'dd-trace'
|
3 |
| -import {getOperationAST, type GraphQLResolveInfo} from 'graphql' |
| 4 | +import {defaultFieldResolver, getNamedType, getOperationAST, type GraphQLResolveInfo} from 'graphql' |
4 | 5 | import type {ExecutionResult} from 'graphql-ws'
|
5 | 6 | import type {Plugin} from 'graphql-yoga'
|
6 | 7 | import {Path} from 'graphql/jsutils/Path'
|
@@ -48,43 +49,43 @@ export const useDatadogTracing = (config: Config): Plugin<DDContext & ServerCont
|
48 | 49 | if (process.env.DD_TRACE_ENABLED !== 'true') return {}
|
49 | 50 | return {
|
50 | 51 | // Removing resolve-level tracing to see if we can measure executions without OOMs
|
51 |
| - // onPluginInit({addPlugin}) { |
52 |
| - // addPlugin( |
53 |
| - // useOnResolve(({info, context, args, replaceResolver, resolver}) => { |
54 |
| - // // Ignore anything without a custom resolver since it's basically an identity function |
55 |
| - // if (resolver === defaultFieldResolver) return |
56 |
| - // const path = getPath(info, config) |
57 |
| - // const computedPathString = path.join('.') |
58 |
| - // const ddContext = context[ddSymbol] |
59 |
| - // const {rootSpan, fields} = ddContext |
60 |
| - // // if collapsed, we just measure the first item in a list |
61 |
| - // if (config.collapse && fields[computedPathString]) return |
| 52 | + onPluginInit({addPlugin}) { |
| 53 | + addPlugin( |
| 54 | + useOnResolve(({info, context, args, replaceResolver, resolver}) => { |
| 55 | + // Ignore anything without a custom resolver since it's basically an identity function |
| 56 | + if (resolver === defaultFieldResolver) return |
| 57 | + const path = getPath(info, config) |
| 58 | + const computedPathString = path.join('.') |
| 59 | + const ddContext = context[ddSymbol] |
| 60 | + const {rootSpan, fields} = ddContext |
| 61 | + // if collapsed, we just measure the first item in a list |
| 62 | + if (config.collapse && fields[computedPathString]) return |
62 | 63 |
|
63 |
| - // const parentSpan = getParentSpan(path, fields) ?? rootSpan |
64 |
| - // const {fieldName, returnType, parentType} = info |
65 |
| - // const returnTypeName = getNamedType(info.returnType).name |
66 |
| - // const parentTypeName = getNamedType(parentType).name |
67 |
| - // const fieldSpan = tracer.startSpan('graphql.resolve', { |
68 |
| - // childOf: parentSpan, |
69 |
| - // tags: { |
70 |
| - // 'resource.name': `${info.fieldName}:${returnType}`, |
71 |
| - // 'span.type': 'graphql', |
72 |
| - // 'graphql.resolver.fieldName': fieldName, |
73 |
| - // 'graphql.resolver.typeName': parentTypeName, |
74 |
| - // 'graphql.resolver.returnType': returnTypeName, |
75 |
| - // 'graphql.resolver.fieldPath': computedPathString, |
76 |
| - // ...makeVariables(config.excludeArgs, args, fieldName) |
77 |
| - // } |
78 |
| - // }) |
79 |
| - // fields[computedPathString] = {span: fieldSpan} |
80 |
| - // replaceResolver((...args) => tracer.scope().activate(fieldSpan, () => resolver(...args))) |
81 |
| - // return ({result}) => { |
82 |
| - // markSpanError(fieldSpan, result) |
83 |
| - // fieldSpan.finish() |
84 |
| - // } |
85 |
| - // }) |
86 |
| - // ) |
87 |
| - // }, |
| 64 | + const parentSpan = getParentSpan(path, fields) ?? rootSpan |
| 65 | + const {fieldName, returnType, parentType} = info |
| 66 | + const returnTypeName = getNamedType(info.returnType).name |
| 67 | + const parentTypeName = getNamedType(parentType).name |
| 68 | + const fieldSpan = tracer.startSpan('graphql.resolve', { |
| 69 | + childOf: parentSpan, |
| 70 | + tags: { |
| 71 | + 'resource.name': `${info.fieldName}:${returnType}`, |
| 72 | + 'span.type': 'graphql', |
| 73 | + 'graphql.resolver.fieldName': fieldName, |
| 74 | + 'graphql.resolver.typeName': parentTypeName, |
| 75 | + 'graphql.resolver.returnType': returnTypeName, |
| 76 | + 'graphql.resolver.fieldPath': computedPathString, |
| 77 | + ...makeVariables(config.excludeArgs, args, fieldName) |
| 78 | + } |
| 79 | + }) |
| 80 | + fields[computedPathString] = {span: fieldSpan} |
| 81 | + replaceResolver((...args) => tracer.scope().activate(fieldSpan, () => resolver(...args))) |
| 82 | + return ({result}) => { |
| 83 | + markSpanError(fieldSpan, result) |
| 84 | + fieldSpan.finish() |
| 85 | + } |
| 86 | + }) |
| 87 | + ) |
| 88 | + }, |
88 | 89 | onExecute({args, extendContext, executeFn, setExecuteFn}) {
|
89 | 90 | const operationAst = getOperationAST(args.document, args.operationName)!
|
90 | 91 | const operationType = operationAst.operation
|
|
0 commit comments