dd-trace 2.3.0 → 2.4.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 +26 -2
- package/index.d.ts +51 -0
- package/package.json +2 -2
- package/packages/datadog-instrumentations/index.js +10 -0
- package/packages/datadog-instrumentations/src/amqp10.js +70 -0
- package/packages/datadog-instrumentations/src/amqplib.js +58 -0
- package/packages/datadog-instrumentations/src/cassandra-driver.js +191 -0
- package/packages/datadog-instrumentations/src/cucumber.js +27 -12
- package/packages/datadog-instrumentations/src/helpers/hook.js +44 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +31 -58
- package/packages/datadog-instrumentations/src/http/client.js +170 -0
- package/packages/datadog-instrumentations/src/http/server.js +61 -0
- package/packages/datadog-instrumentations/src/http.js +4 -0
- package/packages/datadog-instrumentations/src/mocha.js +139 -0
- package/packages/datadog-instrumentations/src/mongodb-core.js +179 -0
- package/packages/datadog-instrumentations/src/net.js +117 -0
- package/packages/datadog-instrumentations/src/pg.js +75 -0
- package/packages/datadog-instrumentations/src/rhea.js +224 -0
- package/packages/datadog-instrumentations/src/tedious.js +66 -0
- package/packages/datadog-plugin-amqp10/src/index.js +79 -122
- package/packages/datadog-plugin-amqplib/src/index.js +77 -142
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -2
- package/packages/datadog-plugin-cassandra-driver/src/index.js +52 -224
- package/packages/datadog-plugin-cucumber/src/index.js +3 -1
- package/packages/datadog-plugin-http/src/client.js +111 -254
- package/packages/datadog-plugin-http/src/index.js +29 -3
- package/packages/datadog-plugin-http/src/server.js +49 -32
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +5 -3
- package/packages/datadog-plugin-mocha/src/index.js +96 -207
- package/packages/datadog-plugin-mongodb-core/src/index.js +119 -3
- package/packages/datadog-plugin-net/src/index.js +65 -121
- package/packages/datadog-plugin-next/src/index.js +10 -10
- package/packages/datadog-plugin-pg/src/index.js +32 -69
- package/packages/datadog-plugin-rhea/src/index.js +59 -225
- package/packages/datadog-plugin-tedious/src/index.js +38 -86
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/recommended.json +137 -116
- package/packages/dd-trace/src/config.js +6 -0
- package/packages/dd-trace/src/iitm.js +5 -1
- package/packages/dd-trace/src/loader.js +6 -4
- package/packages/dd-trace/src/noop/tracer.js +4 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +34 -1
- package/packages/dd-trace/src/opentracing/span.js +34 -0
- package/packages/dd-trace/src/plugin_manager.js +4 -0
- package/packages/dd-trace/src/plugins/plugin.js +3 -1
- package/packages/dd-trace/src/plugins/util/web.js +99 -93
- package/packages/dd-trace/src/proxy.js +4 -0
- package/packages/dd-trace/src/ritm.js +60 -25
- package/packages/dd-trace/src/tracer.js +16 -0
- package/packages/datadog-plugin-mongodb-core/src/legacy.js +0 -59
- package/packages/datadog-plugin-mongodb-core/src/unified.js +0 -138
- package/packages/datadog-plugin-mongodb-core/src/util.js +0 -143
|
@@ -1,40 +1,30 @@
|
|
|
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 tags = require('../../../ext/tags')
|
|
6
|
-
const
|
|
6
|
+
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
7
7
|
const formats = require('../../../ext/formats')
|
|
8
|
+
const HTTP_HEADERS = formats.HTTP_HEADERS
|
|
8
9
|
const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
|
|
9
|
-
const
|
|
10
|
-
const
|
|
10
|
+
const log = require('../../dd-trace/src/log')
|
|
11
|
+
const url = require('url')
|
|
11
12
|
|
|
12
|
-
const HTTP_HEADERS = formats.HTTP_HEADERS
|
|
13
13
|
const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
|
|
14
14
|
const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
|
|
15
15
|
const HTTP_RESPONSE_HEADERS = tags.HTTP_RESPONSE_HEADERS
|
|
16
|
-
const SPAN_KIND = tags.SPAN_KIND
|
|
17
|
-
const CLIENT = kinds.CLIENT
|
|
18
|
-
|
|
19
|
-
function patch (http, methodName, tracer, config) {
|
|
20
|
-
config = normalizeConfig(tracer, config)
|
|
21
|
-
this.wrap(http, methodName, fn => makeRequestTrace(fn))
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (store && store.noop) return request.apply(this, arguments)
|
|
28
|
-
|
|
29
|
-
let args
|
|
17
|
+
class HttpClientPlugin extends Plugin {
|
|
18
|
+
static get name () {
|
|
19
|
+
return 'http'
|
|
20
|
+
}
|
|
30
21
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} catch (e) {
|
|
34
|
-
log.error(e)
|
|
35
|
-
return request.apply(this, arguments)
|
|
36
|
-
}
|
|
22
|
+
constructor (...args) {
|
|
23
|
+
super(...args)
|
|
37
24
|
|
|
25
|
+
this.addSub('apm:http:client:request:start', ({ args, http }) => {
|
|
26
|
+
const store = storage.getStore()
|
|
27
|
+
this.config = normalizeClientConfig(this.config)
|
|
38
28
|
const options = args.options
|
|
39
29
|
const agent = options.agent || options._defaultAgent || http.globalAgent
|
|
40
30
|
const protocol = options.protocol || agent.protocol || 'http:'
|
|
@@ -43,17 +33,13 @@ function patch (http, methodName, tracer, config) {
|
|
|
43
33
|
const path = options.path ? options.path.split(/[?#]/)[0] : '/'
|
|
44
34
|
const uri = `${protocol}//${host}${path}`
|
|
45
35
|
|
|
46
|
-
let callback = args.callback
|
|
47
|
-
|
|
48
36
|
const method = (options.method || 'GET').toUpperCase()
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
const childOf = scope.active()
|
|
52
|
-
const span = tracer.startSpan('http.request', {
|
|
37
|
+
const childOf = store ? store.span : store
|
|
38
|
+
const span = this.tracer.startSpan('http.request', {
|
|
53
39
|
childOf,
|
|
54
40
|
tags: {
|
|
55
|
-
|
|
56
|
-
'service.name': getServiceName(tracer, config, options),
|
|
41
|
+
'span.kind': 'client',
|
|
42
|
+
'service.name': getServiceName(this.tracer, this.config, options),
|
|
57
43
|
'resource.name': method,
|
|
58
44
|
'span.type': 'http',
|
|
59
45
|
'http.method': method,
|
|
@@ -61,184 +47,113 @@ function patch (http, methodName, tracer, config) {
|
|
|
61
47
|
}
|
|
62
48
|
})
|
|
63
49
|
|
|
64
|
-
if (!(hasAmazonSignature(options) || !config.propagationFilter(uri))) {
|
|
65
|
-
tracer.inject(span, HTTP_HEADERS, options.headers)
|
|
50
|
+
if (!(hasAmazonSignature(options) || !this.config.propagationFilter(uri))) {
|
|
51
|
+
this.tracer.inject(span, HTTP_HEADERS, options.headers)
|
|
66
52
|
}
|
|
67
53
|
|
|
68
|
-
analyticsSampler.sample(span, config.measured)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const req = scope.bind(request, span).call(this, options, callback)
|
|
73
|
-
const emit = req.emit
|
|
74
|
-
|
|
75
|
-
req.emit = function (eventName, arg) {
|
|
76
|
-
switch (eventName) {
|
|
77
|
-
case 'response': {
|
|
78
|
-
const res = arg
|
|
54
|
+
analyticsSampler.sample(span, this.config.measured)
|
|
55
|
+
this.enter(span, store)
|
|
56
|
+
})
|
|
79
57
|
|
|
80
|
-
|
|
58
|
+
this.addSub('apm:http:client:request:end', this.exit.bind(this))
|
|
81
59
|
|
|
82
|
-
|
|
60
|
+
this.addSub('apm:http:client:request:async-end', ({ req, res }) => {
|
|
61
|
+
const span = storage.getStore().span
|
|
62
|
+
if (res) {
|
|
63
|
+
span.setTag(HTTP_STATUS_CODE, res.statusCode)
|
|
83
64
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
case 'error':
|
|
87
|
-
addError(span, arg)
|
|
88
|
-
case 'abort': // eslint-disable-line no-fallthrough
|
|
89
|
-
case 'timeout': // eslint-disable-line no-fallthrough
|
|
90
|
-
finish(req, null, span, config)
|
|
65
|
+
if (!this.config.validateStatus(res.statusCode)) {
|
|
66
|
+
span.setTag('error', 1)
|
|
91
67
|
}
|
|
92
68
|
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
scope.bind(req)
|
|
97
|
-
|
|
98
|
-
return req
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function finish (req, res, span, config) {
|
|
103
|
-
if (res) {
|
|
104
|
-
span.setTag(HTTP_STATUS_CODE, res.statusCode)
|
|
105
|
-
|
|
106
|
-
if (!config.validateStatus(res.statusCode)) {
|
|
69
|
+
addResponseHeaders(res, span, this.config)
|
|
70
|
+
} else {
|
|
107
71
|
span.setTag('error', 1)
|
|
108
72
|
}
|
|
109
73
|
|
|
110
|
-
|
|
111
|
-
} else {
|
|
112
|
-
span.setTag('error', 1)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
addRequestHeaders(req, span, config)
|
|
116
|
-
|
|
117
|
-
config.hooks.request(span, req, res)
|
|
74
|
+
addRequestHeaders(req, span, this.config)
|
|
118
75
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
function addError (span, error) {
|
|
123
|
-
span.addTags({
|
|
124
|
-
'error.type': error.name,
|
|
125
|
-
'error.msg': error.message,
|
|
126
|
-
'error.stack': error.stack
|
|
76
|
+
this.config.hooks.request(span, req, res)
|
|
77
|
+
span.finish()
|
|
127
78
|
})
|
|
128
79
|
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function addRequestHeaders (req, span, config) {
|
|
133
|
-
config.headers.forEach(key => {
|
|
134
|
-
const value = req.getHeader(key)
|
|
135
|
-
|
|
136
|
-
if (value) {
|
|
137
|
-
span.setTag(`${HTTP_REQUEST_HEADERS}.${key}`, value)
|
|
138
|
-
}
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function addResponseHeaders (res, span, config) {
|
|
143
|
-
config.headers.forEach(key => {
|
|
144
|
-
const value = res.headers[key]
|
|
145
|
-
|
|
146
|
-
if (value) {
|
|
147
|
-
span.setTag(`${HTTP_RESPONSE_HEADERS}.${key}`, value)
|
|
148
|
-
}
|
|
149
|
-
})
|
|
80
|
+
this.addSub('apm:http:client:request:error', errorHandler)
|
|
150
81
|
}
|
|
82
|
+
}
|
|
151
83
|
|
|
152
|
-
|
|
153
|
-
|
|
84
|
+
function errorHandler (err) {
|
|
85
|
+
const span = storage.getStore().span
|
|
86
|
+
span.addTags({
|
|
87
|
+
'error.type': err.name,
|
|
88
|
+
'error.msg': err.message,
|
|
89
|
+
'error.stack': err.stack
|
|
90
|
+
})
|
|
91
|
+
}
|
|
154
92
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const uri = url.format(options)
|
|
93
|
+
function addResponseHeaders (res, span, config) {
|
|
94
|
+
config.headers.forEach(key => {
|
|
95
|
+
const value = res.headers[key]
|
|
159
96
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
function normalizeCallback (inputOptions, callback, inputURL) {
|
|
164
|
-
if (typeof inputOptions === 'function') {
|
|
165
|
-
return [inputOptions, inputURL || {}]
|
|
166
|
-
} else {
|
|
167
|
-
return [callback, inputOptions]
|
|
97
|
+
if (value) {
|
|
98
|
+
span.setTag(`${HTTP_RESPONSE_HEADERS}.${key}`, value)
|
|
168
99
|
}
|
|
169
|
-
}
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function addRequestHeaders (req, span, config) {
|
|
104
|
+
config.headers.forEach(key => {
|
|
105
|
+
const value = req.getHeader(key)
|
|
170
106
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return Object.assign(inputURL || {}, inputOptions)
|
|
174
|
-
} else {
|
|
175
|
-
return inputURL
|
|
107
|
+
if (value) {
|
|
108
|
+
span.setTag(`${HTTP_REQUEST_HEADERS}.${key}`, value)
|
|
176
109
|
}
|
|
177
|
-
}
|
|
110
|
+
})
|
|
111
|
+
}
|
|
178
112
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
113
|
+
function normalizeClientConfig (config) {
|
|
114
|
+
const validateStatus = getStatusValidator(config)
|
|
115
|
+
const propagationFilter = getFilter({ blocklist: config.propagationBlocklist })
|
|
116
|
+
const headers = getHeaders(config)
|
|
117
|
+
const hooks = getHooks(config)
|
|
182
118
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
: url.hostname ||
|
|
191
|
-
url.host ||
|
|
192
|
-
'localhost',
|
|
193
|
-
hash: url.hash,
|
|
194
|
-
search: url.search,
|
|
195
|
-
pathname: url.pathname,
|
|
196
|
-
path: `${url.pathname || ''}${url.search || ''}`,
|
|
197
|
-
href: url.href
|
|
198
|
-
}
|
|
199
|
-
if (url.port !== '') {
|
|
200
|
-
options.port = Number(url.port)
|
|
201
|
-
}
|
|
202
|
-
if (url.username || url.password) {
|
|
203
|
-
options.auth = `${url.username}:${url.password}`
|
|
204
|
-
}
|
|
205
|
-
return options
|
|
206
|
-
}
|
|
119
|
+
return Object.assign({}, config, {
|
|
120
|
+
validateStatus,
|
|
121
|
+
propagationFilter,
|
|
122
|
+
headers,
|
|
123
|
+
hooks
|
|
124
|
+
})
|
|
125
|
+
}
|
|
207
126
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return url.parse(inputURL)
|
|
214
|
-
}
|
|
215
|
-
} else if (inputURL instanceof url.URL) {
|
|
216
|
-
return urlToOptions(inputURL)
|
|
217
|
-
} else {
|
|
218
|
-
return inputURL
|
|
219
|
-
}
|
|
127
|
+
function getStatusValidator (config) {
|
|
128
|
+
if (typeof config.validateStatus === 'function') {
|
|
129
|
+
return config.validateStatus
|
|
130
|
+
} else if (config.hasOwnProperty('validateStatus')) {
|
|
131
|
+
log.error('Expected `validateStatus` to be a function.')
|
|
220
132
|
}
|
|
133
|
+
return code => code < 400 || code >= 500
|
|
221
134
|
}
|
|
222
135
|
|
|
223
|
-
function
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
136
|
+
function getFilter (config) {
|
|
137
|
+
config = Object.assign({}, config, {
|
|
138
|
+
blocklist: config.blocklist || []
|
|
139
|
+
})
|
|
227
140
|
|
|
228
|
-
|
|
229
|
-
|
|
141
|
+
return urlFilter.getFilter(config)
|
|
142
|
+
}
|
|
230
143
|
|
|
231
|
-
|
|
144
|
+
function getHeaders (config) {
|
|
145
|
+
if (!Array.isArray(config.headers)) return []
|
|
146
|
+
|
|
147
|
+
return config.headers
|
|
148
|
+
.filter(key => typeof key === 'string')
|
|
149
|
+
.map(key => key.toLowerCase())
|
|
232
150
|
}
|
|
233
151
|
|
|
234
|
-
function
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
} else if (config.service) {
|
|
238
|
-
return config.service
|
|
239
|
-
}
|
|
152
|
+
function getHooks (config) {
|
|
153
|
+
const noop = () => {}
|
|
154
|
+
const request = (config.hooks && config.hooks.request) || noop
|
|
240
155
|
|
|
241
|
-
return
|
|
156
|
+
return { request }
|
|
242
157
|
}
|
|
243
158
|
|
|
244
159
|
function hasAmazonSignature (options) {
|
|
@@ -264,87 +179,29 @@ function hasAmazonSignature (options) {
|
|
|
264
179
|
return options.path && options.path.toLowerCase().indexOf('x-amz-signature=') !== -1
|
|
265
180
|
}
|
|
266
181
|
|
|
267
|
-
function
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
this.unwrap(http, 'request')
|
|
273
|
-
this.unwrap(http, 'get')
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function getStatusValidator (config) {
|
|
277
|
-
if (typeof config.validateStatus === 'function') {
|
|
278
|
-
return config.validateStatus
|
|
279
|
-
} else if (config.hasOwnProperty('validateStatus')) {
|
|
280
|
-
log.error('Expected `validateStatus` to be a function.')
|
|
182
|
+
function getServiceName (tracer, config, options) {
|
|
183
|
+
if (config.splitByDomain) {
|
|
184
|
+
return getHost(options)
|
|
185
|
+
} else if (config.service) {
|
|
186
|
+
return config.service
|
|
281
187
|
}
|
|
282
|
-
return code => code < 400 || code >= 500
|
|
283
|
-
}
|
|
284
188
|
|
|
285
|
-
|
|
286
|
-
config = Object.assign({}, config, {
|
|
287
|
-
blocklist: config.blocklist || []
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
return urlFilter.getFilter(config)
|
|
189
|
+
return `${tracer._service}-http-client`
|
|
291
190
|
}
|
|
292
191
|
|
|
293
|
-
function
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const propagationFilter = getFilter({ blocklist: config.propagationBlocklist })
|
|
298
|
-
const headers = getHeaders(config)
|
|
299
|
-
const hooks = getHooks(config)
|
|
300
|
-
|
|
301
|
-
return Object.assign({}, config, {
|
|
302
|
-
validateStatus,
|
|
303
|
-
propagationFilter,
|
|
304
|
-
headers,
|
|
305
|
-
hooks
|
|
306
|
-
})
|
|
307
|
-
}
|
|
192
|
+
function getHost (options) {
|
|
193
|
+
if (typeof options === 'string') {
|
|
194
|
+
return url.parse(options).host
|
|
195
|
+
}
|
|
308
196
|
|
|
309
|
-
|
|
310
|
-
|
|
197
|
+
const hostname = options.hostname || options.host || 'localhost'
|
|
198
|
+
const port = options.port
|
|
311
199
|
|
|
312
|
-
return
|
|
313
|
-
.filter(key => typeof key === 'string')
|
|
314
|
-
.map(key => key.toLowerCase())
|
|
200
|
+
return [hostname, port].filter(val => val).join(':')
|
|
315
201
|
}
|
|
316
202
|
|
|
317
|
-
function
|
|
318
|
-
|
|
319
|
-
const request = (config.hooks && config.hooks.request) || noop
|
|
320
|
-
|
|
321
|
-
return { request }
|
|
203
|
+
function startsWith (searchString) {
|
|
204
|
+
return value => String(value).startsWith(searchString)
|
|
322
205
|
}
|
|
323
206
|
|
|
324
|
-
module.exports =
|
|
325
|
-
{
|
|
326
|
-
name: 'http',
|
|
327
|
-
patch: function (http, tracer, config) {
|
|
328
|
-
if (config.client === false) return
|
|
329
|
-
|
|
330
|
-
patch.call(this, http, 'request', tracer, config)
|
|
331
|
-
/**
|
|
332
|
-
* References internal to modules, such as `http(s).get` calling
|
|
333
|
-
* `http(s).request`, do not use externally patched versions, which is
|
|
334
|
-
* why we need to also patch `get` here separately.
|
|
335
|
-
*/
|
|
336
|
-
patch.call(this, http, 'get', tracer, config)
|
|
337
|
-
},
|
|
338
|
-
unpatch
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
name: 'https',
|
|
342
|
-
patch: function (http, tracer, config) {
|
|
343
|
-
if (config.client === false) return
|
|
344
|
-
|
|
345
|
-
patch.call(this, http, 'request', tracer, config)
|
|
346
|
-
patch.call(this, http, 'get', tracer, config)
|
|
347
|
-
},
|
|
348
|
-
unpatch
|
|
349
|
-
}
|
|
350
|
-
]
|
|
207
|
+
module.exports = HttpClientPlugin
|
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
3
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
4
|
+
const HttpServerPlugin = require('./server')
|
|
5
|
+
const HttpClientPlugin = require('./client')
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
class HttpPlugin extends Plugin {
|
|
8
|
+
static get name () {
|
|
9
|
+
return 'http'
|
|
10
|
+
}
|
|
11
|
+
constructor (...args) {
|
|
12
|
+
super(...args)
|
|
13
|
+
this.server = new HttpServerPlugin(...args)
|
|
14
|
+
this.client = new HttpClientPlugin(...args)
|
|
15
|
+
}
|
|
16
|
+
configure (config) {
|
|
17
|
+
const clientConfig = config.client === false ? false : {
|
|
18
|
+
...config,
|
|
19
|
+
...config.client
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const serverConfig = config.server === false ? false : {
|
|
23
|
+
...config,
|
|
24
|
+
...config.server
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
this.server.configure(serverConfig)
|
|
28
|
+
this.client.configure(clientConfig)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = HttpPlugin
|
|
@@ -1,47 +1,64 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
4
|
+
const { storage } = require('../../datadog-core')
|
|
3
5
|
const web = require('../../dd-trace/src/plugins/util/web')
|
|
4
|
-
const Scope = require('../../dd-trace/src/scope')
|
|
5
6
|
const { incomingHttpRequestStart } = require('../../dd-trace/src/appsec/gateway/channels')
|
|
7
|
+
const tags = require('../../../ext/tags')
|
|
8
|
+
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
9
|
+
const SERVICE_NAME = tags.SERVICE_NAME
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
class HttpServerPlugin extends Plugin {
|
|
12
|
+
static get name () {
|
|
13
|
+
return 'http'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
constructor (...args) {
|
|
17
|
+
super(...args)
|
|
18
|
+
|
|
19
|
+
this.addSub('apm:http:server:request:start', ({ req, res }) => {
|
|
20
|
+
const store = storage.getStore()
|
|
21
|
+
this.config = web.normalizeConfig(this.config)
|
|
9
22
|
|
|
10
|
-
|
|
11
|
-
return function emitWithTrace (eventName, req, res) {
|
|
12
|
-
if (eventName === 'request') {
|
|
13
|
-
return web.instrument(tracer, config, req, res, 'http.request', () => {
|
|
14
|
-
if (incomingHttpRequestStart.hasSubscribers) {
|
|
15
|
-
incomingHttpRequestStart.publish({ req, res })
|
|
16
|
-
}
|
|
23
|
+
const span = web.startSpan(this.tracer, this.config, req, res, 'http.request')
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
if (this.config.service) {
|
|
26
|
+
span.setTag(SERVICE_NAME, this.config.service)
|
|
20
27
|
}
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
}
|
|
29
|
+
analyticsSampler.sample(span, this.config.measured, true)
|
|
30
|
+
this.enter(span, store)
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
name,
|
|
30
|
-
patch (http, tracer, config) {
|
|
31
|
-
if (config.server === false) return
|
|
32
|
+
const context = web.getContext(req)
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
if (!context.instrumented) {
|
|
35
|
+
context.res.writeHead = web.wrapWriteHead(context)
|
|
36
|
+
context.instrumented = true
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
|
|
39
|
+
if (incomingHttpRequestStart.hasSubscribers) {
|
|
40
|
+
incomingHttpRequestStart.publish({ req, res })
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
this.addSub('apm:http:server:request:end', () => {
|
|
45
|
+
this.exit()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
this.addSub('apm:http:server:request:error', (error) => {
|
|
49
|
+
const span = storage.getStore().span
|
|
50
|
+
span.addTags({
|
|
51
|
+
'error.type': error.name,
|
|
52
|
+
'error.msg': error.message,
|
|
53
|
+
'error.stack': error.stack
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
this.addSub('apm:http:server:request:async-end', ({ req }) => {
|
|
58
|
+
const context = web.getContext(req)
|
|
59
|
+
web.wrapRes(context, context.req, context.res, context.res.end)()
|
|
60
|
+
})
|
|
41
61
|
}
|
|
42
62
|
}
|
|
43
63
|
|
|
44
|
-
module.exports =
|
|
45
|
-
plugin('http'),
|
|
46
|
-
plugin('https')
|
|
47
|
-
]
|
|
64
|
+
module.exports = HttpServerPlugin
|
|
@@ -97,9 +97,11 @@ function createWrapOnException (tracer, globalInput) {
|
|
|
97
97
|
if (isActiveSpanFailing && !testStatus) {
|
|
98
98
|
activeTestSpan.setTag(TEST_STATUS, 'fail')
|
|
99
99
|
// If we don't do this, jest will show this file on its error message
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
if (err.stack) {
|
|
101
|
+
const stackFrames = err.stack.split('\n')
|
|
102
|
+
const filteredStackFrames = stackFrames.filter(frame => !frame.includes(__dirname)).join('\n')
|
|
103
|
+
err.stack = filteredStackFrames
|
|
104
|
+
}
|
|
103
105
|
activeTestSpan.setTag('error', err)
|
|
104
106
|
// need to manually finish, as it will not be caught in `itWithTrace`
|
|
105
107
|
activeTestSpan.finish()
|