dd-trace 2.1.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 +22 -12
- package/package.json +3 -5
- package/packages/datadog-instrumentations/index.js +13 -3
- package/packages/datadog-instrumentations/src/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/couchbase.js +143 -0
- package/packages/datadog-instrumentations/src/elasticsearch.js +79 -0
- 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/mysql.js +2 -2
- package/packages/datadog-instrumentations/src/mysql2.js +5 -5
- package/packages/datadog-instrumentations/src/pino.js +105 -0
- package/packages/datadog-instrumentations/src/redis.js +118 -0
- package/packages/datadog-instrumentations/src/sharedb.js +78 -0
- package/packages/datadog-instrumentations/src/winston.js +57 -0
- package/packages/datadog-plugin-aws-sdk/src/helpers.js +1 -1
- package/packages/datadog-plugin-bunyan/src/index.js +5 -22
- package/packages/datadog-plugin-couchbase/src/index.js +51 -148
- package/packages/datadog-plugin-elasticsearch/src/index.js +41 -82
- package/packages/datadog-plugin-fastify/src/fastify.js +22 -1
- 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-mysql/src/index.js +4 -5
- package/packages/datadog-plugin-mysql2/src/index.js +11 -0
- 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 -110
- 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 +6 -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 +1 -3
- 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/dd-trace/src/tagger.js +14 -21
- package/packages/dd-trace/src/tracer.js +1 -1
- package/packages/datadog-plugin-generic-pool/src/index.js +0 -52
- package/packages/datadog-plugin-mongoose/src/index.js +0 -51
|
@@ -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
|
+
}
|
|
@@ -80,7 +80,7 @@ const helpers = {
|
|
|
80
80
|
if (!span) return
|
|
81
81
|
|
|
82
82
|
const service = services[serviceName] && services[serviceName]
|
|
83
|
-
if (service.requestInject) service.requestInject(span, request, tracer)
|
|
83
|
+
if (service && service.requestInject) service.requestInject(span, request, tracer)
|
|
84
84
|
},
|
|
85
85
|
|
|
86
86
|
wrapCb (cb, serviceName, tags, request, tracer, childOf) {
|
|
@@ -1,27 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const LogPlugin = require('../../dd-trace/src/plugins/log_plugin')
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return
|
|
8
|
-
const span = tracer.scope().active()
|
|
9
|
-
|
|
10
|
-
tracer.inject(span, LOG, rec)
|
|
11
|
-
|
|
12
|
-
return emit.apply(this, arguments)
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
module.exports = {
|
|
18
|
-
name: 'bunyan',
|
|
19
|
-
versions: ['>=1'],
|
|
20
|
-
patch (Logger, tracer, config) {
|
|
21
|
-
if (!tracer._logInjection) return
|
|
22
|
-
this.wrap(Logger.prototype, '_emit', createWrapEmit(tracer, config))
|
|
23
|
-
},
|
|
24
|
-
unpatch (Logger) {
|
|
25
|
-
this.unwrap(Logger.prototype, '_emit')
|
|
5
|
+
class BunyanPlugin extends LogPlugin {
|
|
6
|
+
static get name () {
|
|
7
|
+
return 'bunyan'
|
|
26
8
|
}
|
|
27
9
|
}
|
|
10
|
+
module.exports = BunyanPlugin
|
|
@@ -1,171 +1,74 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
3
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
4
|
+
const { storage } = require('../../datadog-core')
|
|
5
5
|
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
class CouchBasePlugin extends Plugin {
|
|
8
|
+
static get name () {
|
|
9
|
+
return 'couchbase'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
addSubs (func, start, asyncEnd = defaultAsyncEnd) {
|
|
13
|
+
this.addSub(`apm:couchbase:${func}:start`, start)
|
|
14
|
+
this.addSub(`apm:couchbase:${func}:end`, this.exit.bind(this))
|
|
15
|
+
this.addSub(`apm:couchbase:${func}:error`, errorHandler)
|
|
16
|
+
this.addSub(`apm:couchbase:${func}:async-end`, asyncEnd)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
startSpan (operation, customTags, store, bucket) {
|
|
20
|
+
const tags = {
|
|
12
21
|
'db.type': 'couchbase',
|
|
13
22
|
'component': 'couchbase',
|
|
14
|
-
'service.name': config.service || `${tracer._service}-couchbase`,
|
|
15
|
-
'resource.name':
|
|
16
|
-
|
|
23
|
+
'service.name': this.config.service || `${this.tracer._service}-couchbase`,
|
|
24
|
+
'resource.name': `couchbase.${operation}`,
|
|
25
|
+
'span.kind': 'client'
|
|
17
26
|
}
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
analyticsSampler.sample(span, config.measured)
|
|
21
|
-
|
|
22
|
-
return span
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function onRequestFinish (emitter, span) {
|
|
26
|
-
emitter.once('rows', () => {
|
|
27
|
-
span.finish()
|
|
28
|
-
})
|
|
29
|
-
emitter.once('error', (err) => {
|
|
30
|
-
span.setTag(Tags.ERROR, err)
|
|
31
|
-
span.finish()
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function createWrapMaybeInvoke (tracer) {
|
|
36
|
-
return function wrapMaybeInvoke (_maybeInvoke) {
|
|
37
|
-
return function maybeInvokeWithTrace (fn, args) {
|
|
38
|
-
if (!Array.isArray(args)) return _maybeInvoke.apply(this, arguments)
|
|
39
27
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const callback = args[callbackIndex]
|
|
43
|
-
|
|
44
|
-
if (callback instanceof Function) {
|
|
45
|
-
args[callbackIndex] = scope.bind(callback)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return scope.bind(_maybeInvoke).apply(this, arguments)
|
|
28
|
+
for (const tag in customTags) {
|
|
29
|
+
tags[tag] = customTags[tag]
|
|
49
30
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return function wrapQuery (query) {
|
|
55
|
-
return function queryWithTrace (q, params, callback) {
|
|
56
|
-
const scope = tracer.scope()
|
|
31
|
+
const span = this.tracer.startSpan(`couchbase.${operation}`, {
|
|
32
|
+
childOf: store ? store.span : null,
|
|
33
|
+
tags
|
|
34
|
+
})
|
|
57
35
|
|
|
58
|
-
|
|
36
|
+
span.setTag('couchbase.bucket.name', bucket.name || bucket._name)
|
|
59
37
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return scope.bind(query.apply(this, arguments))
|
|
65
|
-
}
|
|
38
|
+
analyticsSampler.sample(span, this.config.measured)
|
|
39
|
+
return span
|
|
66
40
|
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function createWrapN1qlReq (tracer, config) {
|
|
70
|
-
return function wrapN1qlReq (_n1qlReq) {
|
|
71
|
-
return function n1qlReqWithTrace (host, q, adhoc, emitter) {
|
|
72
|
-
if (!emitter || !emitter.once) return _n1qlReq.apply(this, arguments)
|
|
73
|
-
|
|
74
|
-
const scope = tracer.scope()
|
|
75
|
-
const n1qlQuery = q && q.statement
|
|
76
|
-
const span = startSpan(tracer, config, 'query', n1qlQuery)
|
|
77
41
|
|
|
78
|
-
|
|
42
|
+
constructor (...args) {
|
|
43
|
+
super(...args)
|
|
79
44
|
|
|
80
|
-
|
|
81
|
-
|
|
45
|
+
this.addSubs('query', ({ resource, bucket }) => {
|
|
46
|
+
const store = storage.getStore()
|
|
47
|
+
const span = this.startSpan('query', { 'span.type': 'sql', 'resource.name': resource }, store, bucket)
|
|
48
|
+
this.enter(span, store)
|
|
49
|
+
})
|
|
82
50
|
|
|
83
|
-
|
|
84
|
-
|
|
51
|
+
this._addCommandSubs('upsert')
|
|
52
|
+
this._addCommandSubs('insert')
|
|
53
|
+
this._addCommandSubs('replace')
|
|
54
|
+
this._addCommandSubs('append')
|
|
55
|
+
this._addCommandSubs('prepend')
|
|
85
56
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (callbackIndex < 0) return store.apply(this, arguments)
|
|
94
|
-
|
|
95
|
-
const scope = tracer.scope()
|
|
96
|
-
const span = startSpan(tracer, config, operation)
|
|
97
|
-
|
|
98
|
-
addBucketTag(span, this)
|
|
99
|
-
|
|
100
|
-
arguments[callbackIndex] = wrapCallback(span, arguments[callbackIndex])
|
|
101
|
-
|
|
102
|
-
return scope.bind(store, span).apply(this, arguments)
|
|
103
|
-
}
|
|
57
|
+
_addCommandSubs (name) {
|
|
58
|
+
this.addSubs(name, ({ bucket }) => {
|
|
59
|
+
const store = storage.getStore()
|
|
60
|
+
const span = this.startSpan(name, {}, store, bucket)
|
|
61
|
+
this.enter(span, store)
|
|
62
|
+
})
|
|
104
63
|
}
|
|
105
64
|
}
|
|
106
65
|
|
|
107
|
-
function
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function findCallbackIndex (args) {
|
|
112
|
-
for (let i = args.length - 1; i >= 2; i--) {
|
|
113
|
-
if (typeof args[i] === 'function') return i
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return -1
|
|
66
|
+
function defaultAsyncEnd () {
|
|
67
|
+
storage.getStore().span.finish()
|
|
117
68
|
}
|
|
118
69
|
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
span.setTag('error', err)
|
|
122
|
-
span.finish()
|
|
123
|
-
|
|
124
|
-
return callback.apply(this, arguments)
|
|
125
|
-
}
|
|
70
|
+
function errorHandler (error) {
|
|
71
|
+
storage.getStore().span.setTag('error', error)
|
|
126
72
|
}
|
|
127
73
|
|
|
128
|
-
module.exports =
|
|
129
|
-
{
|
|
130
|
-
name: 'couchbase',
|
|
131
|
-
versions: ['^2.6.5'],
|
|
132
|
-
file: 'lib/bucket.js',
|
|
133
|
-
patch (Bucket, tracer, config) {
|
|
134
|
-
tracer.scope().bind(Bucket.prototype)
|
|
135
|
-
|
|
136
|
-
this.wrap(Bucket.prototype, '_maybeInvoke', createWrapMaybeInvoke(tracer, config))
|
|
137
|
-
this.wrap(Bucket.prototype, 'query', createWrapQuery(tracer))
|
|
138
|
-
this.wrap(Bucket.prototype, '_n1qlReq', createWrapN1qlReq(tracer, config))
|
|
139
|
-
this.wrap(Bucket.prototype, 'upsert', createWrapStore(tracer, config, 'upsert'))
|
|
140
|
-
this.wrap(Bucket.prototype, 'insert', createWrapStore(tracer, config, 'insert'))
|
|
141
|
-
this.wrap(Bucket.prototype, 'replace', createWrapStore(tracer, config, 'replace'))
|
|
142
|
-
this.wrap(Bucket.prototype, 'append', createWrapStore(tracer, config, 'append'))
|
|
143
|
-
this.wrap(Bucket.prototype, 'prepend', createWrapStore(tracer, config, 'prepend'))
|
|
144
|
-
},
|
|
145
|
-
unpatch (Bucket, tracer) {
|
|
146
|
-
tracer.scope().unbind(Bucket.prototype)
|
|
147
|
-
|
|
148
|
-
this.unwrap(Bucket.prototype, '_maybeInvoke')
|
|
149
|
-
this.unwrap(Bucket.prototype, 'query')
|
|
150
|
-
this.unwrap(Bucket.prototype, '_n1qlReq')
|
|
151
|
-
this.unwrap(Bucket.prototype, 'upsert')
|
|
152
|
-
this.unwrap(Bucket.prototype, 'insert')
|
|
153
|
-
this.unwrap(Bucket.prototype, 'replace')
|
|
154
|
-
this.unwrap(Bucket.prototype, 'append')
|
|
155
|
-
this.unwrap(Bucket.prototype, 'prepend')
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
name: 'couchbase',
|
|
160
|
-
versions: ['^2.6.5'],
|
|
161
|
-
file: 'lib/cluster.js',
|
|
162
|
-
patch (Cluster, tracer, config) {
|
|
163
|
-
this.wrap(Cluster.prototype, '_maybeInvoke', createWrapMaybeInvoke(tracer, config))
|
|
164
|
-
this.wrap(Cluster.prototype, 'query', createWrapQuery(tracer))
|
|
165
|
-
},
|
|
166
|
-
unpatch (Cluster) {
|
|
167
|
-
this.unwrap(Cluster.prototype, '_maybeInvoke')
|
|
168
|
-
this.unwrap(Cluster.prototype, 'query')
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
]
|
|
74
|
+
module.exports = CouchBasePlugin
|
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
4
|
+
const { storage } = require('../../datadog-core')
|
|
4
5
|
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
class ElasticsearchPlugin extends Plugin {
|
|
8
|
+
static get name () {
|
|
9
|
+
return 'elasticsearch'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
constructor (...args) {
|
|
13
|
+
super(...args)
|
|
14
|
+
|
|
15
|
+
this.addSub('apm:elasticsearch:query:start', ({ params }) => {
|
|
16
|
+
this.config = normalizeConfig(this.config)
|
|
11
17
|
|
|
12
|
-
const
|
|
18
|
+
const store = storage.getStore()
|
|
19
|
+
const childOf = store ? store.span : store
|
|
13
20
|
const body = getBody(params.body || params.bulkBody)
|
|
14
|
-
const
|
|
15
|
-
const span = tracer.startSpan('elasticsearch.query', {
|
|
21
|
+
const span = this.tracer.startSpan('elasticsearch.query', {
|
|
16
22
|
childOf,
|
|
17
23
|
tags: {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
'service.name': config.service || `${tracer._service}-elasticsearch`,
|
|
24
|
+
'db.type': 'elasticsearch',
|
|
25
|
+
'span.kind': 'client',
|
|
26
|
+
'service.name': this.config.service || `${this.tracer._service}-elasticsearch`,
|
|
21
27
|
'resource.name': `${params.method} ${quantizePath(params.path)}`,
|
|
22
28
|
'span.type': 'elasticsearch',
|
|
23
29
|
'elasticsearch.url': params.path,
|
|
@@ -26,57 +32,25 @@ function createWrapRequest (tracer, config) {
|
|
|
26
32
|
'elasticsearch.params': JSON.stringify(params.querystring || params.query)
|
|
27
33
|
}
|
|
28
34
|
})
|
|
35
|
+
analyticsSampler.sample(span, this.config.measured)
|
|
36
|
+
this.enter(span, store)
|
|
37
|
+
})
|
|
29
38
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (typeof cb === 'function') {
|
|
35
|
-
arguments[lastIndex] = wrapCallback(tracer, span, params, config, cb)
|
|
36
|
-
|
|
37
|
-
return tracer.scope().activate(span, () => request.apply(this, arguments))
|
|
38
|
-
} else {
|
|
39
|
-
const promise = request.apply(this, arguments)
|
|
40
|
-
|
|
41
|
-
if (promise && typeof promise.then === 'function') {
|
|
42
|
-
promise.then(() => finish(span, params, config), e => finish(span, params, config, e))
|
|
43
|
-
} else {
|
|
44
|
-
finish(span, params, config)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return promise
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
39
|
+
this.addSub('apm:elasticsearch:query:end', () => {
|
|
40
|
+
this.exit()
|
|
41
|
+
})
|
|
52
42
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
})
|
|
58
|
-
}
|
|
43
|
+
this.addSub('apm:elasticsearch:query:error', err => {
|
|
44
|
+
const span = storage.getStore().span
|
|
45
|
+
span.setTag('error', err)
|
|
46
|
+
})
|
|
59
47
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
'error.msg': err.message,
|
|
65
|
-
'error.stack': err.stack
|
|
48
|
+
this.addSub('apm:elasticsearch:query:async-end', ({ params }) => {
|
|
49
|
+
const span = storage.getStore().span
|
|
50
|
+
this.config.hooks.query(span, params)
|
|
51
|
+
span.finish()
|
|
66
52
|
})
|
|
67
53
|
}
|
|
68
|
-
|
|
69
|
-
config.hooks.query(span, params)
|
|
70
|
-
|
|
71
|
-
span.finish()
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function quantizePath (path) {
|
|
75
|
-
return path && path.replace(/[0-9]+/g, '?')
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function getBody (body) {
|
|
79
|
-
return body && JSON.stringify(body)
|
|
80
54
|
}
|
|
81
55
|
|
|
82
56
|
function normalizeConfig (config) {
|
|
@@ -94,27 +68,12 @@ function getHooks (config) {
|
|
|
94
68
|
return { query }
|
|
95
69
|
}
|
|
96
70
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
this.unwrap(Transport.prototype, 'request')
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
name: '@elastic/elasticsearch',
|
|
111
|
-
file: 'lib/Transport.js',
|
|
112
|
-
versions: ['>=5.6.16'], // initial version of this module
|
|
113
|
-
patch (Transport, tracer, config) {
|
|
114
|
-
this.wrap(Transport.prototype, 'request', createWrapRequest(tracer, config))
|
|
115
|
-
},
|
|
116
|
-
unpatch (Transport) {
|
|
117
|
-
this.unwrap(Transport.prototype, 'request')
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
]
|
|
71
|
+
function getBody (body) {
|
|
72
|
+
return body && JSON.stringify(body)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function quantizePath (path) {
|
|
76
|
+
return path && path.replace(/[0-9]+/g, '?')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = ElasticsearchPlugin
|