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
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -22,8 +22,6 @@ require,path-to-regexp,MIT,Copyright 2014 Blake Embrey
|
|
|
22
22
|
require,performance-now,MIT,Copyright 2013 Braveg1rl
|
|
23
23
|
require,retry,MIT,Copyright 2011 Tim Koschützki Felix Geisendörfer
|
|
24
24
|
require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
|
|
25
|
-
require,source-map,BSD-3-Clause,Copyright 2009-2011 Mozilla Foundation and contributors
|
|
26
|
-
require,source-map-resolve,MIT,Copyright 2014-2020 Simon Lydell 2019 Jinxiang
|
|
27
25
|
dev,autocannon,MIT,Copyright 2016 Matteo Collina
|
|
28
26
|
dev,axios,MIT,Copyright 2014-present Matt Zabriskie
|
|
29
27
|
dev,benchmark,MIT,Copyright 2010-2016 Mathias Bynens Robert Kieffer John-David Dalton
|
package/index.d.ts
CHANGED
|
@@ -186,18 +186,6 @@ export declare interface SamplingRule {
|
|
|
186
186
|
* List of options available to the tracer.
|
|
187
187
|
*/
|
|
188
188
|
export declare interface TracerOptions {
|
|
189
|
-
/**
|
|
190
|
-
* Whether to enable the tracer.
|
|
191
|
-
* @default true
|
|
192
|
-
*/
|
|
193
|
-
enabled?: boolean;
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Enable debug logging in the tracer.
|
|
197
|
-
* @default false
|
|
198
|
-
*/
|
|
199
|
-
debug?: boolean;
|
|
200
|
-
|
|
201
189
|
/**
|
|
202
190
|
* Whether to enable trace ID injection in log records to be able to correlate
|
|
203
191
|
* traces with logs.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"crypto-randomuuid": "^1.0.0",
|
|
70
70
|
"diagnostics_channel": "^1.1.0",
|
|
71
71
|
"form-data": "^3.0.0",
|
|
72
|
-
"import-in-the-middle": "^1.1
|
|
72
|
+
"import-in-the-middle": "^1.2.1",
|
|
73
73
|
"koalas": "^1.0.2",
|
|
74
74
|
"limiter": "^1.1.4",
|
|
75
75
|
"lodash.kebabcase": "^4.1.1",
|
|
@@ -83,9 +83,7 @@
|
|
|
83
83
|
"path-to-regexp": "^0.1.2",
|
|
84
84
|
"performance-now": "^2.1.0",
|
|
85
85
|
"retry": "^0.10.1",
|
|
86
|
-
"semver": "^5.5.0"
|
|
87
|
-
"source-map": "^0.7.3",
|
|
88
|
-
"source-map-resolve": "^0.6.0"
|
|
86
|
+
"semver": "^5.5.0"
|
|
89
87
|
},
|
|
90
88
|
"devDependencies": {
|
|
91
89
|
"autocannon": "^4.5.2",
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
require('./src/bluebird')
|
|
4
|
+
require('./src/bunyan')
|
|
4
5
|
require('./src/couchbase')
|
|
5
6
|
require('./src/dns')
|
|
6
7
|
require('./src/elasticsearch')
|
|
8
|
+
require('./src/generic-pool')
|
|
9
|
+
require('./src/ioredis')
|
|
7
10
|
require('./src/memcached')
|
|
11
|
+
require('./src/mongoose')
|
|
8
12
|
require('./src/mysql')
|
|
9
13
|
require('./src/mysql2')
|
|
14
|
+
require('./src/pino')
|
|
10
15
|
require('./src/promise')
|
|
11
16
|
require('./src/promise-js')
|
|
12
17
|
require('./src/q')
|
|
18
|
+
require('./src/redis')
|
|
19
|
+
require('./src/sharedb')
|
|
13
20
|
require('./src/when')
|
|
21
|
+
require('./src/winston')
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook
|
|
6
|
+
} = require('./helpers/instrument')
|
|
7
|
+
const shimmer = require('../../datadog-shimmer')
|
|
8
|
+
|
|
9
|
+
addHook({ name: 'bunyan', versions: ['>=1'] }, Logger => {
|
|
10
|
+
const logCh = channel('apm:bunyan:log')
|
|
11
|
+
shimmer.wrap(Logger.prototype, '_emit', emit => {
|
|
12
|
+
return function wrappedEmit (rec) {
|
|
13
|
+
if (logCh.hasSubscribers) {
|
|
14
|
+
const payload = { message: rec }
|
|
15
|
+
logCh.publish(payload)
|
|
16
|
+
arguments[0] = payload.message
|
|
17
|
+
}
|
|
18
|
+
return emit.apply(this, arguments)
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
return Logger
|
|
22
|
+
})
|
|
@@ -12,7 +12,12 @@ const asyncEndCh = channel('apm:elasticsearch:query:async-end')
|
|
|
12
12
|
const endCh = channel('apm:elasticsearch:query:end')
|
|
13
13
|
const errorCh = channel('apm:elasticsearch:query:error')
|
|
14
14
|
|
|
15
|
-
addHook({ name: '@elastic/
|
|
15
|
+
addHook({ name: '@elastic/transport', file: 'lib/Transport.js', versions: ['>=8'] }, (exports) => {
|
|
16
|
+
shimmer.wrap(exports.default.prototype, 'request', wrapRequest)
|
|
17
|
+
return exports
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
addHook({ name: '@elastic/elasticsearch', file: 'lib/Transport.js', versions: ['>=5.6.16 <8', '>=8'] }, Transport => {
|
|
16
21
|
shimmer.wrap(Transport.prototype, 'request', wrapRequest)
|
|
17
22
|
return Transport
|
|
18
23
|
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { addHook, AsyncResource } = require('./helpers/instrument')
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
|
|
6
|
+
function createWrapAcquire () {
|
|
7
|
+
return function wrapAcquire (acquire) {
|
|
8
|
+
return function acquireWithTrace (callback, priority) {
|
|
9
|
+
if (typeof callback === 'function') {
|
|
10
|
+
arguments[0] = AsyncResource.bind(callback)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return acquire.apply(this, arguments)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function createWrapPool () {
|
|
19
|
+
return function wrapPool (Pool) {
|
|
20
|
+
if (typeof Pool !== 'function') return Pool
|
|
21
|
+
|
|
22
|
+
return function PoolWithTrace (factory) {
|
|
23
|
+
const pool = Pool.apply(this, arguments)
|
|
24
|
+
|
|
25
|
+
if (pool && typeof pool.acquire === 'function') {
|
|
26
|
+
shimmer.wrap(pool, 'acquire', createWrapAcquire())
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return pool
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
addHook({
|
|
35
|
+
name: 'generic-pool',
|
|
36
|
+
versions: ['^2.4']
|
|
37
|
+
}, genericPool => {
|
|
38
|
+
shimmer.wrap(genericPool.Pool.prototype, 'acquire', createWrapAcquire())
|
|
39
|
+
return genericPool
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
addHook({
|
|
43
|
+
name: 'generic-pool',
|
|
44
|
+
versions: ['2 - 2.3']
|
|
45
|
+
}, genericPool => {
|
|
46
|
+
shimmer.wrap(genericPool, 'Pool', createWrapPool())
|
|
47
|
+
return genericPool
|
|
48
|
+
})
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook
|
|
6
|
+
} = require('./helpers/instrument')
|
|
7
|
+
const shimmer = require('../../datadog-shimmer')
|
|
8
|
+
|
|
9
|
+
const startCh = channel('apm:ioredis:command:start')
|
|
10
|
+
const asyncEndCh = channel('apm:ioredis:command:async-end')
|
|
11
|
+
const endCh = channel('apm:ioredis:command:end')
|
|
12
|
+
const errorCh = channel('apm:ioredis:command:error')
|
|
13
|
+
|
|
14
|
+
addHook({ name: 'ioredis', versions: ['>=2'] }, Redis => {
|
|
15
|
+
shimmer.wrap(Redis.prototype, 'sendCommand', sendCommand => function (command, stream) {
|
|
16
|
+
if (!startCh.hasSubscribers) return sendCommand.apply(this, arguments)
|
|
17
|
+
|
|
18
|
+
if (!command || !command.promise) return sendCommand.apply(this, arguments)
|
|
19
|
+
|
|
20
|
+
const options = this.options || {}
|
|
21
|
+
const connectionName = options.connectionName
|
|
22
|
+
const db = options.db
|
|
23
|
+
const connectionOptions = { host: options.host, port: options.port }
|
|
24
|
+
startCh.publish({ db, command: command.name, args: command.args, connectionOptions, connectionName })
|
|
25
|
+
|
|
26
|
+
command.promise.then(
|
|
27
|
+
() => finish(asyncEndCh, errorCh),
|
|
28
|
+
err => finish(asyncEndCh, errorCh, err)
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
return sendCommand.apply(this, arguments)
|
|
33
|
+
} catch (err) {
|
|
34
|
+
errorCh.publish(err)
|
|
35
|
+
|
|
36
|
+
throw err
|
|
37
|
+
} finally {
|
|
38
|
+
endCh.publish(undefined)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
return Redis
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
function finish (asyncEndCh, errorCh, error) {
|
|
45
|
+
if (error) {
|
|
46
|
+
errorCh.publish(error)
|
|
47
|
+
}
|
|
48
|
+
asyncEndCh.publish(undefined)
|
|
49
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { addHook } = require('./helpers/instrument')
|
|
4
|
+
const { wrapThen } = require('./helpers/promise')
|
|
5
|
+
const { AsyncResource } = require('./helpers/instrument')
|
|
6
|
+
const shimmer = require('../../datadog-shimmer')
|
|
7
|
+
|
|
8
|
+
function wrapAddQueue (addQueue) {
|
|
9
|
+
return function addQueueWithTrace (name) {
|
|
10
|
+
if (typeof name === 'function') {
|
|
11
|
+
arguments[0] = AsyncResource.bind(name)
|
|
12
|
+
} else if (typeof this[name] === 'function') {
|
|
13
|
+
arguments[0] = AsyncResource.bind((...args) => this[name](...args))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return addQueue.apply(this, arguments)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
addHook({
|
|
21
|
+
name: 'mongoose',
|
|
22
|
+
versions: ['>=4.6.4']
|
|
23
|
+
}, mongoose => {
|
|
24
|
+
if (mongoose.Promise !== global.Promise) {
|
|
25
|
+
shimmer.wrap(mongoose.Promise.prototype, 'then', wrapThen)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
shimmer.wrap(mongoose.Collection.prototype, 'addQueue', wrapAddQueue)
|
|
29
|
+
return mongoose
|
|
30
|
+
})
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook
|
|
6
|
+
} = require('./helpers/instrument')
|
|
7
|
+
const shimmer = require('../../datadog-shimmer')
|
|
8
|
+
|
|
9
|
+
function wrapPino (symbol, wrapper, pino) {
|
|
10
|
+
return function pinoWithTrace () {
|
|
11
|
+
const instance = pino.apply(this, arguments)
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(instance, symbol, {
|
|
14
|
+
configurable: true,
|
|
15
|
+
enumerable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: wrapper(instance[symbol])
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
return instance
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function wrapAsJson (asJson) {
|
|
25
|
+
const ch = channel('apm:pino:log')
|
|
26
|
+
return function asJsonWithTrace (obj, msg, num, time) {
|
|
27
|
+
obj = arguments[0] = obj || {}
|
|
28
|
+
|
|
29
|
+
const payload = { message: obj }
|
|
30
|
+
ch.publish(payload)
|
|
31
|
+
arguments[0] = payload.message
|
|
32
|
+
|
|
33
|
+
return asJson.apply(this, arguments)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function wrapMixin (mixin) {
|
|
38
|
+
const ch = channel('apm:pino:log')
|
|
39
|
+
return function mixinWithTrace () {
|
|
40
|
+
let obj = {}
|
|
41
|
+
|
|
42
|
+
if (mixin) {
|
|
43
|
+
obj = mixin.apply(this, arguments)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const payload = { message: obj }
|
|
47
|
+
ch.publish(payload)
|
|
48
|
+
|
|
49
|
+
return payload.message
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function wrapPrettifyObject (prettifyObject) {
|
|
54
|
+
const ch = channel('apm:pino:log')
|
|
55
|
+
return function prettifyObjectWithTrace (input) {
|
|
56
|
+
const payload = { message: input.input }
|
|
57
|
+
ch.publish(payload)
|
|
58
|
+
input.input = payload.message
|
|
59
|
+
return prettifyObject.apply(this, arguments)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function wrapPrettyFactory (prettyFactory) {
|
|
64
|
+
const ch = channel('apm:pino:log')
|
|
65
|
+
return function prettyFactoryWithTrace () {
|
|
66
|
+
const pretty = prettyFactory.apply(this, arguments)
|
|
67
|
+
return function prettyWithTrace (obj) {
|
|
68
|
+
const payload = { message: obj }
|
|
69
|
+
ch.publish(payload)
|
|
70
|
+
arguments[0] = payload.message
|
|
71
|
+
return pretty.apply(this, arguments)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
addHook({ name: 'pino', versions: ['2 - 3', '4', '>=5 <5.14.0'] }, pino => {
|
|
77
|
+
const asJsonSym = (pino.symbols && pino.symbols.asJsonSym) || 'asJson'
|
|
78
|
+
|
|
79
|
+
return shimmer.wrap(pino, wrapPino(asJsonSym, wrapAsJson, pino))
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
addHook({ name: 'pino', versions: ['>=5.14.0 <6.8.0'] }, pino => {
|
|
83
|
+
const mixinSym = pino.symbols.mixinSym
|
|
84
|
+
|
|
85
|
+
return shimmer.wrap(pino, wrapPino(mixinSym, wrapMixin, pino))
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
addHook({ name: 'pino', versions: ['>=6.8.0'] }, pino => {
|
|
89
|
+
const mixinSym = pino.symbols.mixinSym
|
|
90
|
+
|
|
91
|
+
const wrapped = shimmer.wrap(pino, wrapPino(mixinSym, wrapMixin, pino))
|
|
92
|
+
wrapped.pino = wrapped
|
|
93
|
+
wrapped.default = wrapped
|
|
94
|
+
|
|
95
|
+
return wrapped
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
addHook({ name: 'pino-pretty', file: 'lib/utils.js', versions: ['>=3'] }, utils => {
|
|
99
|
+
shimmer.wrap(utils, 'prettifyObject', wrapPrettifyObject)
|
|
100
|
+
return utils
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
addHook({ name: 'pino-pretty', versions: ['1 - 2'] }, prettyFactory => {
|
|
104
|
+
return shimmer.wrap(prettyFactory, wrapPrettyFactory(prettyFactory))
|
|
105
|
+
})
|
|
@@ -0,0 +1,118 @@
|
|
|
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 startCh = channel('apm:redis:command:start')
|
|
11
|
+
const asyncEndCh = channel('apm:redis:command:async-end')
|
|
12
|
+
const endCh = channel('apm:redis:command:end')
|
|
13
|
+
const errorCh = channel('apm:redis:command:error')
|
|
14
|
+
|
|
15
|
+
addHook({ name: '@node-redis/client', file: 'dist/lib/client/commands-queue.js', versions: ['>=1'] }, redis => {
|
|
16
|
+
shimmer.wrap(redis.default.prototype, 'addCommand', addCommand => function (command) {
|
|
17
|
+
if (!startCh.hasSubscribers) {
|
|
18
|
+
return addCommand.apply(this, arguments)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const name = command[0]
|
|
22
|
+
const args = command.slice(1)
|
|
23
|
+
|
|
24
|
+
startSpan(this, name, args)
|
|
25
|
+
|
|
26
|
+
const res = addCommand.apply(this, arguments)
|
|
27
|
+
|
|
28
|
+
res.then(
|
|
29
|
+
() => finish(asyncEndCh, errorCh),
|
|
30
|
+
err => finish(asyncEndCh, errorCh, err)
|
|
31
|
+
)
|
|
32
|
+
endCh.publish(undefined)
|
|
33
|
+
return res
|
|
34
|
+
})
|
|
35
|
+
return redis
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
addHook({ name: 'redis', versions: ['>=2.6 <4'] }, redis => {
|
|
39
|
+
shimmer.wrap(redis.RedisClient.prototype, 'internal_send_command', internalSendCommand => function (options) {
|
|
40
|
+
if (!startCh.hasSubscribers) return internalSendCommand.apply(this, arguments)
|
|
41
|
+
|
|
42
|
+
if (!options.callback) return internalSendCommand.apply(this, arguments)
|
|
43
|
+
|
|
44
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
45
|
+
|
|
46
|
+
const cb = asyncResource.bind(options.callback)
|
|
47
|
+
|
|
48
|
+
startSpan(this, options.command, options.args)
|
|
49
|
+
|
|
50
|
+
options.callback = AsyncResource.bind(wrapCallback(asyncEndCh, errorCh, cb))
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
return internalSendCommand.apply(this, arguments)
|
|
54
|
+
} catch (err) {
|
|
55
|
+
errorCh.publish(err)
|
|
56
|
+
|
|
57
|
+
throw err
|
|
58
|
+
} finally {
|
|
59
|
+
endCh.publish(undefined)
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
return redis
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
addHook({ name: 'redis', versions: ['>=0.12 <2.6'] }, redis => {
|
|
66
|
+
shimmer.wrap(redis.RedisClient.prototype, 'send_command', sendCommand => function (command, args, callback) {
|
|
67
|
+
if (!startCh.hasSubscribers) {
|
|
68
|
+
return sendCommand.apply(this, arguments)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
72
|
+
|
|
73
|
+
startSpan(this, command, args)
|
|
74
|
+
|
|
75
|
+
if (typeof callback === 'function') {
|
|
76
|
+
const cb = asyncResource.bind(callback)
|
|
77
|
+
arguments[2] = AsyncResource.bind(wrapCallback(asyncEndCh, errorCh, cb))
|
|
78
|
+
} else if (Array.isArray(args) && typeof args[args.length - 1] === 'function') {
|
|
79
|
+
const cb = asyncResource.bind(args[args.length - 1])
|
|
80
|
+
args[args.length - 1] = AsyncResource.bind(wrapCallback(asyncEndCh, errorCh, cb))
|
|
81
|
+
} else {
|
|
82
|
+
arguments[2] = AsyncResource.bind(wrapCallback(asyncEndCh, errorCh))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
return sendCommand.apply(this, arguments)
|
|
87
|
+
} catch (err) {
|
|
88
|
+
errorCh.publish(err)
|
|
89
|
+
|
|
90
|
+
throw err
|
|
91
|
+
} finally {
|
|
92
|
+
endCh.publish(undefined)
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
return redis
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
function startSpan (client, command, args) {
|
|
99
|
+
const db = client.selected_db
|
|
100
|
+
const connectionOptions = client.connection_options || client.connection_option || client.connectionOption || {}
|
|
101
|
+
startCh.publish({ db, command, args, connectionOptions })
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function wrapCallback (asyncEndCh, errorCh, callback) {
|
|
105
|
+
return function (err) {
|
|
106
|
+
finish(asyncEndCh, errorCh, err)
|
|
107
|
+
if (callback) {
|
|
108
|
+
return callback.apply(this, arguments)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function finish (asyncEndCh, errorCh, error) {
|
|
114
|
+
if (error) {
|
|
115
|
+
errorCh.publish(error)
|
|
116
|
+
}
|
|
117
|
+
asyncEndCh.publish(undefined)
|
|
118
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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
|