dd-trace 2.0.0 → 2.2.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/index.d.ts +22 -0
- package/package.json +2 -2
- package/packages/datadog-instrumentations/index.js +6 -3
- package/packages/datadog-instrumentations/src/couchbase.js +143 -0
- package/packages/datadog-instrumentations/src/elasticsearch.js +74 -0
- package/packages/datadog-instrumentations/src/mysql.js +2 -2
- package/packages/datadog-instrumentations/src/mysql2.js +76 -0
- package/packages/datadog-instrumentations/src/q.js +9 -1
- package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -3
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +48 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +56 -6
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +33 -6
- 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-mysql/src/index.js +4 -4
- package/packages/datadog-plugin-mysql2/src/index.js +5 -88
- package/packages/datadog-plugin-next/src/index.js +10 -6
- package/packages/datadog-plugin-winston/src/index.js +33 -12
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +4 -0
- package/packages/dd-trace/src/appsec/recommended.json +5708 -1
- package/packages/dd-trace/src/profiling/config.js +5 -1
- package/packages/dd-trace/src/profiling/profiler.js +15 -6
- package/packages/dd-trace/src/profiling/profilers/cpu.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/heap.js +3 -2
- package/packages/dd-trace/src/tagger.js +14 -21
- package/packages/dd-trace/src/tracer.js +1 -1
- package/scripts/publish_docs.js +1 -1
- package/NOTICE +0 -4
- package/packages/dd-trace/src/profiling/mapper.js +0 -91
|
@@ -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
|
|
@@ -165,7 +165,28 @@ function getRes (reply) {
|
|
|
165
165
|
module.exports = [
|
|
166
166
|
{
|
|
167
167
|
name: 'fastify',
|
|
168
|
-
versions: ['>=
|
|
168
|
+
versions: ['>=3'],
|
|
169
|
+
patch (fastify, tracer, config) {
|
|
170
|
+
// `fastify` is a function so we return a wrapper that will replace its export.
|
|
171
|
+
const wrapped = this.wrapExport(fastify, createWrapFastify(tracer, config)(fastify))
|
|
172
|
+
|
|
173
|
+
wrapped.fastify = wrapped
|
|
174
|
+
wrapped.default = wrapped
|
|
175
|
+
|
|
176
|
+
return wrapped
|
|
177
|
+
},
|
|
178
|
+
unpatch (fastify) {
|
|
179
|
+
const unwrapped = this.unwrapExport(fastify)
|
|
180
|
+
|
|
181
|
+
unwrapped.fastify = unwrapped
|
|
182
|
+
unwrapped.default = unwrapped
|
|
183
|
+
|
|
184
|
+
return unwrapped
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: 'fastify',
|
|
189
|
+
versions: ['1 - 2'],
|
|
169
190
|
patch (fastify, tracer, config) {
|
|
170
191
|
// `fastify` is a function so we return a wrapper that will replace its export.
|
|
171
192
|
return this.wrapExport(fastify, createWrapFastify(tracer, config)(fastify))
|
|
@@ -12,7 +12,7 @@ class MySQLPlugin extends Plugin {
|
|
|
12
12
|
constructor (...args) {
|
|
13
13
|
super(...args)
|
|
14
14
|
|
|
15
|
-
this.addSub(
|
|
15
|
+
this.addSub(`apm:${this.constructor.name}:query:start`, ({ sql, conf }) => {
|
|
16
16
|
const store = storage.getStore()
|
|
17
17
|
const childOf = store ? store.span : store
|
|
18
18
|
const span = this.tracer.startSpan('mysql.query', {
|
|
@@ -37,18 +37,18 @@ class MySQLPlugin extends Plugin {
|
|
|
37
37
|
this.enter(span, store)
|
|
38
38
|
})
|
|
39
39
|
|
|
40
|
-
this.addSub(
|
|
40
|
+
this.addSub(`apm:${this.constructor.name}:query:end`, () => {
|
|
41
41
|
this.exit()
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
-
this.addSub(
|
|
44
|
+
this.addSub(`apm:${this.constructor.name}:query:error`, err => {
|
|
45
45
|
if (err) {
|
|
46
46
|
const span = storage.getStore().span
|
|
47
47
|
span.setTag('error', err)
|
|
48
48
|
}
|
|
49
49
|
})
|
|
50
50
|
|
|
51
|
-
this.addSub(
|
|
51
|
+
this.addSub(`apm:${this.constructor.name}:query:async-end`, () => {
|
|
52
52
|
const span = storage.getStore().span
|
|
53
53
|
span.finish()
|
|
54
54
|
})
|
|
@@ -1,94 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
3
|
+
const MySQLPlugin = require('../../datadog-plugin-mysql/src')
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return
|
|
9
|
-
const name = cmd && cmd.constructor && cmd.constructor.name
|
|
10
|
-
const isCommand = typeof cmd.execute === 'function'
|
|
11
|
-
const isSupported = name === 'Execute' || name === 'Query'
|
|
12
|
-
|
|
13
|
-
if (isCommand && isSupported) {
|
|
14
|
-
cmd.execute = wrapExecute(tracer, config, cmd.execute)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return addCommand.apply(this, arguments)
|
|
18
|
-
}
|
|
5
|
+
class MySQL2Plugin extends MySQLPlugin {
|
|
6
|
+
static get name () {
|
|
7
|
+
return 'mysql2'
|
|
19
8
|
}
|
|
20
9
|
}
|
|
21
10
|
|
|
22
|
-
|
|
23
|
-
const scope = tracer.scope()
|
|
24
|
-
const childOf = scope.active()
|
|
25
|
-
|
|
26
|
-
return function executeWithTrace (packet, connection) {
|
|
27
|
-
const connectionConfig = (connection && connection.config) || {}
|
|
28
|
-
const sql = this.statement ? this.statement.query : this.sql
|
|
29
|
-
const span = tracer.startSpan('mysql.query', {
|
|
30
|
-
childOf,
|
|
31
|
-
tags: {
|
|
32
|
-
[Tags.SPAN_KIND]: Tags.SPAN_KIND_RPC_CLIENT,
|
|
33
|
-
'service.name': config.service || `${tracer._service}-mysql`,
|
|
34
|
-
'resource.name': sql,
|
|
35
|
-
'span.type': 'sql',
|
|
36
|
-
'span.kind': 'client',
|
|
37
|
-
'db.type': 'mysql',
|
|
38
|
-
'db.user': connectionConfig.user,
|
|
39
|
-
'db.name': connectionConfig.database,
|
|
40
|
-
'out.host': connectionConfig.host,
|
|
41
|
-
'out.port': connectionConfig.port
|
|
42
|
-
}
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
analyticsSampler.sample(span, config.measured)
|
|
46
|
-
|
|
47
|
-
if (typeof this.onResult === 'function') {
|
|
48
|
-
this.onResult = wrapCallback(tracer, span, childOf, this.onResult)
|
|
49
|
-
} else {
|
|
50
|
-
this.on('error', error => span.addTags({ error }))
|
|
51
|
-
this.on('end', () => span.finish())
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
this.execute = execute
|
|
55
|
-
|
|
56
|
-
return scope.bind(execute, span).apply(this, arguments)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function wrapCallback (tracer, span, parent, done) {
|
|
61
|
-
return tracer.scope().bind((...args) => {
|
|
62
|
-
const [ error ] = args
|
|
63
|
-
span.addTags({ error })
|
|
64
|
-
|
|
65
|
-
span.finish()
|
|
66
|
-
|
|
67
|
-
done(...args)
|
|
68
|
-
}, parent)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
module.exports = [
|
|
72
|
-
{
|
|
73
|
-
name: 'mysql2',
|
|
74
|
-
file: 'lib/connection.js',
|
|
75
|
-
versions: ['>=1'],
|
|
76
|
-
patch (Connection, tracer, config) {
|
|
77
|
-
this.wrap(Connection.prototype, 'addCommand', createWrapAddCommand(tracer, config))
|
|
78
|
-
},
|
|
79
|
-
unpatch (Connection) {
|
|
80
|
-
this.unwrap(Connection.prototype, 'addCommand')
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: 'mysql2',
|
|
85
|
-
file: 'lib/commands/command.js',
|
|
86
|
-
versions: ['>=1'],
|
|
87
|
-
patch (Command, tracer, config) {
|
|
88
|
-
tracer.scope().bind(Command.prototype)
|
|
89
|
-
},
|
|
90
|
-
unpatch (Command, tracer) {
|
|
91
|
-
tracer.scope().unbind(Command.prototype)
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
]
|
|
11
|
+
module.exports = MySQL2Plugin
|
|
@@ -115,10 +115,10 @@ function trace (tracer, config, req, res, handler) {
|
|
|
115
115
|
// TODO: Use CLS when it will be available in core.
|
|
116
116
|
span._nextReq = req
|
|
117
117
|
|
|
118
|
-
promise.then(
|
|
119
|
-
span
|
|
120
|
-
finish(span, config, req, res)
|
|
121
|
-
|
|
118
|
+
promise.then(
|
|
119
|
+
() => finish(span, config, req, res),
|
|
120
|
+
err => finish(span, config, req, res, err)
|
|
121
|
+
)
|
|
122
122
|
|
|
123
123
|
return promise
|
|
124
124
|
}
|
|
@@ -132,7 +132,8 @@ function addPage (req, page) {
|
|
|
132
132
|
})
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
function finish (span, config, req, res) {
|
|
135
|
+
function finish (span, config, req, res, err) {
|
|
136
|
+
span.setTag('error', err || !config.validateStatus(res.statusCode))
|
|
136
137
|
span.addTags({
|
|
137
138
|
'http.status_code': res.statusCode
|
|
138
139
|
})
|
|
@@ -142,8 +143,11 @@ function finish (span, config, req, res) {
|
|
|
142
143
|
|
|
143
144
|
function normalizeConfig (config) {
|
|
144
145
|
const hooks = getHooks(config)
|
|
146
|
+
const validateStatus = typeof config.validateStatus === 'function'
|
|
147
|
+
? config.validateStatus
|
|
148
|
+
: code => code < 500
|
|
145
149
|
|
|
146
|
-
return Object.assign({}, config, { hooks })
|
|
150
|
+
return Object.assign({}, config, { hooks, validateStatus })
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
function getHooks (config) {
|
|
@@ -2,18 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
const { LOG } = require('../../../ext/formats')
|
|
4
4
|
|
|
5
|
+
const hasOwn = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
|
|
6
|
+
|
|
7
|
+
function chunkProxy (chunk, holder) {
|
|
8
|
+
return new Proxy(chunk, {
|
|
9
|
+
get (target, p, receiver) {
|
|
10
|
+
switch (p) {
|
|
11
|
+
case Symbol.toStringTag:
|
|
12
|
+
return Object.prototype.toString.call(target).slice(8, -1)
|
|
13
|
+
case 'dd':
|
|
14
|
+
return holder.dd
|
|
15
|
+
default:
|
|
16
|
+
return Reflect.get(target, p, receiver)
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
ownKeys (target) {
|
|
20
|
+
const ownKeys = Reflect.ownKeys(target)
|
|
21
|
+
return hasOwn(target, 'dd') ? ownKeys : ['dd', ...ownKeys]
|
|
22
|
+
},
|
|
23
|
+
getOwnPropertyDescriptor (target, p) {
|
|
24
|
+
return Reflect.getOwnPropertyDescriptor(p === 'dd' ? holder : target, p)
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
5
29
|
function createWrapWrite (tracer, config) {
|
|
6
30
|
return function wrapWrite (write) {
|
|
7
31
|
return function writeWithTrace (chunk, encoding, callback) {
|
|
8
32
|
const span = tracer.scope().active()
|
|
9
33
|
|
|
10
|
-
|
|
34
|
+
const holder = {}
|
|
35
|
+
tracer.inject(span, LOG, holder)
|
|
36
|
+
arguments[0] = chunkProxy(chunk, holder)
|
|
11
37
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
delete chunk.dd
|
|
15
|
-
|
|
16
|
-
return result
|
|
38
|
+
return write.apply(this, arguments)
|
|
17
39
|
}
|
|
18
40
|
}
|
|
19
41
|
}
|
|
@@ -42,15 +64,14 @@ function createWrapLog (tracer, config) {
|
|
|
42
64
|
return function logWithTrace (level, msg, meta, callback) {
|
|
43
65
|
const span = tracer.scope().active()
|
|
44
66
|
|
|
45
|
-
meta =
|
|
67
|
+
meta = meta || {}
|
|
46
68
|
|
|
47
|
-
|
|
69
|
+
const holder = {}
|
|
70
|
+
tracer.inject(span, LOG, holder)
|
|
48
71
|
|
|
49
|
-
|
|
72
|
+
arguments[2] = chunkProxy(meta, holder)
|
|
50
73
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return result
|
|
74
|
+
return log.apply(this, arguments)
|
|
54
75
|
}
|
|
55
76
|
}
|
|
56
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = '2.
|
|
1
|
+
module.exports = '2.2.0'
|
|
@@ -76,6 +76,10 @@ function incomingHttpEndTranslator (data) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// TODO: temporary express instrumentation, will use express plugin later
|
|
79
|
+
if (data.req.body !== undefined && data.req.body !== null) {
|
|
80
|
+
payload[addresses.HTTP_INCOMING_BODY] = data.req.body
|
|
81
|
+
}
|
|
82
|
+
|
|
79
83
|
if (data.req.query && typeof data.req.query === 'object') {
|
|
80
84
|
payload[addresses.HTTP_INCOMING_QUERY] = data.req.query
|
|
81
85
|
}
|