dd-trace 2.2.0 → 2.2.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 +0 -12
- package/package.json +3 -5
- package/packages/datadog-instrumentations/index.js +8 -0
- package/packages/datadog-instrumentations/src/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/elasticsearch.js +6 -1
- package/packages/datadog-instrumentations/src/generic-pool.js +48 -0
- package/packages/datadog-instrumentations/src/ioredis.js +49 -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-bunyan/src/index.js +5 -22
- 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/constants.js +1 -6
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -34
- package/packages/dd-trace/src/plugins/index.js +0 -2
- package/packages/dd-trace/src/plugins/log_plugin.js +44 -0
- package/packages/dd-trace/src/plugins/plugin.js +7 -0
- 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/datadog-plugin-generic-pool/src/index.js +0 -52
- package/packages/datadog-plugin-mongoose/src/index.js +0 -51
|
@@ -29,6 +29,9 @@ const HTTP2_HEADER_AUTHORITY = ':authority'
|
|
|
29
29
|
const HTTP2_HEADER_SCHEME = ':scheme'
|
|
30
30
|
const HTTP2_HEADER_PATH = ':path'
|
|
31
31
|
|
|
32
|
+
const contexts = new WeakMap()
|
|
33
|
+
const ends = new WeakMap()
|
|
34
|
+
|
|
32
35
|
const web = {
|
|
33
36
|
// Ensure the configuration has the correct structure and defaults.
|
|
34
37
|
normalizeConfig (config) {
|
|
@@ -51,8 +54,7 @@ const web = {
|
|
|
51
54
|
|
|
52
55
|
// Start a span and activate a scope for a request.
|
|
53
56
|
instrument (tracer, config, req, res, name, callback) {
|
|
54
|
-
this.patch(req)
|
|
55
|
-
|
|
57
|
+
const context = this.patch(req)
|
|
56
58
|
const span = startSpan(tracer, config, req, res, name)
|
|
57
59
|
|
|
58
60
|
if (!config.filter(req.url)) {
|
|
@@ -65,11 +67,11 @@ const web = {
|
|
|
65
67
|
|
|
66
68
|
analyticsSampler.sample(span, config.measured, true)
|
|
67
69
|
|
|
68
|
-
if (!
|
|
69
|
-
wrapEnd(
|
|
70
|
-
wrapEvents(
|
|
70
|
+
if (!context.instrumented) {
|
|
71
|
+
wrapEnd(context)
|
|
72
|
+
wrapEvents(context)
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
context.instrumented = true
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
return callback && tracer.scope().activate(span, () => callback(span))
|
|
@@ -83,22 +85,23 @@ const web = {
|
|
|
83
85
|
// Add a route segment that will be used for the resource name.
|
|
84
86
|
enterRoute (req, path) {
|
|
85
87
|
if (typeof path === 'string') {
|
|
86
|
-
req.
|
|
88
|
+
contexts.get(req).paths.push(path)
|
|
87
89
|
}
|
|
88
90
|
},
|
|
89
91
|
|
|
90
92
|
// Remove the current route segment.
|
|
91
93
|
exitRoute (req) {
|
|
92
|
-
req.
|
|
94
|
+
contexts.get(req).paths.pop()
|
|
93
95
|
},
|
|
94
96
|
|
|
95
97
|
// Start a new middleware span and activate a new scope with the span.
|
|
96
98
|
wrapMiddleware (req, middleware, name, fn) {
|
|
97
99
|
if (!this.active(req)) return fn()
|
|
98
100
|
|
|
99
|
-
const
|
|
101
|
+
const context = contexts.get(req)
|
|
102
|
+
const tracer = context.tracer
|
|
100
103
|
const childOf = this.active(req)
|
|
101
|
-
const config =
|
|
104
|
+
const config = context.config
|
|
102
105
|
|
|
103
106
|
if (config.middleware === false) return this.bindAndWrapMiddlewareErrors(fn, req, tracer, childOf)
|
|
104
107
|
|
|
@@ -110,7 +113,7 @@ const web = {
|
|
|
110
113
|
[RESOURCE_NAME]: middleware._name || middleware.name || '<anonymous>'
|
|
111
114
|
})
|
|
112
115
|
|
|
113
|
-
|
|
116
|
+
context.middleware.push(span)
|
|
114
117
|
|
|
115
118
|
return tracer.scope().activate(span, fn)
|
|
116
119
|
},
|
|
@@ -129,7 +132,8 @@ const web = {
|
|
|
129
132
|
finish (req, error) {
|
|
130
133
|
if (!this.active(req)) return
|
|
131
134
|
|
|
132
|
-
const
|
|
135
|
+
const context = contexts.get(req)
|
|
136
|
+
const span = context.middleware.pop()
|
|
133
137
|
|
|
134
138
|
if (span) {
|
|
135
139
|
if (error) {
|
|
@@ -146,38 +150,50 @@ const web = {
|
|
|
146
150
|
|
|
147
151
|
// Register a callback to run before res.end() is called.
|
|
148
152
|
beforeEnd (req, callback) {
|
|
149
|
-
req.
|
|
153
|
+
contexts.get(req).beforeEnd.push(callback)
|
|
150
154
|
},
|
|
151
155
|
|
|
152
156
|
// Prepare the request for instrumentation.
|
|
153
157
|
patch (req) {
|
|
154
|
-
|
|
158
|
+
let context = contexts.get(req)
|
|
159
|
+
|
|
160
|
+
if (context) return context
|
|
155
161
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
162
|
+
context = req.stream && contexts.get(req.stream)
|
|
163
|
+
|
|
164
|
+
if (context) {
|
|
165
|
+
contexts.set(req, context)
|
|
166
|
+
return context
|
|
159
167
|
}
|
|
160
168
|
|
|
161
|
-
|
|
169
|
+
context = {
|
|
170
|
+
req,
|
|
162
171
|
span: null,
|
|
163
172
|
paths: [],
|
|
164
173
|
middleware: [],
|
|
165
174
|
beforeEnd: [],
|
|
166
175
|
config: {}
|
|
167
176
|
}
|
|
177
|
+
|
|
178
|
+
contexts.set(req, context)
|
|
179
|
+
|
|
180
|
+
return context
|
|
168
181
|
},
|
|
169
182
|
|
|
170
183
|
// Return the request root span.
|
|
171
184
|
root (req) {
|
|
172
|
-
|
|
185
|
+
const context = contexts.get(req)
|
|
186
|
+
return context ? context.span : null
|
|
173
187
|
},
|
|
174
188
|
|
|
175
189
|
// Return the active span.
|
|
176
190
|
active (req) {
|
|
177
|
-
|
|
178
|
-
if (req._datadog.middleware.length === 0) return req._datadog.span || null
|
|
191
|
+
const context = contexts.get(req)
|
|
179
192
|
|
|
180
|
-
|
|
193
|
+
if (!context) return null
|
|
194
|
+
if (context.middleware.length === 0) return context.span || null
|
|
195
|
+
|
|
196
|
+
return context.middleware.slice(-1)[0]
|
|
181
197
|
},
|
|
182
198
|
|
|
183
199
|
// Extract the parent span from the headers and start a new span as its child
|
|
@@ -190,10 +206,11 @@ const web = {
|
|
|
190
206
|
|
|
191
207
|
// Validate a request's status code and then add error tags if necessary
|
|
192
208
|
addStatusError (req, statusCode) {
|
|
193
|
-
const
|
|
194
|
-
const
|
|
209
|
+
const context = contexts.get(req)
|
|
210
|
+
const span = context.span
|
|
211
|
+
const error = context.error
|
|
195
212
|
|
|
196
|
-
if (!
|
|
213
|
+
if (!context.config.validateStatus(statusCode)) {
|
|
197
214
|
span.setTag(ERROR, error || true)
|
|
198
215
|
}
|
|
199
216
|
},
|
|
@@ -201,94 +218,95 @@ const web = {
|
|
|
201
218
|
// Add an error to the request
|
|
202
219
|
addError (req, error) {
|
|
203
220
|
if (error instanceof Error) {
|
|
204
|
-
|
|
221
|
+
const context = contexts.get(req)
|
|
222
|
+
context.error = context.error || error
|
|
205
223
|
}
|
|
206
224
|
}
|
|
207
225
|
}
|
|
208
226
|
|
|
209
227
|
function startSpan (tracer, config, req, res, name) {
|
|
210
|
-
|
|
228
|
+
const context = contexts.get(req)
|
|
229
|
+
|
|
230
|
+
context.config = config
|
|
211
231
|
|
|
212
232
|
let span
|
|
213
233
|
|
|
214
|
-
if (
|
|
215
|
-
|
|
216
|
-
span =
|
|
234
|
+
if (context.span) {
|
|
235
|
+
context.span.context()._name = name
|
|
236
|
+
span = context.span
|
|
217
237
|
} else {
|
|
218
238
|
span = web.startChildSpan(tracer, name, req.headers)
|
|
219
239
|
}
|
|
220
240
|
|
|
221
|
-
|
|
241
|
+
context.tracer = tracer
|
|
242
|
+
context.span = span
|
|
243
|
+
context.res = res
|
|
222
244
|
|
|
223
245
|
return span
|
|
224
246
|
}
|
|
225
247
|
|
|
226
|
-
function
|
|
227
|
-
const
|
|
228
|
-
ddObj.tracer = tracer
|
|
229
|
-
ddObj.span = span
|
|
230
|
-
ddObj.res = res
|
|
231
|
-
}
|
|
248
|
+
function finish (context) {
|
|
249
|
+
const { req, res } = context
|
|
232
250
|
|
|
233
|
-
|
|
234
|
-
if (req._datadog.finished && !req.stream) return
|
|
251
|
+
if (context.finished && !req.stream) return
|
|
235
252
|
|
|
236
|
-
addRequestTags(
|
|
237
|
-
addResponseTags(
|
|
253
|
+
addRequestTags(context)
|
|
254
|
+
addResponseTags(context)
|
|
238
255
|
|
|
239
|
-
|
|
240
|
-
addResourceTag(
|
|
256
|
+
context.config.hooks.request(context.span, req, res)
|
|
257
|
+
addResourceTag(context)
|
|
241
258
|
|
|
242
|
-
|
|
243
|
-
|
|
259
|
+
context.span.finish()
|
|
260
|
+
context.finished = true
|
|
244
261
|
}
|
|
245
262
|
|
|
246
|
-
function finishMiddleware (
|
|
247
|
-
if (
|
|
263
|
+
function finishMiddleware (context) {
|
|
264
|
+
if (context.finished) return
|
|
248
265
|
|
|
249
266
|
let span
|
|
250
267
|
|
|
251
|
-
while ((span =
|
|
268
|
+
while ((span = context.middleware.pop())) {
|
|
252
269
|
span.finish()
|
|
253
270
|
}
|
|
254
271
|
}
|
|
255
272
|
|
|
256
|
-
function wrapEnd (
|
|
257
|
-
const scope =
|
|
258
|
-
const
|
|
273
|
+
function wrapEnd (context) {
|
|
274
|
+
const scope = context.tracer.scope()
|
|
275
|
+
const req = context.req
|
|
276
|
+
const res = context.res
|
|
259
277
|
const end = res.end
|
|
260
278
|
|
|
261
|
-
res.writeHead = wrapWriteHead(
|
|
279
|
+
res.writeHead = wrapWriteHead(context)
|
|
262
280
|
|
|
263
|
-
res
|
|
264
|
-
for (const beforeEnd of
|
|
281
|
+
ends.set(res, function () {
|
|
282
|
+
for (const beforeEnd of context.beforeEnd) {
|
|
265
283
|
beforeEnd()
|
|
266
284
|
}
|
|
267
285
|
|
|
268
|
-
finishMiddleware(
|
|
286
|
+
finishMiddleware(context)
|
|
269
287
|
|
|
270
288
|
if (incomingHttpRequestEnd.hasSubscribers) incomingHttpRequestEnd.publish({ req, res })
|
|
271
289
|
|
|
272
290
|
const returnValue = end.apply(res, arguments)
|
|
273
291
|
|
|
274
|
-
finish(
|
|
292
|
+
finish(context)
|
|
275
293
|
|
|
276
294
|
return returnValue
|
|
277
|
-
}
|
|
295
|
+
})
|
|
278
296
|
|
|
279
297
|
Object.defineProperty(res, 'end', {
|
|
280
298
|
configurable: true,
|
|
281
299
|
get () {
|
|
282
|
-
return this
|
|
300
|
+
return ends.get(this)
|
|
283
301
|
},
|
|
284
302
|
set (value) {
|
|
285
|
-
this
|
|
303
|
+
ends.set(this, scope.bind(value, context.span))
|
|
286
304
|
}
|
|
287
305
|
})
|
|
288
306
|
}
|
|
289
307
|
|
|
290
|
-
function wrapWriteHead (
|
|
291
|
-
const res =
|
|
308
|
+
function wrapWriteHead (context) {
|
|
309
|
+
const { req, res } = context
|
|
292
310
|
const writeHead = res.writeHead
|
|
293
311
|
|
|
294
312
|
return function (statusCode, statusMessage, headers) {
|
|
@@ -296,15 +314,14 @@ function wrapWriteHead (req) {
|
|
|
296
314
|
headers = Object.assign(res.getHeaders(), headers)
|
|
297
315
|
|
|
298
316
|
if (req.method.toLowerCase() === 'options' && isOriginAllowed(req, headers)) {
|
|
299
|
-
addAllowHeaders(req, headers)
|
|
317
|
+
addAllowHeaders(req, res, headers)
|
|
300
318
|
}
|
|
301
319
|
|
|
302
320
|
return writeHead.apply(this, arguments)
|
|
303
321
|
}
|
|
304
322
|
}
|
|
305
323
|
|
|
306
|
-
function addAllowHeaders (req, headers) {
|
|
307
|
-
const res = req._datadog.res
|
|
324
|
+
function addAllowHeaders (req, res, headers) {
|
|
308
325
|
const allowHeaders = splitHeader(headers['access-control-allow-headers'])
|
|
309
326
|
const requestHeaders = splitHeader(req.headers['access-control-request-headers'])
|
|
310
327
|
const contextHeaders = [
|
|
@@ -337,22 +354,24 @@ function splitHeader (str) {
|
|
|
337
354
|
return typeof str === 'string' ? str.split(/\s*,\s*/) : []
|
|
338
355
|
}
|
|
339
356
|
|
|
340
|
-
function wrapEvents (
|
|
341
|
-
const scope =
|
|
342
|
-
const res =
|
|
357
|
+
function wrapEvents (context) {
|
|
358
|
+
const scope = context.tracer.scope()
|
|
359
|
+
const res = context.res
|
|
343
360
|
|
|
344
|
-
scope.bind(res,
|
|
361
|
+
scope.bind(res, context.span)
|
|
345
362
|
}
|
|
346
363
|
|
|
347
364
|
function reactivate (req, fn) {
|
|
348
|
-
|
|
349
|
-
|
|
365
|
+
const context = contexts.get(req)
|
|
366
|
+
|
|
367
|
+
return context
|
|
368
|
+
? context.tracer.scope().activate(context.span, fn)
|
|
350
369
|
: fn()
|
|
351
370
|
}
|
|
352
371
|
|
|
353
|
-
function addRequestTags (
|
|
372
|
+
function addRequestTags (context) {
|
|
373
|
+
const { req, span } = context
|
|
354
374
|
const url = extractURL(req)
|
|
355
|
-
const span = req._datadog.span
|
|
356
375
|
|
|
357
376
|
span.addTags({
|
|
358
377
|
[HTTP_URL]: url.split('?')[0],
|
|
@@ -361,15 +380,14 @@ function addRequestTags (req) {
|
|
|
361
380
|
[SPAN_TYPE]: WEB
|
|
362
381
|
})
|
|
363
382
|
|
|
364
|
-
addHeaders(
|
|
383
|
+
addHeaders(context)
|
|
365
384
|
}
|
|
366
385
|
|
|
367
|
-
function addResponseTags (
|
|
368
|
-
const span =
|
|
369
|
-
const res = req._datadog.res
|
|
386
|
+
function addResponseTags (context) {
|
|
387
|
+
const { req, res, paths, span } = context
|
|
370
388
|
|
|
371
|
-
if (
|
|
372
|
-
span.setTag(HTTP_ROUTE,
|
|
389
|
+
if (paths.length > 0) {
|
|
390
|
+
span.setTag(HTTP_ROUTE, paths.join(''))
|
|
373
391
|
}
|
|
374
392
|
|
|
375
393
|
span.addTags({
|
|
@@ -379,8 +397,8 @@ function addResponseTags (req) {
|
|
|
379
397
|
web.addStatusError(req, res.statusCode)
|
|
380
398
|
}
|
|
381
399
|
|
|
382
|
-
function addResourceTag (
|
|
383
|
-
const span =
|
|
400
|
+
function addResourceTag (context) {
|
|
401
|
+
const { req, span } = context
|
|
384
402
|
const tags = span.context()._tags
|
|
385
403
|
|
|
386
404
|
if (tags['resource.name']) return
|
|
@@ -392,12 +410,12 @@ function addResourceTag (req) {
|
|
|
392
410
|
span.setTag(RESOURCE_NAME, resource)
|
|
393
411
|
}
|
|
394
412
|
|
|
395
|
-
function addHeaders (
|
|
396
|
-
const span =
|
|
413
|
+
function addHeaders (context) {
|
|
414
|
+
const { req, res, config, span } = context
|
|
397
415
|
|
|
398
|
-
|
|
416
|
+
config.headers.forEach(key => {
|
|
399
417
|
const reqHeader = req.headers[key]
|
|
400
|
-
const resHeader =
|
|
418
|
+
const resHeader = res.getHeader(key)
|
|
401
419
|
|
|
402
420
|
if (reqHeader) {
|
|
403
421
|
span.setTag(`${HTTP_REQUEST_HEADERS}.${key}`, reqHeader)
|
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const coalesce = require('koalas')
|
|
4
3
|
const RateLimiter = require('./rate_limiter')
|
|
5
4
|
const Sampler = require('./sampler')
|
|
6
5
|
const ext = require('../../../ext')
|
|
7
6
|
const { setSamplingRules } = require('./startup-log')
|
|
8
7
|
|
|
9
8
|
const {
|
|
10
|
-
SAMPLING_MECHANISM_DEFAULT,
|
|
11
|
-
SAMPLING_MECHANISM_AGENT,
|
|
12
|
-
SAMPLING_MECHANISM_RULE,
|
|
13
|
-
SAMPLING_MECHANISM_MANUAL,
|
|
14
9
|
SAMPLING_RULE_DECISION,
|
|
15
10
|
SAMPLING_LIMIT_DECISION,
|
|
16
|
-
SAMPLING_AGENT_DECISION
|
|
17
|
-
UPSTREAM_SERVICES_KEY
|
|
11
|
+
SAMPLING_AGENT_DECISION
|
|
18
12
|
} = require('./constants')
|
|
19
13
|
|
|
20
14
|
const SERVICE_NAME = ext.tags.SERVICE_NAME
|
|
@@ -28,7 +22,6 @@ const USER_KEEP = ext.priority.USER_KEEP
|
|
|
28
22
|
const DEFAULT_KEY = 'service:,env:'
|
|
29
23
|
|
|
30
24
|
const defaultSampler = new Sampler(AUTO_KEEP)
|
|
31
|
-
const serviceNames = new Map()
|
|
32
25
|
|
|
33
26
|
class PrioritySampler {
|
|
34
27
|
constructor (env, { sampleRate, rateLimit = 100, rules = [] } = {}) {
|
|
@@ -59,14 +52,9 @@ class PrioritySampler {
|
|
|
59
52
|
|
|
60
53
|
if (this.validate(tag)) {
|
|
61
54
|
context._sampling.priority = tag
|
|
62
|
-
context._sampling.mechanism = SAMPLING_MECHANISM_MANUAL
|
|
63
55
|
} else if (auto) {
|
|
64
56
|
context._sampling.priority = this._getPriorityFromAuto(root)
|
|
65
|
-
} else {
|
|
66
|
-
return
|
|
67
57
|
}
|
|
68
|
-
|
|
69
|
-
this._addUpstreamService(root)
|
|
70
58
|
}
|
|
71
59
|
|
|
72
60
|
update (rates) {
|
|
@@ -127,7 +115,6 @@ class PrioritySampler {
|
|
|
127
115
|
|
|
128
116
|
_getPriorityByRule (context, rule) {
|
|
129
117
|
context._trace[SAMPLING_RULE_DECISION] = rule.sampleRate
|
|
130
|
-
context._sampling.mechanism = SAMPLING_MECHANISM_RULE
|
|
131
118
|
|
|
132
119
|
return rule.sampler.isSampled(context) && this._isSampledByRateLimit(context) ? USER_KEEP : USER_REJECT
|
|
133
120
|
}
|
|
@@ -146,44 +133,9 @@ class PrioritySampler {
|
|
|
146
133
|
|
|
147
134
|
context._trace[SAMPLING_AGENT_DECISION] = sampler.rate()
|
|
148
135
|
|
|
149
|
-
if (sampler === defaultSampler) {
|
|
150
|
-
context._sampling.mechanism = SAMPLING_MECHANISM_DEFAULT
|
|
151
|
-
} else {
|
|
152
|
-
context._sampling.mechanism = SAMPLING_MECHANISM_AGENT
|
|
153
|
-
}
|
|
154
|
-
|
|
155
136
|
return sampler.isSampled(context) ? AUTO_KEEP : AUTO_REJECT
|
|
156
137
|
}
|
|
157
138
|
|
|
158
|
-
_addUpstreamService (span) {
|
|
159
|
-
const context = span.context()
|
|
160
|
-
const trace = context._trace
|
|
161
|
-
const service = this._toBase64(context._tags['service.name'])
|
|
162
|
-
const priority = context._sampling.priority
|
|
163
|
-
const mechanism = context._sampling.mechanism
|
|
164
|
-
const rate = Math.ceil(coalesce(
|
|
165
|
-
context._trace[SAMPLING_RULE_DECISION],
|
|
166
|
-
context._trace[SAMPLING_AGENT_DECISION]
|
|
167
|
-
) * 10000) / 10000
|
|
168
|
-
const group = `${service}|${priority}|${mechanism}|${rate}`
|
|
169
|
-
const groups = trace.tags[UPSTREAM_SERVICES_KEY]
|
|
170
|
-
? `${trace.tags[UPSTREAM_SERVICES_KEY]};${group}`
|
|
171
|
-
: group
|
|
172
|
-
|
|
173
|
-
trace.tags[UPSTREAM_SERVICES_KEY] = groups
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
_toBase64 (serviceName) {
|
|
177
|
-
let encoded = serviceNames.get(serviceName)
|
|
178
|
-
|
|
179
|
-
if (!encoded) {
|
|
180
|
-
encoded = Buffer.from(serviceName).toString('base64')
|
|
181
|
-
serviceNames.set(serviceName, encoded)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return encoded
|
|
185
|
-
}
|
|
186
|
-
|
|
187
139
|
_normalizeRules (rules, sampleRate) {
|
|
188
140
|
return rules
|
|
189
141
|
.concat({ sampleRate })
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
const { storage } = require('../../datadog-core')
|
|
4
4
|
|
|
5
|
+
// TODO: deprecate binding event emitters in 3.0
|
|
6
|
+
|
|
7
|
+
const originals = new WeakMap()
|
|
8
|
+
const listenerMaps = new WeakMap()
|
|
9
|
+
const emitterSpans = new WeakMap()
|
|
10
|
+
const emitterScopes = new WeakMap()
|
|
11
|
+
const emitters = new WeakSet()
|
|
12
|
+
|
|
5
13
|
class Scope {
|
|
6
14
|
active () {
|
|
7
15
|
const store = storage.getStore()
|
|
@@ -58,7 +66,7 @@ class Scope {
|
|
|
58
66
|
})
|
|
59
67
|
}
|
|
60
68
|
|
|
61
|
-
bound
|
|
69
|
+
originals.set(bound, fn)
|
|
62
70
|
|
|
63
71
|
return bound
|
|
64
72
|
}
|
|
@@ -66,16 +74,16 @@ class Scope {
|
|
|
66
74
|
_unbindFn (fn) {
|
|
67
75
|
if (typeof fn !== 'function') return fn
|
|
68
76
|
|
|
69
|
-
return fn
|
|
77
|
+
return originals.get(fn) || fn
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
_bindEmitter (emitter, span) {
|
|
73
81
|
if (!this._isEmitter(emitter)) return emitter
|
|
74
|
-
if (!emitter
|
|
82
|
+
if (!emitters.has(emitter)) {
|
|
75
83
|
Scope._wrapEmitter(emitter)
|
|
76
84
|
}
|
|
77
|
-
emitter
|
|
78
|
-
emitter
|
|
85
|
+
emitterSpans.set(emitter, span)
|
|
86
|
+
emitterScopes.set(emitter, this)
|
|
79
87
|
return emitter
|
|
80
88
|
}
|
|
81
89
|
|
|
@@ -90,13 +98,13 @@ class Scope {
|
|
|
90
98
|
wrapMethod(emitter, 'removeListener', wrapRemoveListener)
|
|
91
99
|
wrapMethod(emitter, 'off', wrapRemoveListener)
|
|
92
100
|
wrapMethod(emitter, 'removeAllListeners', wrapRemoveAllListeners)
|
|
93
|
-
emitter
|
|
101
|
+
emitters.add(emitter)
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
_unbindEmitter (emitter) {
|
|
97
105
|
if (!this._isEmitter(emitter)) return emitter
|
|
98
|
-
delete
|
|
99
|
-
delete
|
|
106
|
+
emitterScopes.delete(emitter)
|
|
107
|
+
emitterSpans.delete(emitter)
|
|
100
108
|
return emitter
|
|
101
109
|
}
|
|
102
110
|
|
|
@@ -111,7 +119,7 @@ class Scope {
|
|
|
111
119
|
_unbindPromise (promise) {
|
|
112
120
|
if (!this._isPromise(promise)) return promise
|
|
113
121
|
|
|
114
|
-
promise.then = promise.then
|
|
122
|
+
promise.then = originals.get(promise.then) || promise.then
|
|
115
123
|
|
|
116
124
|
return promise
|
|
117
125
|
}
|
|
@@ -133,6 +141,18 @@ class Scope {
|
|
|
133
141
|
}
|
|
134
142
|
}
|
|
135
143
|
|
|
144
|
+
function getScope (emitter) {
|
|
145
|
+
return emitterScopes.get(emitter) || emitterScopes.get(emitter.constructor.prototype)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function getSpan (emitter) {
|
|
149
|
+
return emitterSpans.get(emitter) || emitterSpans.get(emitter.constructor.prototype)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function hasScope (emitter) {
|
|
153
|
+
return emitterScopes.has(emitter) || emitterScopes.has(emitter.constructor.prototype)
|
|
154
|
+
}
|
|
155
|
+
|
|
136
156
|
function wrapThen (then, scope, span) {
|
|
137
157
|
return function thenWithTrace (onFulfilled, onRejected) {
|
|
138
158
|
const args = new Array(arguments.length)
|
|
@@ -147,21 +167,22 @@ function wrapThen (then, scope, span) {
|
|
|
147
167
|
|
|
148
168
|
function wrapAddListener (addListener) {
|
|
149
169
|
return function addListenerWithTrace (eventName, listener) {
|
|
150
|
-
|
|
170
|
+
const scope = getScope(this)
|
|
171
|
+
if (!scope || !listener || originals.has(listener) || listener.listener) {
|
|
151
172
|
return addListener.apply(this, arguments)
|
|
152
173
|
}
|
|
153
|
-
const
|
|
154
|
-
const span = this.__dd_span
|
|
174
|
+
const span = getSpan(this)
|
|
155
175
|
|
|
156
176
|
const bound = scope.bind(listener, scope._spanOrActive(span))
|
|
177
|
+
const listenerMap = listenerMaps.get(this) || {}
|
|
157
178
|
|
|
158
|
-
|
|
179
|
+
listenerMaps.set(this, listenerMap)
|
|
159
180
|
|
|
160
|
-
if (!
|
|
161
|
-
|
|
181
|
+
if (!listenerMap[eventName]) {
|
|
182
|
+
listenerMap[eventName] = new WeakMap()
|
|
162
183
|
}
|
|
163
184
|
|
|
164
|
-
const events =
|
|
185
|
+
const events = listenerMap[eventName]
|
|
165
186
|
|
|
166
187
|
if (!events.has(listener)) {
|
|
167
188
|
events.set(listener, [])
|
|
@@ -175,11 +196,12 @@ function wrapAddListener (addListener) {
|
|
|
175
196
|
|
|
176
197
|
function wrapRemoveListener (removeListener) {
|
|
177
198
|
return function removeListenerWithTrace (eventName, listener) {
|
|
178
|
-
if (!this
|
|
199
|
+
if (!hasScope(this)) {
|
|
179
200
|
return removeListener.apply(this, arguments)
|
|
180
201
|
}
|
|
181
202
|
|
|
182
|
-
const
|
|
203
|
+
const listenerMap = listenerMaps.get(this)
|
|
204
|
+
const listeners = listenerMap && listenerMap[eventName]
|
|
183
205
|
|
|
184
206
|
if (!listener || !listeners || !listeners.has(listener)) {
|
|
185
207
|
return removeListener.apply(this, arguments)
|
|
@@ -197,11 +219,13 @@ function wrapRemoveListener (removeListener) {
|
|
|
197
219
|
|
|
198
220
|
function wrapRemoveAllListeners (removeAllListeners) {
|
|
199
221
|
return function removeAllListenersWithTrace (eventName) {
|
|
200
|
-
|
|
222
|
+
const listenerMap = listenerMaps.get(this)
|
|
223
|
+
|
|
224
|
+
if (hasScope(this) && listenerMap) {
|
|
201
225
|
if (eventName) {
|
|
202
|
-
delete
|
|
226
|
+
delete listenerMap[eventName]
|
|
203
227
|
} else {
|
|
204
|
-
delete
|
|
228
|
+
listenerMaps.delete(this)
|
|
205
229
|
}
|
|
206
230
|
}
|
|
207
231
|
|
|
@@ -210,12 +234,12 @@ function wrapRemoveAllListeners (removeAllListeners) {
|
|
|
210
234
|
}
|
|
211
235
|
|
|
212
236
|
function wrapMethod (target, name, wrapper, ...args) {
|
|
213
|
-
if (!target[name] || target[name]
|
|
237
|
+
if (!target[name] || originals.has(target[name])) return
|
|
214
238
|
|
|
215
239
|
const original = target[name]
|
|
216
240
|
|
|
217
241
|
target[name] = wrapper(target[name], ...args)
|
|
218
|
-
target[name]
|
|
242
|
+
originals.set(target[name], original)
|
|
219
243
|
}
|
|
220
244
|
|
|
221
245
|
module.exports = Scope
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
function createWrapAcquire (tracer, config) {
|
|
4
|
-
return function wrapAcquire (acquire) {
|
|
5
|
-
return function acquireWithTrace (callback, priority) {
|
|
6
|
-
if (typeof callback === 'function') {
|
|
7
|
-
arguments[0] = tracer.scope().bind(callback)
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return acquire.apply(this, arguments)
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function createWrapPool (tracer, config, instrumenter) {
|
|
16
|
-
return function wrapPool (Pool) {
|
|
17
|
-
if (typeof Pool !== 'function') return Pool
|
|
18
|
-
|
|
19
|
-
return function PoolWithTrace (factory) {
|
|
20
|
-
const pool = Pool.apply(this, arguments)
|
|
21
|
-
|
|
22
|
-
if (pool && typeof pool.acquire === 'function') {
|
|
23
|
-
instrumenter.wrap(pool, 'acquire', createWrapAcquire(tracer, config))
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return pool
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
module.exports = [
|
|
32
|
-
{
|
|
33
|
-
name: 'generic-pool',
|
|
34
|
-
versions: ['^2.4'],
|
|
35
|
-
patch (genericPool, tracer, config) {
|
|
36
|
-
this.wrap(genericPool.Pool.prototype, 'acquire', createWrapAcquire(tracer, config))
|
|
37
|
-
},
|
|
38
|
-
unpatch (genericPool) {
|
|
39
|
-
this.unwrap(genericPool.Pool.prototype, 'acquire')
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
name: 'generic-pool',
|
|
44
|
-
versions: ['2 - 2.3'],
|
|
45
|
-
patch (genericPool, tracer, config) {
|
|
46
|
-
this.wrap(genericPool, 'Pool', createWrapPool(tracer, config, this))
|
|
47
|
-
},
|
|
48
|
-
unpatch (genericPool) {
|
|
49
|
-
this.unwrap(genericPool, 'Pool')
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
]
|