dd-trace 2.2.0 → 2.3.1
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/LICENSE-3rdparty.csv +0 -2
- package/index.d.ts +6 -12
- package/package.json +3 -5
- package/packages/datadog-instrumentations/index.js +9 -0
- package/packages/datadog-instrumentations/src/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/cucumber.js +116 -0
- package/packages/datadog-instrumentations/src/elasticsearch.js +15 -5
- package/packages/datadog-instrumentations/src/generic-pool.js +48 -0
- package/packages/datadog-instrumentations/src/ioredis.js +52 -0
- package/packages/datadog-instrumentations/src/mongoose.js +30 -0
- package/packages/datadog-instrumentations/src/pino.js +105 -0
- package/packages/datadog-instrumentations/src/redis.js +118 -0
- package/packages/datadog-instrumentations/src/sharedb.js +78 -0
- package/packages/datadog-instrumentations/src/winston.js +57 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -2
- package/packages/datadog-plugin-bunyan/src/index.js +5 -22
- package/packages/datadog-plugin-cucumber/src/index.js +83 -128
- package/packages/datadog-plugin-fastify/src/find-my-way.js +0 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +8 -6
- package/packages/datadog-plugin-graphql/src/index.js +34 -28
- package/packages/datadog-plugin-grpc/src/client.js +20 -6
- package/packages/datadog-plugin-http2/src/server.js +2 -0
- package/packages/datadog-plugin-ioredis/src/index.js +5 -35
- package/packages/datadog-plugin-jest/src/jest-environment.js +26 -30
- package/packages/datadog-plugin-koa/src/index.js +6 -2
- package/packages/datadog-plugin-microgateway-core/src/index.js +1 -3
- package/packages/datadog-plugin-mocha/src/index.js +5 -3
- package/packages/datadog-plugin-mongodb-core/src/util.js +31 -7
- package/packages/datadog-plugin-next/src/index.js +9 -4
- package/packages/datadog-plugin-oracledb/src/index.js +10 -7
- package/packages/datadog-plugin-pino/src/index.js +5 -158
- package/packages/datadog-plugin-redis/src/index.js +96 -80
- package/packages/datadog-plugin-restify/src/index.js +18 -3
- package/packages/datadog-plugin-rhea/src/index.js +8 -5
- package/packages/datadog-plugin-router/src/index.js +23 -14
- package/packages/datadog-plugin-sharedb/src/index.js +47 -87
- package/packages/datadog-plugin-winston/src/index.js +5 -113
- package/packages/datadog-shimmer/src/shimmer.js +1 -1
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +2 -1
- package/packages/dd-trace/src/appsec/reporter.js +3 -2
- package/packages/dd-trace/src/config.js +7 -1
- package/packages/dd-trace/src/constants.js +1 -6
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -34
- package/packages/dd-trace/src/opentracing/tracer.js +1 -1
- package/packages/dd-trace/src/plugins/index.js +0 -2
- package/packages/dd-trace/src/plugins/log_plugin.js +49 -0
- package/packages/dd-trace/src/plugins/plugin.js +7 -0
- package/packages/dd-trace/src/plugins/util/git.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +102 -84
- package/packages/dd-trace/src/priority_sampler.js +1 -49
- package/packages/dd-trace/src/scope.js +47 -23
- package/packages/dd-trace/src/span_processor.js +22 -7
- package/packages/datadog-plugin-generic-pool/src/index.js +0 -52
- package/packages/datadog-plugin-mongoose/src/index.js +0 -51
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook,
|
|
6
|
+
AsyncResource
|
|
7
|
+
} = require('./helpers/instrument')
|
|
8
|
+
const shimmer = require('../../datadog-shimmer')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @description The enum values in this map are not exposed from ShareDB, so the keys are hard-coded here.
|
|
12
|
+
* The values were derived from: https://github.com/share/sharedb/blob/master/lib/client/connection.js#L196
|
|
13
|
+
*/
|
|
14
|
+
const READABLE_ACTION_NAMES = {
|
|
15
|
+
hs: 'handshake',
|
|
16
|
+
qf: 'query-fetch',
|
|
17
|
+
qs: 'query-subscribe',
|
|
18
|
+
qu: 'query-unsubscribe',
|
|
19
|
+
bf: 'bulk-fetch',
|
|
20
|
+
bs: 'bulk-subscribe',
|
|
21
|
+
bu: 'bulk-unsubscribe',
|
|
22
|
+
f: 'fetch',
|
|
23
|
+
s: 'subscribe',
|
|
24
|
+
u: 'unsubscribe',
|
|
25
|
+
op: 'op',
|
|
26
|
+
nf: 'snapshot-fetch',
|
|
27
|
+
nt: 'snapshot-fetch-by-ts',
|
|
28
|
+
p: 'presence-broadcast',
|
|
29
|
+
pr: 'presence-request',
|
|
30
|
+
ps: 'presence-subscribe',
|
|
31
|
+
pu: 'presence-unsubscribe'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
addHook({ name: 'sharedb', versions: ['>=1'], file: 'lib/agent.js' }, Agent => {
|
|
35
|
+
const startCh = channel('apm:sharedb:request:start')
|
|
36
|
+
const asyncEndCh = channel('apm:sharedb:request:async-end')
|
|
37
|
+
const endCh = channel('apm:sharedb:request:end')
|
|
38
|
+
const errorCh = channel('apm:sharedb:request:error')
|
|
39
|
+
|
|
40
|
+
shimmer.wrap(Agent.prototype, '_handleMessage', origHandleMessageFn => function (request, callback) {
|
|
41
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
42
|
+
const action = request.a
|
|
43
|
+
|
|
44
|
+
const actionName = getReadableActionName(action)
|
|
45
|
+
|
|
46
|
+
startCh.publish({ actionName, request })
|
|
47
|
+
|
|
48
|
+
callback = asyncResource.bind(callback)
|
|
49
|
+
|
|
50
|
+
arguments[1] = AsyncResource.bind(function (error, res) {
|
|
51
|
+
if (error) {
|
|
52
|
+
errorCh.publish(error)
|
|
53
|
+
}
|
|
54
|
+
asyncEndCh.publish({ request, res })
|
|
55
|
+
|
|
56
|
+
return callback.apply(this, arguments)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
return origHandleMessageFn.apply(this, arguments)
|
|
61
|
+
} catch (error) {
|
|
62
|
+
errorCh.publish(error)
|
|
63
|
+
|
|
64
|
+
throw error
|
|
65
|
+
} finally {
|
|
66
|
+
endCh.publish(undefined)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
return Agent
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
function getReadableActionName (action) {
|
|
73
|
+
const actionName = READABLE_ACTION_NAMES[action]
|
|
74
|
+
if (actionName === undefined) {
|
|
75
|
+
return action
|
|
76
|
+
}
|
|
77
|
+
return actionName
|
|
78
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook
|
|
6
|
+
} = require('./helpers/instrument')
|
|
7
|
+
const shimmer = require('../../datadog-shimmer')
|
|
8
|
+
|
|
9
|
+
const patched = new WeakSet()
|
|
10
|
+
|
|
11
|
+
addHook({ name: 'winston', file: 'lib/winston/logger.js', versions: ['>=3'] }, Logger => {
|
|
12
|
+
const logCh = channel('apm:winston:log')
|
|
13
|
+
shimmer.wrap(Logger.prototype, 'write', write => {
|
|
14
|
+
return function wrappedWrite (chunk, enc, cb) {
|
|
15
|
+
if (logCh.hasSubscribers) {
|
|
16
|
+
const payload = { message: chunk }
|
|
17
|
+
logCh.publish(payload)
|
|
18
|
+
arguments[0] = payload.message
|
|
19
|
+
}
|
|
20
|
+
return write.apply(this, arguments)
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
return Logger
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
addHook({ name: 'winston', file: 'lib/winston/logger.js', versions: ['1', '2'] }, logger => {
|
|
27
|
+
const logCh = channel('apm:winston:log')
|
|
28
|
+
if (logger.Logger.prototype.configure) {
|
|
29
|
+
shimmer.wrap(logger.Logger.prototype, 'configure', configure => wrapMethod(configure, logCh))
|
|
30
|
+
}
|
|
31
|
+
shimmer.wrap(logger.Logger.prototype, 'add', configure => wrapMethod(configure, logCh))
|
|
32
|
+
return logger
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
function wrapMethod (method, logCh) {
|
|
36
|
+
return function methodWithTrace () {
|
|
37
|
+
const result = method.apply(this, arguments)
|
|
38
|
+
|
|
39
|
+
if (logCh.hasSubscribers) {
|
|
40
|
+
for (const name in this.transports) {
|
|
41
|
+
const transport = this.transports[name]
|
|
42
|
+
|
|
43
|
+
if (patched.has(transport) || typeof transport.log !== 'function') continue
|
|
44
|
+
|
|
45
|
+
const log = transport.log
|
|
46
|
+
transport.log = function wrappedLog (level, msg, meta, callback) {
|
|
47
|
+
const payload = { message: meta || {} }
|
|
48
|
+
logCh.publish(payload)
|
|
49
|
+
arguments[2] = payload.message
|
|
50
|
+
log.apply(this, arguments)
|
|
51
|
+
}
|
|
52
|
+
patched.add(transport)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return result
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -38,8 +38,8 @@ class Sns {
|
|
|
38
38
|
const ddInfo = {}
|
|
39
39
|
tracer.inject(span, 'text_map', ddInfo)
|
|
40
40
|
injectPath.MessageAttributes._datadog = {
|
|
41
|
-
DataType: '
|
|
42
|
-
|
|
41
|
+
DataType: 'Binary',
|
|
42
|
+
BinaryValue: JSON.stringify(ddInfo) // BINARY types are automatically base64 encoded
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -1,27 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const LogPlugin = require('../../dd-trace/src/plugins/log_plugin')
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return
|
|
8
|
-
const span = tracer.scope().active()
|
|
9
|
-
|
|
10
|
-
tracer.inject(span, LOG, rec)
|
|
11
|
-
|
|
12
|
-
return emit.apply(this, arguments)
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
module.exports = {
|
|
18
|
-
name: 'bunyan',
|
|
19
|
-
versions: ['>=1'],
|
|
20
|
-
patch (Logger, tracer, config) {
|
|
21
|
-
if (!tracer._logInjection) return
|
|
22
|
-
this.wrap(Logger.prototype, '_emit', createWrapEmit(tracer, config))
|
|
23
|
-
},
|
|
24
|
-
unpatch (Logger) {
|
|
25
|
-
this.unwrap(Logger.prototype, '_emit')
|
|
5
|
+
class BunyanPlugin extends LogPlugin {
|
|
6
|
+
static get name () {
|
|
7
|
+
return 'bunyan'
|
|
26
8
|
}
|
|
27
9
|
}
|
|
10
|
+
module.exports = BunyanPlugin
|
|
@@ -1,150 +1,105 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
4
|
+
const { storage } = require('../../datadog-core')
|
|
2
5
|
|
|
3
6
|
const {
|
|
7
|
+
CI_APP_ORIGIN,
|
|
4
8
|
TEST_TYPE,
|
|
5
9
|
TEST_NAME,
|
|
6
10
|
TEST_SUITE,
|
|
7
|
-
TEST_STATUS,
|
|
8
|
-
TEST_FRAMEWORK_VERSION,
|
|
9
11
|
TEST_SKIP_REASON,
|
|
10
|
-
|
|
12
|
+
TEST_FRAMEWORK_VERSION,
|
|
11
13
|
ERROR_MESSAGE,
|
|
12
|
-
|
|
14
|
+
TEST_STATUS,
|
|
13
15
|
finishAllTraceSpans,
|
|
16
|
+
getTestEnvironmentMetadata,
|
|
14
17
|
getTestSuitePath
|
|
15
18
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
19
|
+
const { SPAN_TYPE, RESOURCE_NAME } = require('../../../ext/tags')
|
|
20
|
+
const { SAMPLING_RULE_DECISION } = require('../../dd-trace/src/constants')
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} else if (result.status === 2) {
|
|
21
|
-
span.setTag(tag, 'skip')
|
|
22
|
-
} else if (result.status === 4) {
|
|
23
|
-
span.setTag(tag, 'skip')
|
|
24
|
-
span.setTag(TEST_SKIP_REASON, 'not implemented')
|
|
25
|
-
} else {
|
|
26
|
-
span.setTag(tag, 'fail')
|
|
27
|
-
span.setTag(ERROR_MESSAGE, result.message)
|
|
22
|
+
class CucumberPlugin extends Plugin {
|
|
23
|
+
static get name () {
|
|
24
|
+
return 'cucumber'
|
|
28
25
|
}
|
|
29
|
-
}
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
span.setTag(tag, 'pass')
|
|
34
|
-
} else if (result.status === 'SKIPPED' || result.status === 'PENDING') {
|
|
35
|
-
span.setTag(tag, 'skip')
|
|
36
|
-
} else if (result.status === 'UNDEFINED') {
|
|
37
|
-
span.setTag(tag, 'skip')
|
|
38
|
-
span.setTag(TEST_SKIP_REASON, 'not implemented')
|
|
39
|
-
} else {
|
|
40
|
-
span.setTag(tag, 'fail')
|
|
41
|
-
span.setTag(ERROR_MESSAGE, result.message)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
27
|
+
constructor (...args) {
|
|
28
|
+
super(...args)
|
|
44
29
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
[TEST_TYPE]: 'test',
|
|
53
|
-
[TEST_NAME]: testName,
|
|
54
|
-
[TEST_SUITE]: testSuite,
|
|
55
|
-
[SAMPLING_RULE_DECISION]: 1,
|
|
56
|
-
[TEST_FRAMEWORK_VERSION]: tracer._version,
|
|
57
|
-
...testEnvironmentMetadata
|
|
58
|
-
}
|
|
30
|
+
const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber', this.config)
|
|
31
|
+
const sourceRoot = process.cwd()
|
|
32
|
+
|
|
33
|
+
this.addSub('ci:cucumber:run:start', ({ pickleName, pickleUri }) => {
|
|
34
|
+
const store = storage.getStore()
|
|
35
|
+
const childOf = store ? store.span : store
|
|
36
|
+
const testSuite = getTestSuitePath(pickleUri, sourceRoot)
|
|
59
37
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
{
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
setStatus(testSpan, this.getWorstStepResult(), TEST_STATUS)
|
|
72
|
-
}).finally(() => {
|
|
73
|
-
finishAllTraceSpans(testSpan)
|
|
74
|
-
})
|
|
75
|
-
return promise
|
|
38
|
+
const span = this.tracer.startSpan('cucumber.test', {
|
|
39
|
+
childOf,
|
|
40
|
+
tags: {
|
|
41
|
+
[SPAN_TYPE]: 'test',
|
|
42
|
+
[RESOURCE_NAME]: pickleName,
|
|
43
|
+
[TEST_TYPE]: 'test',
|
|
44
|
+
[TEST_NAME]: pickleName,
|
|
45
|
+
[TEST_SUITE]: testSuite,
|
|
46
|
+
[SAMPLING_RULE_DECISION]: 1,
|
|
47
|
+
[TEST_FRAMEWORK_VERSION]: this.tracer._version,
|
|
48
|
+
...testEnvironmentMetadata
|
|
76
49
|
}
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
50
|
+
})
|
|
51
|
+
span.context()._trace.origin = CI_APP_ORIGIN
|
|
52
|
+
this.enter(span, store)
|
|
53
|
+
})
|
|
81
54
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return promise
|
|
55
|
+
this.addSub('ci:cucumber:run:end', () => {
|
|
56
|
+
this.exit()
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
this.addSub('ci:cucumber:run-step:start', ({ resource }) => {
|
|
60
|
+
const store = storage.getStore()
|
|
61
|
+
const childOf = store ? store.span : store
|
|
62
|
+
const span = this.tracer.startSpan('cucumber.step', {
|
|
63
|
+
childOf,
|
|
64
|
+
tags: {
|
|
65
|
+
'cucumber.step': resource,
|
|
66
|
+
[RESOURCE_NAME]: resource
|
|
95
67
|
}
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
68
|
+
})
|
|
69
|
+
this.enter(span, store)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
this.addSub('ci:cucumber:run-step:end', () => {
|
|
73
|
+
this.exit()
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
this.addSub('ci:cucumber:run:async-end', ({ isStep, status, skipReason, errorMessage }) => {
|
|
77
|
+
const span = storage.getStore().span
|
|
78
|
+
const statusTag = isStep ? 'step.status' : TEST_STATUS
|
|
79
|
+
|
|
80
|
+
span.setTag(statusTag, status)
|
|
100
81
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
name: '@cucumber/cucumber',
|
|
104
|
-
versions: ['7.0.0 - 7.2.1'],
|
|
105
|
-
file: 'lib/runtime/pickle_runner.js',
|
|
106
|
-
patch (PickleRunner, tracer, config) {
|
|
107
|
-
const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber', config)
|
|
108
|
-
const sourceRoot = process.cwd()
|
|
109
|
-
const pl = PickleRunner.default
|
|
110
|
-
this.wrap(
|
|
111
|
-
pl.prototype,
|
|
112
|
-
'run',
|
|
113
|
-
createWrapRun(tracer, testEnvironmentMetadata, sourceRoot, setStatusFromResult)
|
|
114
|
-
)
|
|
115
|
-
const getResourceName = (testStep) => {
|
|
116
|
-
return testStep.isHook ? 'hook' : testStep.pickleStep.text
|
|
82
|
+
if (skipReason) {
|
|
83
|
+
span.setTag(TEST_SKIP_REASON, skipReason)
|
|
117
84
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
{
|
|
127
|
-
name: '@cucumber/cucumber',
|
|
128
|
-
versions: ['>=7.3.0'],
|
|
129
|
-
file: 'lib/runtime/test_case_runner.js',
|
|
130
|
-
patch (TestCaseRunner, tracer, config) {
|
|
131
|
-
const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber', config)
|
|
132
|
-
const sourceRoot = process.cwd()
|
|
133
|
-
const pl = TestCaseRunner.default
|
|
134
|
-
this.wrap(
|
|
135
|
-
pl.prototype,
|
|
136
|
-
'run',
|
|
137
|
-
createWrapRun(tracer, testEnvironmentMetadata, sourceRoot, setStatusFromResultLatest)
|
|
138
|
-
)
|
|
139
|
-
const getResourceName = (testStep) => {
|
|
140
|
-
return testStep.text
|
|
85
|
+
|
|
86
|
+
if (errorMessage) {
|
|
87
|
+
span.setTag(ERROR_MESSAGE, errorMessage)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
span.finish()
|
|
91
|
+
if (!isStep) {
|
|
92
|
+
finishAllTraceSpans(span)
|
|
141
93
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
this.addSub('ci:cucumber:error', (err) => {
|
|
97
|
+
if (err) {
|
|
98
|
+
const span = storage.getStore().span
|
|
99
|
+
span.setTag('error', err)
|
|
100
|
+
}
|
|
101
|
+
})
|
|
149
102
|
}
|
|
150
|
-
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = CucumberPlugin
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
4
4
|
|
|
5
|
+
const messageSpans = new WeakMap()
|
|
6
|
+
|
|
5
7
|
function createWrapRequest (tracer, config) {
|
|
6
8
|
return function wrapRequest (request) {
|
|
7
9
|
return function requestWithTrace (cfg = { reqOpts: {} }, cb) {
|
|
@@ -45,11 +47,11 @@ function createWrapRequest (tracer, config) {
|
|
|
45
47
|
function createWrapSubscriptionEmit (tracer, config) {
|
|
46
48
|
return function wrapSubscriptionEmit (emit) {
|
|
47
49
|
return function emitWithTrace (eventName, message) {
|
|
48
|
-
if (eventName !== 'message' || !message
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
if (eventName !== 'message' || !message) return emit.apply(this, arguments)
|
|
51
|
+
|
|
52
|
+
const span = messageSpans.get(message)
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
if (!span) return emit.apply(this, arguments)
|
|
53
55
|
|
|
54
56
|
return tracer.scope().activate(span, () => {
|
|
55
57
|
try {
|
|
@@ -83,7 +85,7 @@ function createWrapLeaseDispense (tracer, config) {
|
|
|
83
85
|
|
|
84
86
|
analyticsSampler.sample(span, config.measured, true)
|
|
85
87
|
|
|
86
|
-
message
|
|
88
|
+
messageSpans.set(message, span)
|
|
87
89
|
|
|
88
90
|
return dispense.apply(this, arguments)
|
|
89
91
|
}
|
|
@@ -119,7 +121,7 @@ function getTopic (cfg) {
|
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
function finish (message) {
|
|
122
|
-
const span = message
|
|
124
|
+
const span = messageSpans.get(message)
|
|
123
125
|
|
|
124
126
|
if (!span) return
|
|
125
127
|
|
|
@@ -4,6 +4,11 @@ const pick = require('lodash.pick')
|
|
|
4
4
|
const log = require('../../dd-trace/src/log')
|
|
5
5
|
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
6
6
|
|
|
7
|
+
const contexts = new WeakMap()
|
|
8
|
+
const documentSources = new WeakMap()
|
|
9
|
+
const patchedTypes = new WeakSet()
|
|
10
|
+
const patchedResolvers = new WeakSet()
|
|
11
|
+
|
|
7
12
|
let tools
|
|
8
13
|
|
|
9
14
|
function createWrapExecute (tracer, config, defaultFieldResolver) {
|
|
@@ -12,11 +17,11 @@ function createWrapExecute (tracer, config, defaultFieldResolver) {
|
|
|
12
17
|
const args = normalizeArgs(arguments, tracer, config, defaultFieldResolver)
|
|
13
18
|
const schema = args.schema
|
|
14
19
|
const document = args.document
|
|
15
|
-
const source = document
|
|
20
|
+
const source = documentSources.get(document)
|
|
16
21
|
const contextValue = args.contextValue
|
|
17
22
|
const operation = getOperation(document, args.operationName)
|
|
18
23
|
|
|
19
|
-
if (contextValue
|
|
24
|
+
if (contexts.has(contextValue)) {
|
|
20
25
|
return execute.apply(this, arguments)
|
|
21
26
|
}
|
|
22
27
|
|
|
@@ -26,11 +31,12 @@ function createWrapExecute (tracer, config, defaultFieldResolver) {
|
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
const span = startExecutionSpan(tracer, config, operation, args)
|
|
34
|
+
const context = { source, span, fields: {} }
|
|
29
35
|
|
|
30
|
-
contextValue
|
|
36
|
+
contexts.set(contextValue, context)
|
|
31
37
|
|
|
32
38
|
return call(execute, span, this, arguments, (err, res) => {
|
|
33
|
-
finishResolvers(
|
|
39
|
+
finishResolvers(context)
|
|
34
40
|
|
|
35
41
|
setError(span, err || (res && res.errors && res.errors[0]))
|
|
36
42
|
config.hooks.execute(span, args, res)
|
|
@@ -55,7 +61,7 @@ function createWrapParse (tracer, config) {
|
|
|
55
61
|
if (!operation) return document // skip schema parsing
|
|
56
62
|
|
|
57
63
|
if (source) {
|
|
58
|
-
document
|
|
64
|
+
documentSources.set(document, source.body || source)
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
addDocumentTags(span, document, config)
|
|
@@ -103,11 +109,11 @@ function createWrapValidate (tracer, config) {
|
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
function wrapFields (type, tracer, config) {
|
|
106
|
-
if (!type || !type._fields || type
|
|
112
|
+
if (!type || !type._fields || patchedTypes.has(type)) {
|
|
107
113
|
return
|
|
108
114
|
}
|
|
109
115
|
|
|
110
|
-
type
|
|
116
|
+
patchedTypes.add(type)
|
|
111
117
|
|
|
112
118
|
Object.keys(type._fields).forEach(key => {
|
|
113
119
|
const field = type._fields[key]
|
|
@@ -136,14 +142,16 @@ function wrapFieldType (field, tracer, config) {
|
|
|
136
142
|
}
|
|
137
143
|
|
|
138
144
|
function wrapResolve (resolve, tracer, config) {
|
|
139
|
-
if (
|
|
145
|
+
if (typeof resolve !== 'function' || patchedResolvers.has(resolve)) return resolve
|
|
140
146
|
|
|
141
147
|
const responsePathAsArray = config.collapse
|
|
142
148
|
? withCollapse(pathToArray)
|
|
143
149
|
: pathToArray
|
|
144
150
|
|
|
145
151
|
function resolveWithTrace (source, args, contextValue, info) {
|
|
146
|
-
|
|
152
|
+
const context = contexts.get(contextValue)
|
|
153
|
+
|
|
154
|
+
if (!context) return resolve.apply(this, arguments)
|
|
147
155
|
|
|
148
156
|
const path = responsePathAsArray(info && info.path)
|
|
149
157
|
|
|
@@ -151,18 +159,18 @@ function wrapResolve (resolve, tracer, config) {
|
|
|
151
159
|
const depth = path.filter(item => typeof item === 'string').length
|
|
152
160
|
|
|
153
161
|
if (config.depth < depth) {
|
|
154
|
-
const parent = getParentField(tracer,
|
|
162
|
+
const parent = getParentField(tracer, context, path)
|
|
155
163
|
|
|
156
164
|
return call(resolve, parent.span, this, arguments)
|
|
157
165
|
}
|
|
158
166
|
}
|
|
159
167
|
|
|
160
|
-
const field = assertField(tracer, config,
|
|
168
|
+
const field = assertField(tracer, config, context, info, path)
|
|
161
169
|
|
|
162
170
|
return call(resolve, field.span, this, arguments, err => updateField(field, err))
|
|
163
171
|
}
|
|
164
172
|
|
|
165
|
-
resolveWithTrace
|
|
173
|
+
patchedResolvers.add(resolveWithTrace)
|
|
166
174
|
|
|
167
175
|
return resolveWithTrace
|
|
168
176
|
}
|
|
@@ -191,9 +199,9 @@ function call (fn, span, thisArg, args, callback) {
|
|
|
191
199
|
}
|
|
192
200
|
}
|
|
193
201
|
|
|
194
|
-
function getParentField (tracer,
|
|
202
|
+
function getParentField (tracer, context, path) {
|
|
195
203
|
for (let i = path.length - 1; i > 0; i--) {
|
|
196
|
-
const field = getField(
|
|
204
|
+
const field = getField(context, path.slice(0, i))
|
|
197
205
|
|
|
198
206
|
if (field) {
|
|
199
207
|
return field
|
|
@@ -201,12 +209,12 @@ function getParentField (tracer, contextValue, path) {
|
|
|
201
209
|
}
|
|
202
210
|
|
|
203
211
|
return {
|
|
204
|
-
span:
|
|
212
|
+
span: context.span
|
|
205
213
|
}
|
|
206
214
|
}
|
|
207
215
|
|
|
208
|
-
function getField (
|
|
209
|
-
return
|
|
216
|
+
function getField (context, path) {
|
|
217
|
+
return context.fields[path.join('.')]
|
|
210
218
|
}
|
|
211
219
|
|
|
212
220
|
function normalizeArgs (args, tracer, config, defaultFieldResolver) {
|
|
@@ -267,8 +275,8 @@ function addExecutionTags (span, config, operation, document, operationName) {
|
|
|
267
275
|
function addDocumentTags (span, document, config) {
|
|
268
276
|
const tags = {}
|
|
269
277
|
|
|
270
|
-
if (config.source && document
|
|
271
|
-
tags['graphql.source'] = document
|
|
278
|
+
if (config.source && document) {
|
|
279
|
+
tags['graphql.source'] = documentSources.get(document)
|
|
272
280
|
}
|
|
273
281
|
|
|
274
282
|
span.addTags(tags)
|
|
@@ -300,9 +308,9 @@ function startSpan (tracer, config, name, options) {
|
|
|
300
308
|
})
|
|
301
309
|
}
|
|
302
310
|
|
|
303
|
-
function startResolveSpan (tracer, config, childOf, path, info,
|
|
311
|
+
function startResolveSpan (tracer, config, childOf, path, info, { source }) {
|
|
304
312
|
const span = startSpan(tracer, config, 'resolve', { childOf })
|
|
305
|
-
const document =
|
|
313
|
+
const document = source
|
|
306
314
|
const fieldNode = info.fieldNodes.find(fieldNode => fieldNode.kind === 'Field')
|
|
307
315
|
|
|
308
316
|
analyticsSampler.sample(span, config.measured)
|
|
@@ -345,9 +353,7 @@ function finish (span, finishTime) {
|
|
|
345
353
|
span.finish(finishTime)
|
|
346
354
|
}
|
|
347
355
|
|
|
348
|
-
function finishResolvers (
|
|
349
|
-
const fields = contextValue._datadog_graphql.fields
|
|
350
|
-
|
|
356
|
+
function finishResolvers ({ fields }) {
|
|
351
357
|
Object.keys(fields).reverse().forEach(key => {
|
|
352
358
|
const field = fields[key]
|
|
353
359
|
|
|
@@ -369,18 +375,18 @@ function withCollapse (responsePathAsArray) {
|
|
|
369
375
|
}
|
|
370
376
|
}
|
|
371
377
|
|
|
372
|
-
function assertField (tracer, config,
|
|
378
|
+
function assertField (tracer, config, context, info, path) {
|
|
373
379
|
const pathString = path.join('.')
|
|
374
|
-
const fields =
|
|
380
|
+
const fields = context.fields
|
|
375
381
|
|
|
376
382
|
let field = fields[pathString]
|
|
377
383
|
|
|
378
384
|
if (!field) {
|
|
379
|
-
const parent = getParentField(tracer,
|
|
385
|
+
const parent = getParentField(tracer, context, path)
|
|
380
386
|
|
|
381
387
|
field = fields[pathString] = {
|
|
382
388
|
parent,
|
|
383
|
-
span: startResolveSpan(tracer, config, parent.span, path, info,
|
|
389
|
+
span: startResolveSpan(tracer, config, parent.span, path, info, context),
|
|
384
390
|
error: null
|
|
385
391
|
}
|
|
386
392
|
}
|