dd-trace 2.8.0 → 2.10.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/ci/init.js +22 -6
- package/ci/jest/env.js +19 -7
- package/ext/tags.d.ts +1 -0
- package/ext/tags.js +2 -1
- package/index.d.ts +4 -2
- package/package.json +5 -5
- package/packages/datadog-core/src/storage/async_resource.js +1 -1
- package/packages/datadog-instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/aws-sdk.js +5 -4
- package/packages/datadog-instrumentations/src/fastify.js +84 -92
- package/packages/datadog-instrumentations/src/graphql.js +352 -0
- package/packages/datadog-instrumentations/src/http/client.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +14 -14
- package/packages/datadog-instrumentations/src/koa.js +10 -7
- package/packages/datadog-instrumentations/src/tedious.js +1 -1
- package/packages/datadog-plugin-graphql/src/index.js +123 -412
- package/packages/datadog-plugin-graphql/src/resolve.js +125 -0
- package/packages/datadog-plugin-http/src/client.js +10 -7
- package/packages/datadog-plugin-http2/src/server.js +3 -1
- package/packages/datadog-plugin-jest/src/util.js +13 -1
- package/packages/datadog-plugin-mysql/src/index.js +18 -7
- package/packages/dd-trace/src/appsec/index.js +3 -3
- package/packages/dd-trace/src/config.js +1 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -1
- package/packages/dd-trace/src/plugin_manager.js +21 -0
- package/packages/dd-trace/src/plugins/util/test.js +3 -0
- package/packages/dd-trace/src/plugins/util/web.js +3 -1
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/startup-log.js +1 -1
- package/packages/dd-trace/src/telemetry.js +1 -1
- package/scripts/install_plugin_modules.js +2 -4
- package/packages/dd-trace/lib/version.js +0 -1
package/ci/init.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
1
3
|
const path = require('path')
|
|
2
4
|
const tracer = require('../packages/dd-trace')
|
|
3
5
|
const { ORIGIN_KEY } = require('../packages/dd-trace/src/constants')
|
|
@@ -11,9 +13,22 @@ const options = {
|
|
|
11
13
|
}
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
let shouldInit = true
|
|
17
|
+
|
|
18
|
+
const isAgentlessEnabled = process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED &&
|
|
19
|
+
process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== 'false' &&
|
|
20
|
+
process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== '0'
|
|
21
|
+
|
|
22
|
+
if (isAgentlessEnabled) {
|
|
23
|
+
if (process.env.DATADOG_API_KEY || process.env.DD_API_KEY) {
|
|
24
|
+
options.experimental = {
|
|
25
|
+
exporter: 'datadog'
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
console.error(`DD_CIVISIBILITY_AGENTLESS_ENABLED is set, \
|
|
29
|
+
but neither DD_API_KEY nor DATADOG_API_KEY are set in your environment, \
|
|
30
|
+
so dd-trace will not be initialized.`)
|
|
31
|
+
shouldInit = false
|
|
17
32
|
}
|
|
18
33
|
}
|
|
19
34
|
|
|
@@ -36,8 +51,9 @@ try {
|
|
|
36
51
|
// ignore error and let the tracer initialize anyway
|
|
37
52
|
}
|
|
38
53
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
tracer.use('fs', false)
|
|
54
|
+
if (shouldInit) {
|
|
55
|
+
tracer.init(options)
|
|
56
|
+
tracer.use('fs', false)
|
|
57
|
+
}
|
|
42
58
|
|
|
43
59
|
module.exports = tracer
|
package/ci/jest/env.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
1
3
|
const tracer = require('../../packages/dd-trace')
|
|
2
4
|
const { ORIGIN_KEY } = require('../../packages/dd-trace/src/constants')
|
|
3
5
|
|
|
@@ -8,13 +10,23 @@ const options = {
|
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const isAgentlessEnabled = process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED &&
|
|
14
|
+
process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== 'false' &&
|
|
15
|
+
process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== '0'
|
|
16
|
+
|
|
17
|
+
if (isAgentlessEnabled) {
|
|
18
|
+
if (process.env.DATADOG_API_KEY || process.env.DD_API_KEY) {
|
|
19
|
+
tracer.init({
|
|
20
|
+
...options,
|
|
21
|
+
experimental: {
|
|
22
|
+
exporter: 'datadog'
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
} else {
|
|
26
|
+
console.error(`DD_CIVISIBILITY_AGENTLESS_ENABLED is set, \
|
|
27
|
+
but neither DD_API_KEY nor DATADOG_API_KEY are set in your environment, \
|
|
28
|
+
so dd-trace will not be initialized.`)
|
|
29
|
+
}
|
|
18
30
|
} else {
|
|
19
31
|
tracer.init({
|
|
20
32
|
...options,
|
package/ext/tags.d.ts
CHANGED
package/ext/tags.js
CHANGED
|
@@ -19,7 +19,8 @@ const tags = {
|
|
|
19
19
|
HTTP_STATUS_CODE: 'http.status_code',
|
|
20
20
|
HTTP_ROUTE: 'http.route',
|
|
21
21
|
HTTP_REQUEST_HEADERS: 'http.request.headers',
|
|
22
|
-
HTTP_RESPONSE_HEADERS: 'http.response.headers'
|
|
22
|
+
HTTP_RESPONSE_HEADERS: 'http.response.headers',
|
|
23
|
+
HTTP_USERAGENT: 'http.useragent'
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
// Deprecated
|
package/index.d.ts
CHANGED
|
@@ -1210,13 +1210,15 @@ declare namespace plugins {
|
|
|
1210
1210
|
* This plugin automatically instruments the
|
|
1211
1211
|
* [mysql](https://github.com/mysqljs/mysql) module.
|
|
1212
1212
|
*/
|
|
1213
|
-
interface mysql extends Instrumentation {
|
|
1213
|
+
interface mysql extends Instrumentation {
|
|
1214
|
+
service?: string | ((params: any) => string);
|
|
1215
|
+
}
|
|
1214
1216
|
|
|
1215
1217
|
/**
|
|
1216
1218
|
* This plugin automatically instruments the
|
|
1217
1219
|
* [mysql2](https://github.com/brianmario/mysql2) module.
|
|
1218
1220
|
*/
|
|
1219
|
-
interface mysql2 extends
|
|
1221
|
+
interface mysql2 extends mysql {}
|
|
1220
1222
|
|
|
1221
1223
|
/**
|
|
1222
1224
|
* This plugin automatically instruments the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@datadog/native-appsec": "^1.2.0",
|
|
62
|
-
"@datadog/native-metrics": "^1.
|
|
63
|
-
"@datadog/pprof": "^0.
|
|
64
|
-
"@datadog/sketches-js": "^1.0.
|
|
62
|
+
"@datadog/native-metrics": "^1.4.0",
|
|
63
|
+
"@datadog/pprof": "^0.5.1",
|
|
64
|
+
"@datadog/sketches-js": "^1.0.5",
|
|
65
65
|
"@types/node": ">=12",
|
|
66
66
|
"crypto-randomuuid": "^1.0.0",
|
|
67
67
|
"diagnostics_channel": "^1.1.0",
|
|
@@ -106,8 +106,8 @@
|
|
|
106
106
|
"jszip": "^3.5.0",
|
|
107
107
|
"mkdirp": "^0.5.1",
|
|
108
108
|
"mocha": "8",
|
|
109
|
-
"multer": "^1.4.2",
|
|
110
109
|
"msgpack-lite": "^0.1.26",
|
|
110
|
+
"multer": "^1.4.5-lts.1",
|
|
111
111
|
"nock": "^11.3.3",
|
|
112
112
|
"nyc": "^15.1.0",
|
|
113
113
|
"proxyquire": "^1.8.0",
|
|
@@ -15,13 +15,14 @@ function wrapRequest (send) {
|
|
|
15
15
|
const channelSuffix = getChannelSuffix(serviceIdentifier)
|
|
16
16
|
const startCh = channel(`apm:aws:request:start:${channelSuffix}`)
|
|
17
17
|
if (!startCh.hasSubscribers) return send.apply(this, arguments)
|
|
18
|
+
const innerAr = new AsyncResource('apm:aws:request:inner')
|
|
18
19
|
const outerAr = new AsyncResource('apm:aws:request:outer')
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
return innerAr.runInAsyncScope(() => {
|
|
22
|
+
this.on('complete', innerAr.bind(response => {
|
|
23
|
+
channel(`apm:aws:request:complete:${channelSuffix}`).publish({ response })
|
|
24
|
+
}))
|
|
23
25
|
|
|
24
|
-
return new AsyncResource('apm:aws:request:inner').runInAsyncScope(() => {
|
|
25
26
|
startCh.publish({
|
|
26
27
|
serviceIdentifier,
|
|
27
28
|
operation: this.operation,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const methods = require('methods').concat('all')
|
|
4
3
|
const shimmer = require('../../datadog-shimmer')
|
|
5
4
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
6
5
|
|
|
@@ -8,26 +7,28 @@ const errorChannel = channel('apm:fastify:middleware:error')
|
|
|
8
7
|
const handleChannel = channel('apm:fastify:request:handle')
|
|
9
8
|
|
|
10
9
|
const requestResources = new WeakMap()
|
|
10
|
+
const parsingResources = new WeakMap()
|
|
11
11
|
|
|
12
|
-
function wrapFastify (fastify) {
|
|
12
|
+
function wrapFastify (fastify, hasParsingEvents) {
|
|
13
13
|
if (typeof fastify !== 'function') return fastify
|
|
14
14
|
|
|
15
15
|
return function fastifyWithTrace () {
|
|
16
16
|
const app = fastify.apply(this, arguments)
|
|
17
17
|
|
|
18
|
-
if (!app) return app
|
|
18
|
+
if (!app || typeof app.addHook !== 'function') return app
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
app.addHook = wrapAddHook(app.addHook)
|
|
23
|
-
app.addHook('preHandler', preHandler)
|
|
24
|
-
}
|
|
20
|
+
app.addHook('onRequest', onRequest)
|
|
21
|
+
app.addHook('preHandler', preHandler)
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
app
|
|
28
|
-
|
|
23
|
+
if (hasParsingEvents) {
|
|
24
|
+
app.addHook('preParsing', preParsing)
|
|
25
|
+
app.addHook('preValidation', preValidation)
|
|
26
|
+
} else {
|
|
27
|
+
app.addHook('onRequest', preParsing)
|
|
28
|
+
app.addHook('preHandler', preValidation)
|
|
29
|
+
}
|
|
29
30
|
|
|
30
|
-
app.
|
|
31
|
+
app.addHook = wrapAddHook(app.addHook)
|
|
31
32
|
|
|
32
33
|
return app
|
|
33
34
|
}
|
|
@@ -45,114 +46,102 @@ function wrapAddHook (addHook) {
|
|
|
45
46
|
|
|
46
47
|
if (!requestResource) return fn.apply(this, arguments)
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
try {
|
|
50
|
+
if (typeof done === 'function') {
|
|
51
|
+
done = arguments[arguments.length - 1]
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
done = arguments[arguments.length - 1]
|
|
53
|
+
arguments[arguments.length - 1] = function (err) {
|
|
54
|
+
publishError(err, requestResource)
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return done.apply(this, arguments)
|
|
58
|
-
})
|
|
56
|
+
if (name === 'onRequest' || name === 'preParsing') {
|
|
57
|
+
const parsingResource = new AsyncResource('bound-anonymous-fn')
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
} else {
|
|
62
|
-
const promise = hookResource.bind(fn).apply(this, arguments)
|
|
59
|
+
parsingResources.set(req, parsingResource)
|
|
63
60
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
errorChannel.publish(err)
|
|
67
|
-
throw err
|
|
61
|
+
return parsingResource.runInAsyncScope(() => {
|
|
62
|
+
return done.apply(this, arguments)
|
|
68
63
|
})
|
|
64
|
+
} else {
|
|
65
|
+
return done.apply(this, arguments)
|
|
69
66
|
}
|
|
67
|
+
}
|
|
70
68
|
|
|
71
|
-
|
|
69
|
+
return fn.apply(this, arguments)
|
|
70
|
+
} else {
|
|
71
|
+
const promise = fn.apply(this, arguments)
|
|
72
|
+
|
|
73
|
+
if (promise && typeof promise.catch === 'function') {
|
|
74
|
+
return promise.catch(err => publishError(err, requestResource))
|
|
72
75
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
throw e
|
|
76
|
+
|
|
77
|
+
return promise
|
|
76
78
|
}
|
|
77
|
-
})
|
|
79
|
+
} catch (e) {
|
|
80
|
+
throw publishError(e, requestResource)
|
|
81
|
+
}
|
|
78
82
|
})
|
|
79
83
|
|
|
80
84
|
return addHook.apply(this, arguments)
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
function onRequest (request, reply,
|
|
85
|
-
if (typeof
|
|
88
|
+
function onRequest (request, reply, done) {
|
|
89
|
+
if (typeof done !== 'function') return
|
|
86
90
|
|
|
87
91
|
const req = getReq(request)
|
|
88
92
|
const res = getRes(reply)
|
|
93
|
+
const requestResource = new AsyncResource('bound-anonymous-fn')
|
|
89
94
|
|
|
90
|
-
requestResources.set(req,
|
|
91
|
-
handleChannel.publish({ req, res })
|
|
95
|
+
requestResources.set(req, requestResource)
|
|
92
96
|
|
|
93
|
-
return
|
|
97
|
+
return requestResource.runInAsyncScope(() => {
|
|
98
|
+
handleChannel.publish({ req, res })
|
|
99
|
+
return done()
|
|
100
|
+
})
|
|
94
101
|
}
|
|
95
102
|
|
|
96
|
-
function preHandler (request, reply,
|
|
97
|
-
if (typeof
|
|
98
|
-
if (!reply || typeof reply.send !== 'function') return
|
|
103
|
+
function preHandler (request, reply, done) {
|
|
104
|
+
if (typeof done !== 'function') return
|
|
105
|
+
if (!reply || typeof reply.send !== 'function') return done()
|
|
99
106
|
|
|
100
107
|
const req = getReq(request)
|
|
108
|
+
const requestResource = requestResources.get(req)
|
|
101
109
|
|
|
102
|
-
reply.send =
|
|
110
|
+
reply.send = wrapSend(reply.send, requestResource)
|
|
103
111
|
|
|
104
|
-
|
|
112
|
+
done()
|
|
105
113
|
}
|
|
106
114
|
|
|
107
|
-
function
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
errorChannel.publish(payload)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return send.apply(this, arguments)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function wrapRoute (route) {
|
|
118
|
-
if (typeof route !== 'function') return route
|
|
115
|
+
function preValidation (request, reply, done) {
|
|
116
|
+
const req = getReq(request)
|
|
117
|
+
const parsingResource = parsingResources.get(req)
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
opts.handler = wrapHandler(opts.handler)
|
|
119
|
+
if (!parsingResource) return done()
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
}
|
|
121
|
+
parsingResource.runInAsyncScope(() => done())
|
|
125
122
|
}
|
|
126
123
|
|
|
127
|
-
function
|
|
128
|
-
if (typeof
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const lastIndex = arguments.length - 1
|
|
132
|
-
|
|
133
|
-
handler = arguments[lastIndex]
|
|
124
|
+
function preParsing (request, reply, payload, done) {
|
|
125
|
+
if (typeof done !== 'function') {
|
|
126
|
+
done = payload
|
|
127
|
+
}
|
|
134
128
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} else if (handler) {
|
|
138
|
-
arguments[lastIndex].handler = wrapHandler(handler.handler)
|
|
139
|
-
}
|
|
129
|
+
const req = getReq(request)
|
|
130
|
+
const parsingResource = new AsyncResource('bound-anonymous-fn')
|
|
140
131
|
|
|
141
|
-
|
|
142
|
-
|
|
132
|
+
parsingResources.set(req, parsingResource)
|
|
133
|
+
parsingResource.runInAsyncScope(() => done())
|
|
143
134
|
}
|
|
144
135
|
|
|
145
|
-
function
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
136
|
+
function wrapSend (send, resource) {
|
|
137
|
+
return function sendWithTrace (payload) {
|
|
138
|
+
if (payload instanceof Error) {
|
|
139
|
+
resource.runInAsyncScope(() => {
|
|
140
|
+
errorChannel.publish(payload)
|
|
141
|
+
})
|
|
142
|
+
}
|
|
152
143
|
|
|
153
|
-
return
|
|
154
|
-
return handler.apply(this, arguments)
|
|
155
|
-
})
|
|
144
|
+
return send.apply(this, arguments)
|
|
156
145
|
}
|
|
157
146
|
}
|
|
158
147
|
|
|
@@ -164,16 +153,15 @@ function getRes (reply) {
|
|
|
164
153
|
return reply && (reply.raw || reply.res || reply)
|
|
165
154
|
}
|
|
166
155
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
wrapped.default = wrapped
|
|
156
|
+
function publishError (error, resource) {
|
|
157
|
+
resource.runInAsyncScope(() => {
|
|
158
|
+
errorChannel.publish(error)
|
|
159
|
+
})
|
|
172
160
|
|
|
173
|
-
return
|
|
174
|
-
}
|
|
161
|
+
return error
|
|
162
|
+
}
|
|
175
163
|
|
|
176
|
-
addHook({ name: 'fastify', versions: ['3
|
|
164
|
+
addHook({ name: 'fastify', versions: ['>=3'] }, fastify => {
|
|
177
165
|
const wrapped = shimmer.wrap(fastify, wrapFastify(fastify, true))
|
|
178
166
|
|
|
179
167
|
wrapped.fastify = wrapped
|
|
@@ -182,6 +170,10 @@ addHook({ name: 'fastify', versions: ['3 - 3.25.1'] }, fastify => {
|
|
|
182
170
|
return wrapped
|
|
183
171
|
})
|
|
184
172
|
|
|
185
|
-
addHook({ name: 'fastify', versions: ['
|
|
173
|
+
addHook({ name: 'fastify', versions: ['2'] }, fastify => {
|
|
186
174
|
return shimmer.wrap(fastify, wrapFastify(fastify, true))
|
|
187
175
|
})
|
|
176
|
+
|
|
177
|
+
addHook({ name: 'fastify', versions: ['1'] }, fastify => {
|
|
178
|
+
return shimmer.wrap(fastify, wrapFastify(fastify, false))
|
|
179
|
+
})
|