dd-trace 2.4.2 → 2.7.0
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 +1 -2
- package/ci/init.js +6 -0
- package/ci/jest/env.js +16 -3
- package/ext/exporters.d.ts +2 -1
- package/ext/exporters.js +2 -1
- package/index.d.ts +17 -8
- package/package.json +20 -23
- package/packages/datadog-instrumentations/index.js +14 -0
- package/packages/datadog-instrumentations/src/connect.js +111 -0
- package/packages/datadog-instrumentations/src/cypress.js +8 -0
- package/packages/datadog-instrumentations/src/express.js +27 -0
- package/packages/datadog-instrumentations/src/fastify.js +187 -0
- package/packages/datadog-instrumentations/src/find-my-way.js +30 -0
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +100 -0
- package/packages/datadog-instrumentations/src/http/server.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +175 -0
- package/packages/datadog-instrumentations/src/kafkajs.js +112 -0
- package/packages/datadog-instrumentations/src/knex.js +20 -0
- package/packages/datadog-instrumentations/src/koa.js +159 -0
- package/packages/datadog-instrumentations/src/limitd-client.js +21 -0
- package/packages/datadog-instrumentations/src/oracledb.js +128 -0
- package/packages/datadog-instrumentations/src/paperplane.js +77 -0
- package/packages/datadog-instrumentations/src/pg.js +2 -2
- package/packages/datadog-instrumentations/src/restify.js +58 -0
- package/packages/datadog-instrumentations/src/rhea.js +1 -1
- package/packages/datadog-instrumentations/src/router.js +177 -0
- package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -4
- package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
- package/packages/datadog-plugin-connect/src/index.js +10 -114
- package/packages/datadog-plugin-cucumber/src/index.js +16 -16
- package/packages/datadog-plugin-cypress/src/index.js +10 -5
- package/packages/datadog-plugin-cypress/src/plugin.js +18 -17
- package/packages/datadog-plugin-dns/src/index.js +12 -1
- package/packages/datadog-plugin-express/src/index.js +11 -25
- package/packages/datadog-plugin-fastify/src/index.js +17 -4
- package/packages/datadog-plugin-find-my-way/src/index.js +20 -0
- package/packages/datadog-plugin-fs/src/index.js +2 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +56 -111
- package/packages/datadog-plugin-http/src/server.js +2 -10
- package/packages/datadog-plugin-jest/src/index.js +101 -3
- package/packages/datadog-plugin-jest/src/util.js +1 -29
- package/packages/datadog-plugin-kafkajs/src/index.js +64 -90
- package/packages/datadog-plugin-koa/src/index.js +12 -164
- package/packages/datadog-plugin-mocha/src/index.js +14 -15
- package/packages/datadog-plugin-oracledb/src/index.js +34 -100
- package/packages/datadog-plugin-paperplane/src/index.js +14 -100
- package/packages/datadog-plugin-paperplane/src/logger.js +11 -0
- package/packages/datadog-plugin-paperplane/src/server.js +24 -0
- package/packages/datadog-plugin-restify/src/index.js +13 -75
- package/packages/datadog-plugin-router/src/index.js +67 -164
- package/packages/datadog-plugin-web/src/index.js +20 -0
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +34 -12
- package/packages/dd-trace/src/appsec/index.js +7 -3
- package/packages/dd-trace/src/appsec/recommended.json +15 -5
- package/packages/dd-trace/src/appsec/reporter.js +33 -3
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +32 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +51 -0
- package/packages/dd-trace/src/config.js +33 -4
- package/packages/dd-trace/src/encode/0.4.js +0 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +193 -0
- package/packages/dd-trace/src/encode/tags-processors.js +116 -0
- package/packages/dd-trace/src/exporter.js +3 -0
- package/packages/dd-trace/src/exporters/agent/index.js +1 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +7 -32
- package/packages/dd-trace/src/exporters/{agent → common}/docker.js +0 -0
- package/packages/dd-trace/src/exporters/common/request.js +83 -0
- package/packages/dd-trace/src/exporters/common/writer.js +36 -0
- package/packages/dd-trace/src/exporters/{agent/scheduler.js → scheduler.js} +0 -0
- package/packages/dd-trace/src/format.js +9 -5
- package/packages/dd-trace/src/instrumenter.js +3 -0
- package/packages/dd-trace/src/pkg.js +11 -6
- package/packages/dd-trace/src/plugin_manager.js +13 -7
- package/packages/dd-trace/src/plugins/index.js +1 -2
- package/packages/dd-trace/src/plugins/log_plugin.js +8 -4
- package/packages/dd-trace/src/plugins/plugin.js +8 -0
- package/packages/dd-trace/src/plugins/util/test.js +79 -1
- package/packages/dd-trace/src/plugins/util/web.js +41 -12
- package/packages/dd-trace/src/profiling/config.js +8 -8
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/index.js +4 -4
- package/packages/dd-trace/src/profiling/profilers/{heap.js → space.js} +2 -2
- package/packages/dd-trace/src/profiling/profilers/{cpu.js → wall.js} +3 -3
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/span_processor.js +4 -1
- package/packages/dd-trace/src/telemetry.js +187 -0
- package/scripts/install_plugin_modules.js +1 -0
- package/packages/datadog-plugin-fastify/src/fastify.js +0 -198
- package/packages/datadog-plugin-fastify/src/find-my-way.js +0 -37
- package/packages/datadog-plugin-jest/src/jest-environment.js +0 -272
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +0 -185
- package/packages/datadog-plugin-knex/src/index.js +0 -23
- package/packages/datadog-plugin-limitd-client/src/index.js +0 -30
- package/packages/dd-trace/src/exporters/agent/request.js +0 -86
- package/scripts/postpublish.js +0 -24
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook,
|
|
6
|
+
AsyncResource
|
|
7
|
+
} = require('./helpers/instrument')
|
|
8
|
+
const shimmer = require('../../datadog-shimmer')
|
|
9
|
+
|
|
10
|
+
const requestStartCh = channel('apm:google-cloud-pubsub:request:start')
|
|
11
|
+
const requestFinishCh = channel('apm:google-cloud-pubsub:request:finish')
|
|
12
|
+
const requestErrorCh = channel('apm:google-cloud-pubsub:request:error')
|
|
13
|
+
|
|
14
|
+
const receiveStartCh = channel(`apm:google-cloud-pubsub:receive:start`)
|
|
15
|
+
const receiveFinishCh = channel('apm:google-cloud-pubsub:receive:finish')
|
|
16
|
+
const receiveErrorCh = channel('apm:google-cloud-pubsub:receive:error')
|
|
17
|
+
|
|
18
|
+
addHook({ name: '@google-cloud/pubsub', versions: ['>=1.2'] }, (obj) => {
|
|
19
|
+
const PubSub = obj.PubSub
|
|
20
|
+
const Subscription = obj.Subscription
|
|
21
|
+
|
|
22
|
+
shimmer.wrap(PubSub.prototype, 'request', request => function (cfg = { reqOpts: {} }, cb) {
|
|
23
|
+
if (!requestStartCh.hasSubscribers) {
|
|
24
|
+
return request.apply(this, arguments)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const innerAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
28
|
+
const outerAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
29
|
+
|
|
30
|
+
return innerAsyncResource.runInAsyncScope(() => {
|
|
31
|
+
let messages = []
|
|
32
|
+
if (cfg.reqOpts && cfg.method === 'publish') {
|
|
33
|
+
messages = cfg.reqOpts.messages
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
requestStartCh.publish({ cfg, projectId: this.projectId, messages })
|
|
37
|
+
cb = outerAsyncResource.bind(cb)
|
|
38
|
+
|
|
39
|
+
const fn = () => {
|
|
40
|
+
arguments[1] = innerAsyncResource.bind(function (error) {
|
|
41
|
+
if (error) {
|
|
42
|
+
requestErrorCh.publish(error)
|
|
43
|
+
}
|
|
44
|
+
requestFinishCh.publish(undefined)
|
|
45
|
+
return cb.apply(this, arguments)
|
|
46
|
+
})
|
|
47
|
+
return request.apply(this, arguments)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
return fn.apply(this, arguments)
|
|
52
|
+
} catch (e) {
|
|
53
|
+
requestErrorCh.publish(e)
|
|
54
|
+
throw e
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
shimmer.wrap(Subscription.prototype, 'emit', emit => function (eventName, message) {
|
|
60
|
+
if (eventName !== 'message' || !message) return emit.apply(this, arguments)
|
|
61
|
+
|
|
62
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
63
|
+
|
|
64
|
+
return asyncResource.runInAsyncScope(() => {
|
|
65
|
+
try {
|
|
66
|
+
return emit.apply(this, arguments)
|
|
67
|
+
} catch (err) {
|
|
68
|
+
receiveErrorCh.publish({ err, message })
|
|
69
|
+
throw err
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
return obj
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
addHook({ name: '@google-cloud/pubsub', versions: ['>=1.2'], file: 'build/src/lease-manager.js' }, (obj) => {
|
|
78
|
+
const LeaseManager = obj.LeaseManager
|
|
79
|
+
|
|
80
|
+
shimmer.wrap(LeaseManager.prototype, '_dispense', dispense => function (message) {
|
|
81
|
+
if (receiveStartCh.hasSubscribers) {
|
|
82
|
+
receiveStartCh.publish({ message })
|
|
83
|
+
}
|
|
84
|
+
return dispense.apply(this, arguments)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
shimmer.wrap(LeaseManager.prototype, 'remove', remove => function (message) {
|
|
88
|
+
receiveFinishCh.publish({ message })
|
|
89
|
+
return remove.apply(this, arguments)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
shimmer.wrap(LeaseManager.prototype, 'clear', clear => function () {
|
|
93
|
+
for (const message of this._messages) {
|
|
94
|
+
receiveFinishCh.publish({ message })
|
|
95
|
+
}
|
|
96
|
+
return clear.apply(this, arguments)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
return obj
|
|
100
|
+
})
|
|
@@ -9,7 +9,7 @@ const shimmer = require('../../../datadog-shimmer')
|
|
|
9
9
|
const startServerCh = channel('apm:http:server:request:start')
|
|
10
10
|
const endServerCh = channel('apm:http:server:request:end')
|
|
11
11
|
const errorServerCh = channel('apm:http:server:request:error')
|
|
12
|
-
const asyncEndServerCh = channel('apm:http:server:request:
|
|
12
|
+
const asyncEndServerCh = channel('apm:http:server:request:finish')
|
|
13
13
|
|
|
14
14
|
addHook({ name: 'https' }, http => {
|
|
15
15
|
// http.ServerResponse not present on https
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
|
|
6
|
+
const testStartCh = channel('ci:jest:test:start')
|
|
7
|
+
const testSkippedCh = channel('ci:jest:test:skip')
|
|
8
|
+
const testRunEndCh = channel('ci:jest:test:end')
|
|
9
|
+
const testErrCh = channel('ci:jest:test:err')
|
|
10
|
+
const testSuiteEnd = channel('ci:jest:test-suite:end')
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
getTestSuitePath,
|
|
14
|
+
getTestParametersString
|
|
15
|
+
} = require('../../dd-trace/src/plugins/util/test')
|
|
16
|
+
|
|
17
|
+
const { getFormattedJestTestParameters } = require('../../datadog-plugin-jest/src/util')
|
|
18
|
+
|
|
19
|
+
const specStatusToTestStatus = {
|
|
20
|
+
'pending': 'skip',
|
|
21
|
+
'disabled': 'skip',
|
|
22
|
+
'todo': 'skip',
|
|
23
|
+
'passed': 'pass',
|
|
24
|
+
'failed': 'fail'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const asyncResources = new WeakMap()
|
|
28
|
+
const originalTestFns = new WeakMap()
|
|
29
|
+
|
|
30
|
+
// based on https://github.com/facebook/jest/blob/main/packages/jest-circus/src/formatNodeAssertErrors.ts#L41
|
|
31
|
+
function formatJestError (errors) {
|
|
32
|
+
let error
|
|
33
|
+
if (Array.isArray(errors)) {
|
|
34
|
+
const [originalError, asyncError] = errors
|
|
35
|
+
if (originalError === null || !originalError.stack) {
|
|
36
|
+
error = asyncError
|
|
37
|
+
error.message = originalError
|
|
38
|
+
} else {
|
|
39
|
+
error = originalError
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
error = errors
|
|
43
|
+
}
|
|
44
|
+
return error
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getWrappedEnvironment (BaseEnvironment) {
|
|
48
|
+
return class DatadogEnvironment extends BaseEnvironment {
|
|
49
|
+
constructor (config, context) {
|
|
50
|
+
super(config, context)
|
|
51
|
+
const rootDir = config.globalConfig ? config.globalConfig.rootDir : config.rootDir
|
|
52
|
+
this.testSuite = getTestSuitePath(context.testPath, rootDir)
|
|
53
|
+
this.nameToParams = {}
|
|
54
|
+
this.global._ddtrace = global._ddtrace
|
|
55
|
+
}
|
|
56
|
+
async teardown () {
|
|
57
|
+
super.teardown().finally(() => {
|
|
58
|
+
testSuiteEnd.publish()
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async handleTestEvent (event, state) {
|
|
63
|
+
if (super.handleTestEvent) {
|
|
64
|
+
await super.handleTestEvent(event, state)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const globalExpect = this.global.expect
|
|
68
|
+
const setNameToParams = (name, params) => { this.nameToParams[name] = params }
|
|
69
|
+
|
|
70
|
+
if (event.name === 'setup') {
|
|
71
|
+
shimmer.wrap(this.global.test, 'each', each => function () {
|
|
72
|
+
const testParameters = getFormattedJestTestParameters(arguments)
|
|
73
|
+
const eachBind = each.apply(this, arguments)
|
|
74
|
+
return function () {
|
|
75
|
+
const [testName] = arguments
|
|
76
|
+
setNameToParams(testName, testParameters)
|
|
77
|
+
return eachBind.apply(this, arguments)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
if (event.name === 'test_start') {
|
|
82
|
+
const testParameters = getTestParametersString(this.nameToParams, event.test.name)
|
|
83
|
+
|
|
84
|
+
// Async resource for this test is created here
|
|
85
|
+
// It is used later on by the test_done handler
|
|
86
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
87
|
+
asyncResources.set(event.test, asyncResource)
|
|
88
|
+
asyncResource.runInAsyncScope(() => {
|
|
89
|
+
testStartCh.publish({
|
|
90
|
+
name: globalExpect.getState().currentTestName,
|
|
91
|
+
suite: this.testSuite,
|
|
92
|
+
runner: 'jest-circus',
|
|
93
|
+
testParameters
|
|
94
|
+
})
|
|
95
|
+
originalTestFns.set(event.test, event.test.fn)
|
|
96
|
+
event.test.fn = asyncResource.bind(event.test.fn)
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
if (event.name === 'test_done') {
|
|
100
|
+
const asyncResource = asyncResources.get(event.test)
|
|
101
|
+
asyncResource.runInAsyncScope(() => {
|
|
102
|
+
let status = 'pass'
|
|
103
|
+
if (event.test.errors && event.test.errors.length) {
|
|
104
|
+
status = 'fail'
|
|
105
|
+
const formattedError = formatJestError(event.test.errors[0])
|
|
106
|
+
testErrCh.publish(formattedError)
|
|
107
|
+
}
|
|
108
|
+
testRunEndCh.publish(status)
|
|
109
|
+
// restore in case it is retried
|
|
110
|
+
event.test.fn = originalTestFns.get(event.test)
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
if (event.name === 'test_skip' || event.name === 'test_todo') {
|
|
114
|
+
testSkippedCh.publish({
|
|
115
|
+
name: globalExpect.getState().currentTestName,
|
|
116
|
+
suite: this.testSuite,
|
|
117
|
+
runner: 'jest-circus'
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function getTestEnvironment (pkg) {
|
|
125
|
+
if (pkg.default) {
|
|
126
|
+
const wrappedTestEnvironment = getWrappedEnvironment(pkg.default)
|
|
127
|
+
pkg.default = wrappedTestEnvironment
|
|
128
|
+
pkg.TestEnvironment = wrappedTestEnvironment
|
|
129
|
+
return pkg
|
|
130
|
+
}
|
|
131
|
+
return getWrappedEnvironment(pkg)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
addHook({
|
|
135
|
+
name: 'jest-environment-node',
|
|
136
|
+
versions: ['>=24.8.0']
|
|
137
|
+
}, getTestEnvironment)
|
|
138
|
+
|
|
139
|
+
addHook({
|
|
140
|
+
name: 'jest-environment-jsdom',
|
|
141
|
+
versions: ['>=24.8.0']
|
|
142
|
+
}, getTestEnvironment)
|
|
143
|
+
|
|
144
|
+
addHook({
|
|
145
|
+
name: 'jest-jasmine2',
|
|
146
|
+
versions: ['>=24.8.0'],
|
|
147
|
+
file: 'build/jasmineAsyncInstall.js'
|
|
148
|
+
}, (jasmineAsyncInstallExport) => {
|
|
149
|
+
return function (globalConfig, globalInput) {
|
|
150
|
+
globalInput._ddtrace = global._ddtrace
|
|
151
|
+
shimmer.wrap(globalInput.jasmine.Spec.prototype, 'execute', execute => function (onComplete) {
|
|
152
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
153
|
+
asyncResource.runInAsyncScope(() => {
|
|
154
|
+
const testSuite = getTestSuitePath(this.result.testPath, globalConfig.rootDir)
|
|
155
|
+
testStartCh.publish({
|
|
156
|
+
name: this.getFullName(),
|
|
157
|
+
suite: testSuite,
|
|
158
|
+
runner: 'jest-jasmine2'
|
|
159
|
+
})
|
|
160
|
+
const spec = this
|
|
161
|
+
const callback = asyncResource.bind(function () {
|
|
162
|
+
if (spec.result.failedExpectations && spec.result.failedExpectations.length) {
|
|
163
|
+
const formattedError = formatJestError(spec.result.failedExpectations[0].error)
|
|
164
|
+
testErrCh.publish(formattedError)
|
|
165
|
+
}
|
|
166
|
+
testRunEndCh.publish(specStatusToTestStatus[spec.result.status])
|
|
167
|
+
onComplete.apply(this, arguments)
|
|
168
|
+
})
|
|
169
|
+
arguments[0] = callback
|
|
170
|
+
execute.apply(this, arguments)
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
return jasmineAsyncInstallExport.default(globalConfig, globalInput)
|
|
174
|
+
}
|
|
175
|
+
})
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook,
|
|
6
|
+
AsyncResource
|
|
7
|
+
} = require('./helpers/instrument')
|
|
8
|
+
const shimmer = require('../../datadog-shimmer')
|
|
9
|
+
|
|
10
|
+
const producerStartCh = channel('apm:kafkajs:produce:start')
|
|
11
|
+
const producerFinishCh = channel('apm:kafkajs:produce:finish')
|
|
12
|
+
const producerErrorCh = channel('apm:kafkajs:produce:error')
|
|
13
|
+
|
|
14
|
+
const consumerStartCh = channel('apm:kafkajs:consume:start')
|
|
15
|
+
const consumerFinishCh = channel('apm:kafkajs:consume:finish')
|
|
16
|
+
const consumerErrorCh = channel('apm:kafkajs:consume:error')
|
|
17
|
+
|
|
18
|
+
addHook({ name: 'kafkajs', versions: ['>=1.4'] }, (obj) => {
|
|
19
|
+
const Kafka = obj.Kafka
|
|
20
|
+
shimmer.wrap(Kafka.prototype, 'producer', createProducer => function () {
|
|
21
|
+
const producer = createProducer.apply(this, arguments)
|
|
22
|
+
const send = producer.send
|
|
23
|
+
|
|
24
|
+
producer.send = function () {
|
|
25
|
+
const innerAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
26
|
+
|
|
27
|
+
return innerAsyncResource.runInAsyncScope(() => {
|
|
28
|
+
if (!producerStartCh.hasSubscribers) {
|
|
29
|
+
return send.apply(this, arguments)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const { topic, messages = [] } = arguments[0]
|
|
34
|
+
for (const message of messages) {
|
|
35
|
+
if (typeof message === 'object') {
|
|
36
|
+
message.headers = message.headers || {}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
producerStartCh.publish({ topic, messages })
|
|
40
|
+
|
|
41
|
+
const result = send.apply(this, arguments)
|
|
42
|
+
|
|
43
|
+
result.then(
|
|
44
|
+
innerAsyncResource.bind(() => producerFinishCh.publish(undefined)),
|
|
45
|
+
innerAsyncResource.bind(err => {
|
|
46
|
+
if (err) {
|
|
47
|
+
producerErrorCh.publish(err)
|
|
48
|
+
}
|
|
49
|
+
producerFinishCh.publish(undefined)
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return result
|
|
54
|
+
} catch (e) {
|
|
55
|
+
producerErrorCh.publish(e)
|
|
56
|
+
producerFinishCh.publish(undefined)
|
|
57
|
+
throw e
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
return producer
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
shimmer.wrap(Kafka.prototype, 'consumer', createConsumer => function () {
|
|
65
|
+
if (!consumerStartCh.hasSubscribers) {
|
|
66
|
+
return createConsumer.apply(this, arguments)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const consumer = createConsumer.apply(this, arguments)
|
|
70
|
+
const run = consumer.run
|
|
71
|
+
|
|
72
|
+
consumer.run = function ({ eachMessage, ...runArgs }) {
|
|
73
|
+
if (typeof eachMessage !== 'function') return run({ eachMessage, ...runArgs })
|
|
74
|
+
|
|
75
|
+
return run({
|
|
76
|
+
eachMessage: function (...eachMessageArgs) {
|
|
77
|
+
const innerAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
78
|
+
return innerAsyncResource.runInAsyncScope(() => {
|
|
79
|
+
const { topic, partition, message } = eachMessageArgs[0]
|
|
80
|
+
consumerStartCh.publish({ topic, partition, message })
|
|
81
|
+
try {
|
|
82
|
+
const result = eachMessage.apply(this, eachMessageArgs)
|
|
83
|
+
|
|
84
|
+
if (result && typeof result.then === 'function') {
|
|
85
|
+
result.then(
|
|
86
|
+
innerAsyncResource.bind(() => consumerFinishCh.publish(undefined)),
|
|
87
|
+
innerAsyncResource.bind(err => {
|
|
88
|
+
if (err) {
|
|
89
|
+
consumerErrorCh.publish(err)
|
|
90
|
+
}
|
|
91
|
+
consumerFinishCh.publish(undefined)
|
|
92
|
+
})
|
|
93
|
+
)
|
|
94
|
+
} else {
|
|
95
|
+
consumerFinishCh.publish(undefined)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return result
|
|
99
|
+
} catch (e) {
|
|
100
|
+
consumerErrorCh.publish(e)
|
|
101
|
+
consumerFinishCh.publish(undefined)
|
|
102
|
+
throw e
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
},
|
|
106
|
+
...runArgs
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
return consumer
|
|
110
|
+
})
|
|
111
|
+
return obj
|
|
112
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { addHook } = require('./helpers/instrument')
|
|
4
|
+
const { wrapThen } = require('./helpers/promise')
|
|
5
|
+
const shimmer = require('../../datadog-shimmer')
|
|
6
|
+
|
|
7
|
+
patch('lib/query/builder.js')
|
|
8
|
+
patch('lib/raw.js')
|
|
9
|
+
patch('lib/schema/builder.js')
|
|
10
|
+
|
|
11
|
+
function patch (file) {
|
|
12
|
+
addHook({
|
|
13
|
+
name: 'knex',
|
|
14
|
+
versions: ['>=0.8.0'],
|
|
15
|
+
file
|
|
16
|
+
}, Builder => {
|
|
17
|
+
shimmer.wrap(Builder.prototype, 'then', wrapThen)
|
|
18
|
+
return Builder
|
|
19
|
+
})
|
|
20
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../datadog-shimmer')
|
|
4
|
+
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
5
|
+
|
|
6
|
+
const enterChannel = channel('apm:koa:middleware:enter')
|
|
7
|
+
const errorChannel = channel('apm:koa:middleware:error')
|
|
8
|
+
const exitChannel = channel('apm:koa:middleware:exit')
|
|
9
|
+
const handleChannel = channel('apm:koa:request:handle')
|
|
10
|
+
const routeChannel = channel('apm:koa:request:route')
|
|
11
|
+
|
|
12
|
+
const originals = new WeakMap()
|
|
13
|
+
|
|
14
|
+
function wrapCallback (callback) {
|
|
15
|
+
return function callbackWithTrace () {
|
|
16
|
+
const handleRequest = callback.apply(this, arguments)
|
|
17
|
+
|
|
18
|
+
if (typeof handleRequest !== 'function') return handleRequest
|
|
19
|
+
|
|
20
|
+
return function handleRequestWithTrace (req, res) {
|
|
21
|
+
handleChannel.publish({ req, res })
|
|
22
|
+
|
|
23
|
+
return handleRequest.apply(this, arguments)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function wrapUse (use) {
|
|
29
|
+
return function useWithTrace () {
|
|
30
|
+
const result = use.apply(this, arguments)
|
|
31
|
+
|
|
32
|
+
if (!Array.isArray(this.middleware)) return result
|
|
33
|
+
|
|
34
|
+
const fn = this.middleware.pop()
|
|
35
|
+
|
|
36
|
+
this.middleware.push(wrapMiddleware(fn))
|
|
37
|
+
|
|
38
|
+
return result
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function wrapRegister (register) {
|
|
43
|
+
return function registerWithTrace (path, methods, middleware, opts) {
|
|
44
|
+
const route = register.apply(this, arguments)
|
|
45
|
+
|
|
46
|
+
if (!Array.isArray(path) && route && Array.isArray(route.stack)) {
|
|
47
|
+
wrapStack(route)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return route
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function wrapRouterUse (use) {
|
|
55
|
+
return function useWithTrace () {
|
|
56
|
+
const router = use.apply(this, arguments)
|
|
57
|
+
|
|
58
|
+
router.stack.forEach(wrapStack)
|
|
59
|
+
|
|
60
|
+
return router
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function wrapStack (layer) {
|
|
65
|
+
layer.stack = layer.stack.map(middleware => {
|
|
66
|
+
if (typeof middleware !== 'function') return middleware
|
|
67
|
+
|
|
68
|
+
const original = originals.get(middleware)
|
|
69
|
+
|
|
70
|
+
middleware = original || middleware
|
|
71
|
+
|
|
72
|
+
const handler = shimmer.wrap(middleware, wrapMiddleware(middleware, layer))
|
|
73
|
+
|
|
74
|
+
originals.set(handler, middleware)
|
|
75
|
+
|
|
76
|
+
return handler
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function wrapMiddleware (fn, layer) {
|
|
81
|
+
if (typeof fn !== 'function') return fn
|
|
82
|
+
|
|
83
|
+
const name = fn.name
|
|
84
|
+
|
|
85
|
+
return function (ctx, next) {
|
|
86
|
+
if (!ctx || !enterChannel.hasSubscribers) return fn.apply(this, arguments)
|
|
87
|
+
|
|
88
|
+
const middlewareResource = new AsyncResource('bound-anonymous-fn')
|
|
89
|
+
const req = ctx.req
|
|
90
|
+
|
|
91
|
+
return middlewareResource.runInAsyncScope(() => {
|
|
92
|
+
enterChannel.publish({ req, name })
|
|
93
|
+
|
|
94
|
+
if (typeof next === 'function') {
|
|
95
|
+
arguments[1] = AsyncResource.bind(next)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
const result = fn.apply(this, arguments)
|
|
100
|
+
|
|
101
|
+
if (result && typeof result.then === 'function') {
|
|
102
|
+
return result.then(
|
|
103
|
+
result => {
|
|
104
|
+
exit(ctx, layer)
|
|
105
|
+
return result
|
|
106
|
+
},
|
|
107
|
+
err => {
|
|
108
|
+
exit(ctx, layer, err)
|
|
109
|
+
throw err
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
} else {
|
|
113
|
+
exit(ctx, layer)
|
|
114
|
+
return result
|
|
115
|
+
}
|
|
116
|
+
} catch (e) {
|
|
117
|
+
exit(ctx, layer, e)
|
|
118
|
+
throw e
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function exit (ctx, layer, error) {
|
|
125
|
+
if (error) {
|
|
126
|
+
errorChannel.publish(error)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const req = ctx.req
|
|
130
|
+
const route = ctx.routePath || (layer && layer.path)
|
|
131
|
+
|
|
132
|
+
// TODO: make sure that the parent class cannot override this in `enter`
|
|
133
|
+
if (route) {
|
|
134
|
+
routeChannel.publish({ req, route })
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
exitChannel.publish(ctx)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
addHook({ name: 'koa', versions: ['>=2'] }, Koa => {
|
|
141
|
+
shimmer.wrap(Koa.prototype, 'callback', wrapCallback)
|
|
142
|
+
shimmer.wrap(Koa.prototype, 'use', wrapUse)
|
|
143
|
+
|
|
144
|
+
return Koa
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
addHook({ name: '@koa/router', versions: ['>=8'] }, Router => {
|
|
148
|
+
shimmer.wrap(Router.prototype, 'register', wrapRegister)
|
|
149
|
+
shimmer.wrap(Router.prototype, 'use', wrapRouterUse)
|
|
150
|
+
|
|
151
|
+
return Router
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
addHook({ name: 'koa-router', versions: ['>=7'] }, Router => {
|
|
155
|
+
shimmer.wrap(Router.prototype, 'register', wrapRegister)
|
|
156
|
+
shimmer.wrap(Router.prototype, 'use', wrapRouterUse)
|
|
157
|
+
|
|
158
|
+
return Router
|
|
159
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { addHook, AsyncResource } = require('./helpers/instrument')
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
|
|
6
|
+
function wrapRequest (original) {
|
|
7
|
+
return function () {
|
|
8
|
+
const id = arguments.length - 1
|
|
9
|
+
arguments[id] = AsyncResource.bind(arguments[id])
|
|
10
|
+
return original.apply(this, arguments)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
addHook({
|
|
15
|
+
name: 'limitd-client',
|
|
16
|
+
versions: ['>=2.8']
|
|
17
|
+
}, LimitdClient => {
|
|
18
|
+
shimmer.wrap(LimitdClient.prototype, '_directRequest', wrapRequest)
|
|
19
|
+
shimmer.wrap(LimitdClient.prototype, '_retriedRequest', wrapRequest)
|
|
20
|
+
return LimitdClient
|
|
21
|
+
})
|