dd-trace 2.8.0 → 2.9.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/ci/init.js +22 -6
- package/ci/jest/env.js +19 -7
- package/ext/tags.d.ts +1 -0
- package/ext/tags.js +2 -1
- package/index.d.ts +4 -2
- package/package.json +1 -1
- package/packages/datadog-core/src/storage/async_resource.js +1 -1
- package/packages/datadog-instrumentations/src/aws-sdk.js +5 -4
- package/packages/datadog-instrumentations/src/fastify.js +84 -92
- package/packages/datadog-instrumentations/src/koa.js +10 -7
- package/packages/datadog-plugin-http2/src/server.js +3 -1
- package/packages/datadog-plugin-mysql/src/index.js +18 -7
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +3 -3
- package/packages/dd-trace/src/plugins/util/web.js +3 -1
- package/scripts/install_plugin_modules.js +2 -4
package/ci/init.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
1
3
|
const path = require('path')
|
|
2
4
|
const tracer = require('../packages/dd-trace')
|
|
3
5
|
const { ORIGIN_KEY } = require('../packages/dd-trace/src/constants')
|
|
@@ -11,9 +13,22 @@ const options = {
|
|
|
11
13
|
}
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
let shouldInit = true
|
|
17
|
+
|
|
18
|
+
const isAgentlessEnabled = process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED &&
|
|
19
|
+
process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== 'false' &&
|
|
20
|
+
process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== '0'
|
|
21
|
+
|
|
22
|
+
if (isAgentlessEnabled) {
|
|
23
|
+
if (process.env.DATADOG_API_KEY || process.env.DD_API_KEY) {
|
|
24
|
+
options.experimental = {
|
|
25
|
+
exporter: 'datadog'
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
console.error(`DD_CIVISIBILITY_AGENTLESS_ENABLED is set, \
|
|
29
|
+
but neither DD_API_KEY nor DATADOG_API_KEY are set in your environment, \
|
|
30
|
+
so dd-trace will not be initialized.`)
|
|
31
|
+
shouldInit = false
|
|
17
32
|
}
|
|
18
33
|
}
|
|
19
34
|
|
|
@@ -36,8 +51,9 @@ try {
|
|
|
36
51
|
// ignore error and let the tracer initialize anyway
|
|
37
52
|
}
|
|
38
53
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
tracer.use('fs', false)
|
|
54
|
+
if (shouldInit) {
|
|
55
|
+
tracer.init(options)
|
|
56
|
+
tracer.use('fs', false)
|
|
57
|
+
}
|
|
42
58
|
|
|
43
59
|
module.exports = tracer
|
package/ci/jest/env.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
1
3
|
const tracer = require('../../packages/dd-trace')
|
|
2
4
|
const { ORIGIN_KEY } = require('../../packages/dd-trace/src/constants')
|
|
3
5
|
|
|
@@ -8,13 +10,23 @@ const options = {
|
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const isAgentlessEnabled = process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED &&
|
|
14
|
+
process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== 'false' &&
|
|
15
|
+
process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== '0'
|
|
16
|
+
|
|
17
|
+
if (isAgentlessEnabled) {
|
|
18
|
+
if (process.env.DATADOG_API_KEY || process.env.DD_API_KEY) {
|
|
19
|
+
tracer.init({
|
|
20
|
+
...options,
|
|
21
|
+
experimental: {
|
|
22
|
+
exporter: 'datadog'
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
} else {
|
|
26
|
+
console.error(`DD_CIVISIBILITY_AGENTLESS_ENABLED is set, \
|
|
27
|
+
but neither DD_API_KEY nor DATADOG_API_KEY are set in your environment, \
|
|
28
|
+
so dd-trace will not be initialized.`)
|
|
29
|
+
}
|
|
18
30
|
} else {
|
|
19
31
|
tracer.init({
|
|
20
32
|
...options,
|
package/ext/tags.d.ts
CHANGED
package/ext/tags.js
CHANGED
|
@@ -19,7 +19,8 @@ const tags = {
|
|
|
19
19
|
HTTP_STATUS_CODE: 'http.status_code',
|
|
20
20
|
HTTP_ROUTE: 'http.route',
|
|
21
21
|
HTTP_REQUEST_HEADERS: 'http.request.headers',
|
|
22
|
-
HTTP_RESPONSE_HEADERS: 'http.response.headers'
|
|
22
|
+
HTTP_RESPONSE_HEADERS: 'http.response.headers',
|
|
23
|
+
HTTP_USERAGENT: 'http.useragent'
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
// Deprecated
|
package/index.d.ts
CHANGED
|
@@ -1210,13 +1210,15 @@ declare namespace plugins {
|
|
|
1210
1210
|
* This plugin automatically instruments the
|
|
1211
1211
|
* [mysql](https://github.com/mysqljs/mysql) module.
|
|
1212
1212
|
*/
|
|
1213
|
-
interface mysql extends Instrumentation {
|
|
1213
|
+
interface mysql extends Instrumentation {
|
|
1214
|
+
service?: string | ((params: any) => string);
|
|
1215
|
+
}
|
|
1214
1216
|
|
|
1215
1217
|
/**
|
|
1216
1218
|
* This plugin automatically instruments the
|
|
1217
1219
|
* [mysql2](https://github.com/brianmario/mysql2) module.
|
|
1218
1220
|
*/
|
|
1219
|
-
interface mysql2 extends
|
|
1221
|
+
interface mysql2 extends mysql {}
|
|
1220
1222
|
|
|
1221
1223
|
/**
|
|
1222
1224
|
* This plugin automatically instruments the
|
package/package.json
CHANGED
|
@@ -15,13 +15,14 @@ function wrapRequest (send) {
|
|
|
15
15
|
const channelSuffix = getChannelSuffix(serviceIdentifier)
|
|
16
16
|
const startCh = channel(`apm:aws:request:start:${channelSuffix}`)
|
|
17
17
|
if (!startCh.hasSubscribers) return send.apply(this, arguments)
|
|
18
|
+
const innerAr = new AsyncResource('apm:aws:request:inner')
|
|
18
19
|
const outerAr = new AsyncResource('apm:aws:request:outer')
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
return innerAr.runInAsyncScope(() => {
|
|
22
|
+
this.on('complete', innerAr.bind(response => {
|
|
23
|
+
channel(`apm:aws:request:complete:${channelSuffix}`).publish({ response })
|
|
24
|
+
}))
|
|
23
25
|
|
|
24
|
-
return new AsyncResource('apm:aws:request:inner').runInAsyncScope(() => {
|
|
25
26
|
startCh.publish({
|
|
26
27
|
serviceIdentifier,
|
|
27
28
|
operation: this.operation,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const methods = require('methods').concat('all')
|
|
4
3
|
const shimmer = require('../../datadog-shimmer')
|
|
5
4
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
6
5
|
|
|
@@ -8,26 +7,28 @@ const errorChannel = channel('apm:fastify:middleware:error')
|
|
|
8
7
|
const handleChannel = channel('apm:fastify:request:handle')
|
|
9
8
|
|
|
10
9
|
const requestResources = new WeakMap()
|
|
10
|
+
const parsingResources = new WeakMap()
|
|
11
11
|
|
|
12
|
-
function wrapFastify (fastify) {
|
|
12
|
+
function wrapFastify (fastify, hasParsingEvents) {
|
|
13
13
|
if (typeof fastify !== 'function') return fastify
|
|
14
14
|
|
|
15
15
|
return function fastifyWithTrace () {
|
|
16
16
|
const app = fastify.apply(this, arguments)
|
|
17
17
|
|
|
18
|
-
if (!app) return app
|
|
18
|
+
if (!app || typeof app.addHook !== 'function') return app
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
app.addHook = wrapAddHook(app.addHook)
|
|
23
|
-
app.addHook('preHandler', preHandler)
|
|
24
|
-
}
|
|
20
|
+
app.addHook('onRequest', onRequest)
|
|
21
|
+
app.addHook('preHandler', preHandler)
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
app
|
|
28
|
-
|
|
23
|
+
if (hasParsingEvents) {
|
|
24
|
+
app.addHook('preParsing', preParsing)
|
|
25
|
+
app.addHook('preValidation', preValidation)
|
|
26
|
+
} else {
|
|
27
|
+
app.addHook('onRequest', preParsing)
|
|
28
|
+
app.addHook('preHandler', preValidation)
|
|
29
|
+
}
|
|
29
30
|
|
|
30
|
-
app.
|
|
31
|
+
app.addHook = wrapAddHook(app.addHook)
|
|
31
32
|
|
|
32
33
|
return app
|
|
33
34
|
}
|
|
@@ -45,114 +46,102 @@ function wrapAddHook (addHook) {
|
|
|
45
46
|
|
|
46
47
|
if (!requestResource) return fn.apply(this, arguments)
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
try {
|
|
50
|
+
if (typeof done === 'function') {
|
|
51
|
+
done = arguments[arguments.length - 1]
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
done = arguments[arguments.length - 1]
|
|
53
|
+
arguments[arguments.length - 1] = function (err) {
|
|
54
|
+
publishError(err, requestResource)
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return done.apply(this, arguments)
|
|
58
|
-
})
|
|
56
|
+
if (name === 'onRequest' || name === 'preParsing') {
|
|
57
|
+
const parsingResource = new AsyncResource('bound-anonymous-fn')
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
} else {
|
|
62
|
-
const promise = hookResource.bind(fn).apply(this, arguments)
|
|
59
|
+
parsingResources.set(req, parsingResource)
|
|
63
60
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
errorChannel.publish(err)
|
|
67
|
-
throw err
|
|
61
|
+
return parsingResource.runInAsyncScope(() => {
|
|
62
|
+
return done.apply(this, arguments)
|
|
68
63
|
})
|
|
64
|
+
} else {
|
|
65
|
+
return done.apply(this, arguments)
|
|
69
66
|
}
|
|
67
|
+
}
|
|
70
68
|
|
|
71
|
-
|
|
69
|
+
return fn.apply(this, arguments)
|
|
70
|
+
} else {
|
|
71
|
+
const promise = fn.apply(this, arguments)
|
|
72
|
+
|
|
73
|
+
if (promise && typeof promise.catch === 'function') {
|
|
74
|
+
return promise.catch(err => publishError(err, requestResource))
|
|
72
75
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
throw e
|
|
76
|
+
|
|
77
|
+
return promise
|
|
76
78
|
}
|
|
77
|
-
})
|
|
79
|
+
} catch (e) {
|
|
80
|
+
throw publishError(e, requestResource)
|
|
81
|
+
}
|
|
78
82
|
})
|
|
79
83
|
|
|
80
84
|
return addHook.apply(this, arguments)
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
function onRequest (request, reply,
|
|
85
|
-
if (typeof
|
|
88
|
+
function onRequest (request, reply, done) {
|
|
89
|
+
if (typeof done !== 'function') return
|
|
86
90
|
|
|
87
91
|
const req = getReq(request)
|
|
88
92
|
const res = getRes(reply)
|
|
93
|
+
const requestResource = new AsyncResource('bound-anonymous-fn')
|
|
89
94
|
|
|
90
|
-
requestResources.set(req,
|
|
91
|
-
handleChannel.publish({ req, res })
|
|
95
|
+
requestResources.set(req, requestResource)
|
|
92
96
|
|
|
93
|
-
return
|
|
97
|
+
return requestResource.runInAsyncScope(() => {
|
|
98
|
+
handleChannel.publish({ req, res })
|
|
99
|
+
return done()
|
|
100
|
+
})
|
|
94
101
|
}
|
|
95
102
|
|
|
96
|
-
function preHandler (request, reply,
|
|
97
|
-
if (typeof
|
|
98
|
-
if (!reply || typeof reply.send !== 'function') return
|
|
103
|
+
function preHandler (request, reply, done) {
|
|
104
|
+
if (typeof done !== 'function') return
|
|
105
|
+
if (!reply || typeof reply.send !== 'function') return done()
|
|
99
106
|
|
|
100
107
|
const req = getReq(request)
|
|
108
|
+
const requestResource = requestResources.get(req)
|
|
101
109
|
|
|
102
|
-
reply.send =
|
|
110
|
+
reply.send = wrapSend(reply.send, requestResource)
|
|
103
111
|
|
|
104
|
-
|
|
112
|
+
done()
|
|
105
113
|
}
|
|
106
114
|
|
|
107
|
-
function
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
errorChannel.publish(payload)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return send.apply(this, arguments)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function wrapRoute (route) {
|
|
118
|
-
if (typeof route !== 'function') return route
|
|
115
|
+
function preValidation (request, reply, done) {
|
|
116
|
+
const req = getReq(request)
|
|
117
|
+
const parsingResource = parsingResources.get(req)
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
opts.handler = wrapHandler(opts.handler)
|
|
119
|
+
if (!parsingResource) return done()
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
}
|
|
121
|
+
parsingResource.runInAsyncScope(() => done())
|
|
125
122
|
}
|
|
126
123
|
|
|
127
|
-
function
|
|
128
|
-
if (typeof
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const lastIndex = arguments.length - 1
|
|
132
|
-
|
|
133
|
-
handler = arguments[lastIndex]
|
|
124
|
+
function preParsing (request, reply, payload, done) {
|
|
125
|
+
if (typeof done !== 'function') {
|
|
126
|
+
done = payload
|
|
127
|
+
}
|
|
134
128
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} else if (handler) {
|
|
138
|
-
arguments[lastIndex].handler = wrapHandler(handler.handler)
|
|
139
|
-
}
|
|
129
|
+
const req = getReq(request)
|
|
130
|
+
const parsingResource = new AsyncResource('bound-anonymous-fn')
|
|
140
131
|
|
|
141
|
-
|
|
142
|
-
|
|
132
|
+
parsingResources.set(req, parsingResource)
|
|
133
|
+
parsingResource.runInAsyncScope(() => done())
|
|
143
134
|
}
|
|
144
135
|
|
|
145
|
-
function
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
136
|
+
function wrapSend (send, resource) {
|
|
137
|
+
return function sendWithTrace (payload) {
|
|
138
|
+
if (payload instanceof Error) {
|
|
139
|
+
resource.runInAsyncScope(() => {
|
|
140
|
+
errorChannel.publish(payload)
|
|
141
|
+
})
|
|
142
|
+
}
|
|
152
143
|
|
|
153
|
-
return
|
|
154
|
-
return handler.apply(this, arguments)
|
|
155
|
-
})
|
|
144
|
+
return send.apply(this, arguments)
|
|
156
145
|
}
|
|
157
146
|
}
|
|
158
147
|
|
|
@@ -164,16 +153,15 @@ function getRes (reply) {
|
|
|
164
153
|
return reply && (reply.raw || reply.res || reply)
|
|
165
154
|
}
|
|
166
155
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
wrapped.default = wrapped
|
|
156
|
+
function publishError (error, resource) {
|
|
157
|
+
resource.runInAsyncScope(() => {
|
|
158
|
+
errorChannel.publish(error)
|
|
159
|
+
})
|
|
172
160
|
|
|
173
|
-
return
|
|
174
|
-
}
|
|
161
|
+
return error
|
|
162
|
+
}
|
|
175
163
|
|
|
176
|
-
addHook({ name: 'fastify', versions: ['3
|
|
164
|
+
addHook({ name: 'fastify', versions: ['>=3'] }, fastify => {
|
|
177
165
|
const wrapped = shimmer.wrap(fastify, wrapFastify(fastify, true))
|
|
178
166
|
|
|
179
167
|
wrapped.fastify = wrapped
|
|
@@ -182,6 +170,10 @@ addHook({ name: 'fastify', versions: ['3 - 3.25.1'] }, fastify => {
|
|
|
182
170
|
return wrapped
|
|
183
171
|
})
|
|
184
172
|
|
|
185
|
-
addHook({ name: 'fastify', versions: ['
|
|
173
|
+
addHook({ name: 'fastify', versions: ['2'] }, fastify => {
|
|
186
174
|
return shimmer.wrap(fastify, wrapFastify(fastify, true))
|
|
187
175
|
})
|
|
176
|
+
|
|
177
|
+
addHook({ name: 'fastify', versions: ['1'] }, fastify => {
|
|
178
|
+
return shimmer.wrap(fastify, wrapFastify(fastify, false))
|
|
179
|
+
})
|
|
@@ -89,7 +89,10 @@ function wrapMiddleware (fn, layer) {
|
|
|
89
89
|
const req = ctx.req
|
|
90
90
|
|
|
91
91
|
return middlewareResource.runInAsyncScope(() => {
|
|
92
|
-
|
|
92
|
+
const path = layer && layer.path
|
|
93
|
+
const route = path !== '(.*)' && path !== '([^/]*)' && path
|
|
94
|
+
|
|
95
|
+
enterChannel.publish({ req, name, route })
|
|
93
96
|
|
|
94
97
|
if (typeof next === 'function') {
|
|
95
98
|
arguments[1] = next
|
|
@@ -101,33 +104,33 @@ function wrapMiddleware (fn, layer) {
|
|
|
101
104
|
if (result && typeof result.then === 'function') {
|
|
102
105
|
return result.then(
|
|
103
106
|
result => {
|
|
104
|
-
fulfill(ctx
|
|
107
|
+
fulfill(ctx)
|
|
105
108
|
return result
|
|
106
109
|
},
|
|
107
110
|
err => {
|
|
108
|
-
fulfill(ctx,
|
|
111
|
+
fulfill(ctx, err)
|
|
109
112
|
throw err
|
|
110
113
|
}
|
|
111
114
|
)
|
|
112
115
|
} else {
|
|
113
|
-
fulfill(ctx
|
|
116
|
+
fulfill(ctx)
|
|
114
117
|
return result
|
|
115
118
|
}
|
|
116
119
|
} catch (e) {
|
|
117
|
-
fulfill(ctx,
|
|
120
|
+
fulfill(ctx, e)
|
|
118
121
|
throw e
|
|
119
122
|
}
|
|
120
123
|
})
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
126
|
|
|
124
|
-
function fulfill (ctx,
|
|
127
|
+
function fulfill (ctx, error) {
|
|
125
128
|
if (error) {
|
|
126
129
|
errorChannel.publish(error)
|
|
127
130
|
}
|
|
128
131
|
|
|
129
132
|
const req = ctx.req
|
|
130
|
-
const route = ctx.routePath
|
|
133
|
+
const route = ctx.routePath
|
|
131
134
|
|
|
132
135
|
// TODO: make sure that the parent class cannot override this in `enter`
|
|
133
136
|
if (route) {
|
|
@@ -22,6 +22,7 @@ const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
|
|
|
22
22
|
const HTTP_ROUTE = tags.HTTP_ROUTE
|
|
23
23
|
const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
|
|
24
24
|
const HTTP_RESPONSE_HEADERS = tags.HTTP_RESPONSE_HEADERS
|
|
25
|
+
const HTTP_USERAGENT = tags.HTTP_USERAGENT
|
|
25
26
|
const MANUAL_DROP = tags.MANUAL_DROP
|
|
26
27
|
|
|
27
28
|
const HTTP_STATUS_OK = 200
|
|
@@ -141,7 +142,8 @@ function addRequestTags (stream, headers) {
|
|
|
141
142
|
[HTTP_METHOD]: headers[HTTP2_HEADER_METHOD],
|
|
142
143
|
[HTTP_URL]: url.split('?')[0],
|
|
143
144
|
[SPAN_KIND]: SERVER,
|
|
144
|
-
[SPAN_TYPE]: WEB
|
|
145
|
+
[SPAN_TYPE]: WEB,
|
|
146
|
+
[HTTP_USERAGENT]: headers['user-agent']
|
|
145
147
|
})
|
|
146
148
|
}
|
|
147
149
|
|
|
@@ -12,25 +12,26 @@ class MySQLPlugin extends Plugin {
|
|
|
12
12
|
constructor (...args) {
|
|
13
13
|
super(...args)
|
|
14
14
|
|
|
15
|
-
this.addSub(`apm:${this.constructor.name}:query:start`, ({ sql, conf }) => {
|
|
15
|
+
this.addSub(`apm:${this.constructor.name}:query:start`, ({ sql, conf: dbConfig }) => {
|
|
16
|
+
const service = getServiceName(this.tracer, this.config, dbConfig)
|
|
16
17
|
const store = storage.getStore()
|
|
17
18
|
const childOf = store ? store.span : store
|
|
18
19
|
const span = this.tracer.startSpan('mysql.query', {
|
|
19
20
|
childOf,
|
|
20
21
|
tags: {
|
|
21
|
-
'service.name':
|
|
22
|
+
'service.name': service,
|
|
22
23
|
'span.type': 'sql',
|
|
23
24
|
'span.kind': 'client',
|
|
24
25
|
'db.type': 'mysql',
|
|
25
|
-
'db.user':
|
|
26
|
-
'out.host':
|
|
27
|
-
'out.port':
|
|
26
|
+
'db.user': dbConfig.user,
|
|
27
|
+
'out.host': dbConfig.host,
|
|
28
|
+
'out.port': dbConfig.port,
|
|
28
29
|
'resource.name': sql
|
|
29
30
|
}
|
|
30
31
|
})
|
|
31
32
|
|
|
32
|
-
if (
|
|
33
|
-
span.setTag('db.name',
|
|
33
|
+
if (dbConfig.database) {
|
|
34
|
+
span.setTag('db.name', dbConfig.database)
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
analyticsSampler.sample(span, this.config.measured)
|
|
@@ -51,4 +52,14 @@ class MySQLPlugin extends Plugin {
|
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
function getServiceName (tracer, config, dbConfig) {
|
|
56
|
+
if (typeof config.service === 'function') {
|
|
57
|
+
return config.service(dbConfig)
|
|
58
|
+
} else if (config.service) {
|
|
59
|
+
return config.service
|
|
60
|
+
} else {
|
|
61
|
+
return `${tracer._service}-mysql`
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
54
65
|
module.exports = MySQLPlugin
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = '2.
|
|
1
|
+
module.exports = '2.9.1'
|
|
@@ -47,15 +47,15 @@ function incomingHttpStartTranslator (data) {
|
|
|
47
47
|
'_dd.runtime_family': 'nodejs'
|
|
48
48
|
})
|
|
49
49
|
}
|
|
50
|
+
}
|
|
50
51
|
|
|
52
|
+
function incomingHttpEndTranslator (data) {
|
|
51
53
|
const store = Gateway.startContext()
|
|
52
54
|
|
|
53
55
|
store.set('req', data.req)
|
|
54
56
|
store.set('res', data.res)
|
|
55
|
-
}
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
const context = Gateway.getContext()
|
|
58
|
+
const context = store.get('context')
|
|
59
59
|
|
|
60
60
|
if (!context) return
|
|
61
61
|
|
|
@@ -23,6 +23,7 @@ const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
|
|
|
23
23
|
const HTTP_ROUTE = tags.HTTP_ROUTE
|
|
24
24
|
const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
|
|
25
25
|
const HTTP_RESPONSE_HEADERS = tags.HTTP_RESPONSE_HEADERS
|
|
26
|
+
const HTTP_USERAGENT = tags.HTTP_USERAGENT
|
|
26
27
|
const MANUAL_DROP = tags.MANUAL_DROP
|
|
27
28
|
|
|
28
29
|
const HTTP2_HEADER_AUTHORITY = ':authority'
|
|
@@ -412,7 +413,8 @@ function addRequestTags (context) {
|
|
|
412
413
|
[HTTP_URL]: url.split('?')[0],
|
|
413
414
|
[HTTP_METHOD]: req.method,
|
|
414
415
|
[SPAN_KIND]: SERVER,
|
|
415
|
-
[SPAN_TYPE]: WEB
|
|
416
|
+
[SPAN_TYPE]: WEB,
|
|
417
|
+
[HTTP_USERAGENT]: req.headers['user-agent']
|
|
416
418
|
})
|
|
417
419
|
|
|
418
420
|
addHeaders(context)
|
|
@@ -78,15 +78,13 @@ async function assertVersions () {
|
|
|
78
78
|
const externalNames = Object.keys(externals).filter(name => ~names.indexOf(name))
|
|
79
79
|
for (const name of externalNames) {
|
|
80
80
|
for (const inst of [].concat(externals[name])) {
|
|
81
|
-
|
|
82
|
-
await assertInstrumentation(inst, true)
|
|
83
|
-
}
|
|
81
|
+
await assertInstrumentation(inst, true)
|
|
84
82
|
}
|
|
85
83
|
}
|
|
86
84
|
}
|
|
87
85
|
|
|
88
86
|
async function assertInstrumentation (instrumentation, external) {
|
|
89
|
-
const versions = [].concat(instrumentation.versions)
|
|
87
|
+
const versions = [].concat(instrumentation.versions || [])
|
|
90
88
|
for (const version of versions) {
|
|
91
89
|
if (version) {
|
|
92
90
|
await assertModules(instrumentation.name, semver.coerce(version).version, external)
|