dd-trace 2.7.0 → 2.9.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/LICENSE-3rdparty.csv +1 -2
- 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 +3 -5
- package/packages/datadog-core/src/storage/async_resource.js +1 -1
- package/packages/datadog-instrumentations/index.js +3 -0
- package/packages/datadog-instrumentations/src/amqp10.js +33 -32
- package/packages/datadog-instrumentations/src/amqplib.js +16 -11
- package/packages/datadog-instrumentations/src/aws-sdk.js +105 -0
- package/packages/datadog-instrumentations/src/cassandra-driver.js +53 -51
- package/packages/datadog-instrumentations/src/connect.js +5 -5
- package/packages/datadog-instrumentations/src/couchbase.js +41 -39
- package/packages/datadog-instrumentations/src/cucumber.js +38 -38
- package/packages/datadog-instrumentations/src/dns.js +20 -19
- package/packages/datadog-instrumentations/src/elasticsearch.js +30 -32
- package/packages/datadog-instrumentations/src/fastify.js +75 -87
- package/packages/datadog-instrumentations/src/hapi.js +210 -0
- package/packages/datadog-instrumentations/src/http/client.js +44 -44
- package/packages/datadog-instrumentations/src/http/server.js +15 -13
- package/packages/datadog-instrumentations/src/ioredis.js +16 -17
- package/packages/datadog-instrumentations/src/jest.js +5 -5
- package/packages/datadog-instrumentations/src/koa.js +13 -10
- package/packages/datadog-instrumentations/src/memcached.js +14 -12
- package/packages/datadog-instrumentations/src/mocha.js +37 -39
- package/packages/datadog-instrumentations/src/moleculer/client.js +46 -0
- package/packages/datadog-instrumentations/src/moleculer/server.js +59 -0
- package/packages/datadog-instrumentations/src/moleculer.js +4 -0
- package/packages/datadog-instrumentations/src/mongodb-core.js +29 -33
- package/packages/datadog-instrumentations/src/mysql.js +30 -29
- package/packages/datadog-instrumentations/src/mysql2.js +8 -9
- package/packages/datadog-instrumentations/src/net.js +23 -24
- package/packages/datadog-instrumentations/src/pg.js +30 -30
- package/packages/datadog-instrumentations/src/redis.js +49 -47
- package/packages/datadog-instrumentations/src/rhea.js +51 -49
- package/packages/datadog-instrumentations/src/router.js +5 -5
- package/packages/datadog-instrumentations/src/sharedb.js +20 -20
- package/packages/datadog-instrumentations/src/tedious.js +19 -19
- package/packages/datadog-plugin-amqp10/src/index.js +2 -7
- package/packages/datadog-plugin-amqplib/src/index.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +146 -0
- package/packages/datadog-plugin-aws-sdk/src/index.js +16 -106
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +4 -2
- package/packages/datadog-plugin-aws-sdk/src/services/default.js +7 -0
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +3 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +5 -4
- package/packages/datadog-plugin-aws-sdk/src/services/index.js +12 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -3
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +4 -3
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +3 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +4 -3
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +45 -6
- package/packages/datadog-plugin-cassandra-driver/src/index.js +1 -5
- package/packages/datadog-plugin-couchbase/src/index.js +3 -4
- package/packages/datadog-plugin-cucumber/src/index.js +1 -9
- package/packages/datadog-plugin-dns/src/index.js +3 -4
- package/packages/datadog-plugin-elasticsearch/src/index.js +1 -5
- package/packages/datadog-plugin-hapi/src/index.js +34 -3
- package/packages/datadog-plugin-http/src/client.js +1 -3
- package/packages/datadog-plugin-http/src/server.js +0 -4
- package/packages/datadog-plugin-http2/src/server.js +3 -1
- package/packages/datadog-plugin-jest/src/index.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/index.js +0 -4
- package/packages/datadog-plugin-memcached/src/index.js +1 -5
- package/packages/datadog-plugin-mocha/src/index.js +3 -7
- package/packages/datadog-plugin-moleculer/src/client.js +34 -44
- package/packages/datadog-plugin-moleculer/src/index.js +32 -3
- package/packages/datadog-plugin-moleculer/src/server.js +28 -50
- package/packages/datadog-plugin-mongodb-core/src/index.js +1 -5
- package/packages/datadog-plugin-mysql/src/index.js +19 -12
- package/packages/datadog-plugin-net/src/index.js +3 -7
- package/packages/datadog-plugin-pg/src/index.js +1 -5
- package/packages/datadog-plugin-redis/src/index.js +1 -5
- package/packages/datadog-plugin-rhea/src/index.js +1 -5
- package/packages/datadog-plugin-router/src/index.js +1 -1
- package/packages/datadog-plugin-sharedb/src/index.js +1 -5
- package/packages/datadog-plugin-tedious/src/index.js +1 -5
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +2 -1
- package/packages/dd-trace/src/appsec/index.js +3 -3
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +3 -1
- package/packages/dd-trace/src/plugins/plugin.js +0 -8
- package/packages/dd-trace/src/plugins/util/test.js +5 -1
- package/packages/dd-trace/src/plugins/util/web.js +3 -1
- package/scripts/install_plugin_modules.js +25 -15
- package/packages/datadog-plugin-aws-sdk/src/helpers.js +0 -103
- package/packages/datadog-plugin-hapi/src/route.js +0 -75
- package/packages/datadog-plugin-hapi/src/server.js +0 -204
|
@@ -5,7 +5,7 @@ const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
|
5
5
|
|
|
6
6
|
const enterChannel = channel('apm:connect:middleware:enter')
|
|
7
7
|
const errorChannel = channel('apm:connect:middleware:error')
|
|
8
|
-
const
|
|
8
|
+
const nextChannel = channel('apm:connect:middleware:next')
|
|
9
9
|
const handleChannel = channel('apm:connect:request:handle')
|
|
10
10
|
|
|
11
11
|
function wrapConnect (connect) {
|
|
@@ -64,10 +64,10 @@ function wrapLayerHandle (layer) {
|
|
|
64
64
|
const lastIndex = arguments.length - 1
|
|
65
65
|
const name = original._name || original.name
|
|
66
66
|
const req = arguments[arguments.length > 3 ? 1 : 0]
|
|
67
|
-
const next =
|
|
67
|
+
const next = arguments[lastIndex]
|
|
68
68
|
|
|
69
69
|
if (typeof next === 'function') {
|
|
70
|
-
arguments[lastIndex] = wrapNext(req,
|
|
70
|
+
arguments[lastIndex] = wrapNext(req, next)
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
return middlewareResource.runInAsyncScope(() => {
|
|
@@ -79,7 +79,7 @@ function wrapLayerHandle (layer) {
|
|
|
79
79
|
return original.apply(this, arguments)
|
|
80
80
|
} catch (e) {
|
|
81
81
|
errorChannel.publish(e)
|
|
82
|
-
|
|
82
|
+
nextChannel.publish({ req })
|
|
83
83
|
|
|
84
84
|
throw e
|
|
85
85
|
}
|
|
@@ -93,7 +93,7 @@ function wrapNext (req, next) {
|
|
|
93
93
|
errorChannel.publish(error)
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
nextChannel.publish({ req })
|
|
97
97
|
|
|
98
98
|
next.apply(null, arguments)
|
|
99
99
|
}
|
|
@@ -9,8 +9,7 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
9
9
|
|
|
10
10
|
addHook({ name: 'couchbase', file: 'lib/bucket.js', versions: ['^2.6.5'] }, Bucket => {
|
|
11
11
|
const startCh = channel('apm:couchbase:query:start')
|
|
12
|
-
const
|
|
13
|
-
const endCh = channel('apm:couchbase:query:end')
|
|
12
|
+
const finishCh = channel('apm:couchbase:query:finish')
|
|
14
13
|
const errorCh = channel('apm:couchbase:query:error')
|
|
15
14
|
|
|
16
15
|
Bucket.prototype._maybeInvoke = wrapMaybeInvoke(Bucket.prototype._maybeInvoke)
|
|
@@ -25,27 +24,28 @@ addHook({ name: 'couchbase', file: 'lib/bucket.js', versions: ['^2.6.5'] }, Buck
|
|
|
25
24
|
|
|
26
25
|
const n1qlQuery = q && q.statement
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
28
|
+
return asyncResource.runInAsyncScope(() => {
|
|
29
|
+
startCh.publish({ resource: n1qlQuery, bucket: this })
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
emitter.once('rows', asyncResource.bind(() => {
|
|
32
|
+
finishCh.publish(undefined)
|
|
33
|
+
}))
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
emitter.once('error', asyncResource.bind((error) => {
|
|
36
|
+
errorCh.publish(error)
|
|
37
|
+
finishCh.publish(undefined)
|
|
38
|
+
}))
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
try {
|
|
41
|
+
return _n1qlReq.apply(this, arguments)
|
|
42
|
+
} catch (err) {
|
|
43
|
+
err.stack // trigger getting the stack at the original throwing point
|
|
44
|
+
errorCh.publish(err)
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
46
|
+
throw err
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
49
|
})
|
|
50
50
|
|
|
51
51
|
Bucket.prototype.upsert = wrap('apm:couchbase:upsert', Bucket.prototype.upsert)
|
|
@@ -103,8 +103,7 @@ function wrapQuery (query) {
|
|
|
103
103
|
|
|
104
104
|
function wrap (prefix, fn) {
|
|
105
105
|
const startCh = channel(prefix + ':start')
|
|
106
|
-
const
|
|
107
|
-
const asyncEndCh = channel(prefix + ':async-end')
|
|
106
|
+
const finishCh = channel(prefix + ':finish')
|
|
108
107
|
const errorCh = channel(prefix + ':error')
|
|
109
108
|
|
|
110
109
|
const wrapped = function (key, value, options, callback) {
|
|
@@ -116,28 +115,31 @@ function wrap (prefix, fn) {
|
|
|
116
115
|
|
|
117
116
|
if (callbackIndex < 0) return fn.apply(this, arguments)
|
|
118
117
|
|
|
119
|
-
const
|
|
118
|
+
const callbackResource = new AsyncResource('bound-anonymous-fn')
|
|
119
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
return asyncResource.runInAsyncScope(() => {
|
|
122
|
+
const cb = callbackResource.bind(arguments[callbackIndex])
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
if (error) {
|
|
125
|
-
errorCh.publish(error)
|
|
126
|
-
}
|
|
127
|
-
asyncEndCh.publish(result)
|
|
128
|
-
return cb.apply(this, arguments)
|
|
129
|
-
}
|
|
124
|
+
startCh.publish({ bucket: this })
|
|
130
125
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
126
|
+
arguments[callbackIndex] = asyncResource.bind(function (error, result) {
|
|
127
|
+
if (error) {
|
|
128
|
+
errorCh.publish(error)
|
|
129
|
+
}
|
|
130
|
+
finishCh.publish(result)
|
|
131
|
+
return cb.apply(this, arguments)
|
|
132
|
+
})
|
|
136
133
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
try {
|
|
135
|
+
return fn.apply(this, arguments)
|
|
136
|
+
} catch (error) {
|
|
137
|
+
error.stack // trigger getting the stack at the original throwing point
|
|
138
|
+
errorCh.publish(error)
|
|
139
|
+
|
|
140
|
+
throw error
|
|
141
|
+
}
|
|
142
|
+
})
|
|
141
143
|
}
|
|
142
144
|
return shimmer.wrap(fn, wrapped)
|
|
143
145
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { addHook, channel } = require('./helpers/instrument')
|
|
3
|
+
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
5
|
|
|
6
6
|
const runStartCh = channel('ci:cucumber:run:start')
|
|
7
|
-
const
|
|
8
|
-
const runAsyncEndCh = channel('ci:cucumber:run:async-end')
|
|
7
|
+
const runFinishCh = channel('ci:cucumber:run:finish')
|
|
9
8
|
const runStepStartCh = channel('ci:cucumber:run-step:start')
|
|
10
|
-
const runStepEndCh = channel('ci:cucumber:run-step:end')
|
|
11
9
|
const errorCh = channel('ci:cucumber:error')
|
|
12
10
|
|
|
13
11
|
// TODO: remove in a later major version
|
|
@@ -49,23 +47,24 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
49
47
|
return run.apply(this, arguments)
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
50
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
51
|
+
return asyncResource.runInAsyncScope(() => {
|
|
52
|
+
runStartCh.publish({ pickleName: this.pickle.name, pickleUri: this.pickle.uri })
|
|
53
|
+
try {
|
|
54
|
+
const promise = run.apply(this, arguments)
|
|
55
|
+
promise.finally(() => {
|
|
56
|
+
const result = this.getWorstStepResult()
|
|
57
|
+
const { status, skipReason, errorMessage } = isLatestVersion
|
|
58
|
+
? getStatusFromResultLatest(result) : getStatusFromResult(result)
|
|
59
|
+
|
|
60
|
+
runFinishCh.publish({ status, skipReason, errorMessage })
|
|
61
|
+
})
|
|
62
|
+
return promise
|
|
63
|
+
} catch (err) {
|
|
64
|
+
errorCh.publish(err)
|
|
65
|
+
throw err
|
|
66
|
+
}
|
|
67
|
+
})
|
|
69
68
|
})
|
|
70
69
|
shimmer.wrap(pl.prototype, 'runStep', runStep => function () {
|
|
71
70
|
if (!runStepStartCh.hasSubscribers) {
|
|
@@ -80,23 +79,24 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
80
79
|
resource = testStep.isHook ? 'hook' : testStep.pickleStep.text
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
82
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
83
|
+
return asyncResource.runInAsyncScope(() => {
|
|
84
|
+
runStepStartCh.publish({ resource })
|
|
85
|
+
try {
|
|
86
|
+
const promise = runStep.apply(this, arguments)
|
|
87
|
+
|
|
88
|
+
promise.then((result) => {
|
|
89
|
+
const { status, skipReason, errorMessage } = isLatestVersion
|
|
90
|
+
? getStatusFromResultLatest(result) : getStatusFromResult(result)
|
|
91
|
+
|
|
92
|
+
runFinishCh.publish({ isStep: true, status, skipReason, errorMessage })
|
|
93
|
+
})
|
|
94
|
+
return promise
|
|
95
|
+
} catch (err) {
|
|
96
|
+
errorCh.publish(err)
|
|
97
|
+
throw err
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
100
|
})
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -48,8 +48,7 @@ function patchResolveShorthands (prototype) {
|
|
|
48
48
|
|
|
49
49
|
function wrap (prefix, fn, expectedArgs, rrtype) {
|
|
50
50
|
const startCh = channel(prefix + ':start')
|
|
51
|
-
const
|
|
52
|
-
const asyncEndCh = channel(prefix + ':async-end')
|
|
51
|
+
const finishCh = channel(prefix + ':finish')
|
|
53
52
|
const errorCh = channel(prefix + ':error')
|
|
54
53
|
|
|
55
54
|
const wrapped = function () {
|
|
@@ -67,27 +66,29 @@ function wrap (prefix, fn, expectedArgs, rrtype) {
|
|
|
67
66
|
if (rrtype) {
|
|
68
67
|
startArgs.push(rrtype)
|
|
69
68
|
}
|
|
70
|
-
startCh.publish(startArgs)
|
|
71
69
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
asyncEndCh.publish(result)
|
|
77
|
-
cb.apply(this, arguments)
|
|
78
|
-
}
|
|
70
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
71
|
+
return asyncResource.runInAsyncScope(() => {
|
|
72
|
+
startCh.publish(startArgs)
|
|
79
73
|
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
arguments[arguments.length - 1] = asyncResource.bind(function (error, result) {
|
|
75
|
+
if (error) {
|
|
76
|
+
errorCh.publish(error)
|
|
77
|
+
}
|
|
78
|
+
finishCh.publish(result)
|
|
79
|
+
cb.apply(this, arguments)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
return fn.apply(this, arguments)
|
|
82
84
|
// TODO deal with promise versions when we support `dns/promises`
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
} catch (error) {
|
|
86
|
+
error.stack // trigger getting the stack at the original throwing point
|
|
87
|
+
errorCh.publish(error)
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
89
|
+
throw error
|
|
90
|
+
}
|
|
91
|
+
})
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
return shimmer.wrap(fn, wrapped)
|
|
@@ -8,8 +8,7 @@ const {
|
|
|
8
8
|
const shimmer = require('../../datadog-shimmer')
|
|
9
9
|
|
|
10
10
|
const startCh = channel('apm:elasticsearch:query:start')
|
|
11
|
-
const
|
|
12
|
-
const endCh = channel('apm:elasticsearch:query:end')
|
|
11
|
+
const finishCh = channel('apm:elasticsearch:query:finish')
|
|
13
12
|
const errorCh = channel('apm:elasticsearch:query:error')
|
|
14
13
|
|
|
15
14
|
addHook({ name: '@elastic/transport', file: 'lib/Transport.js', versions: ['>=8'] }, (exports) => {
|
|
@@ -36,43 +35,42 @@ function wrapRequest (request) {
|
|
|
36
35
|
if (!params) return request.apply(this, arguments)
|
|
37
36
|
|
|
38
37
|
const parentResource = new AsyncResource('bound-anonymous-fn')
|
|
39
|
-
|
|
40
|
-
startCh.publish({ params })
|
|
41
|
-
|
|
42
38
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
43
39
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
cb = arguments[lastIndex]
|
|
40
|
+
return asyncResource.runInAsyncScope(() => {
|
|
41
|
+
startCh.publish({ params })
|
|
47
42
|
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
try {
|
|
44
|
+
const lastIndex = arguments.length - 1
|
|
45
|
+
cb = arguments[lastIndex]
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return cb.apply(null, arguments)
|
|
54
|
-
})
|
|
55
|
-
return request.apply(this, arguments)
|
|
56
|
-
} else {
|
|
57
|
-
const promise = request.apply(this, arguments)
|
|
58
|
-
if (promise && typeof promise.then === 'function') {
|
|
59
|
-
const onResolve = asyncResource.bind(() => finish(params))
|
|
60
|
-
const onReject = asyncResource.bind(e => finish(params, e))
|
|
47
|
+
if (typeof cb === 'function') {
|
|
48
|
+
cb = parentResource.bind(cb)
|
|
61
49
|
|
|
62
|
-
|
|
50
|
+
arguments[lastIndex] = asyncResource.bind(function (error) {
|
|
51
|
+
finish(params, error)
|
|
52
|
+
return cb.apply(null, arguments)
|
|
53
|
+
})
|
|
54
|
+
return request.apply(this, arguments)
|
|
63
55
|
} else {
|
|
64
|
-
|
|
56
|
+
const promise = request.apply(this, arguments)
|
|
57
|
+
if (promise && typeof promise.then === 'function') {
|
|
58
|
+
const onResolve = asyncResource.bind(() => finish(params))
|
|
59
|
+
const onReject = asyncResource.bind(e => finish(params, e))
|
|
60
|
+
|
|
61
|
+
promise.then(onResolve, onReject)
|
|
62
|
+
} else {
|
|
63
|
+
finish(params)
|
|
64
|
+
}
|
|
65
|
+
return promise
|
|
65
66
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
err.stack // trigger getting the stack at the original throwing point
|
|
70
|
-
errorCh.publish(err)
|
|
67
|
+
} catch (err) {
|
|
68
|
+
err.stack // trigger getting the stack at the original throwing point
|
|
69
|
+
errorCh.publish(err)
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
71
|
+
throw err
|
|
72
|
+
}
|
|
73
|
+
})
|
|
76
74
|
}
|
|
77
75
|
}
|
|
78
76
|
|
|
@@ -80,5 +78,5 @@ function finish (params, error) {
|
|
|
80
78
|
if (error) {
|
|
81
79
|
errorCh.publish(error)
|
|
82
80
|
}
|
|
83
|
-
|
|
81
|
+
finishCh.publish({ params })
|
|
84
82
|
}
|
|
@@ -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,36 +46,39 @@ 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)
|
|
@@ -86,11 +90,14 @@ function onRequest (request, reply, next) {
|
|
|
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 next()
|
|
100
|
+
})
|
|
94
101
|
}
|
|
95
102
|
|
|
96
103
|
function preHandler (request, reply, next) {
|
|
@@ -98,61 +105,39 @@ function preHandler (request, reply, next) {
|
|
|
98
105
|
if (!reply || typeof reply.send !== 'function') return next()
|
|
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
|
next()
|
|
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, next) {
|
|
116
|
+
const req = getReq(request)
|
|
117
|
+
const parsingResource = parsingResources.get(req)
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
opts.handler = wrapHandler(opts.handler)
|
|
119
|
+
if (!parsingResource) return next()
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
}
|
|
121
|
+
parsingResource.runInAsyncScope(() => next())
|
|
125
122
|
}
|
|
126
123
|
|
|
127
|
-
function
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return function methodWithTrace (url, opts, handler) {
|
|
131
|
-
const lastIndex = arguments.length - 1
|
|
132
|
-
|
|
133
|
-
handler = arguments[lastIndex]
|
|
134
|
-
|
|
135
|
-
if (typeof handler === 'function') {
|
|
136
|
-
arguments[lastIndex] = wrapHandler(handler)
|
|
137
|
-
} else if (handler) {
|
|
138
|
-
arguments[lastIndex].handler = wrapHandler(handler.handler)
|
|
139
|
-
}
|
|
124
|
+
function preParsing (request, reply, next) {
|
|
125
|
+
const req = getReq(request)
|
|
126
|
+
const parsingResource = new AsyncResource('bound-anonymous-fn')
|
|
140
127
|
|
|
141
|
-
|
|
142
|
-
|
|
128
|
+
parsingResources.set(req, parsingResource)
|
|
129
|
+
parsingResource.runInAsyncScope(() => next())
|
|
143
130
|
}
|
|
144
131
|
|
|
145
|
-
function
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
132
|
+
function wrapSend (send, resource) {
|
|
133
|
+
return function sendWithTrace (payload) {
|
|
134
|
+
if (payload instanceof Error) {
|
|
135
|
+
resource.runInAsyncScope(() => {
|
|
136
|
+
errorChannel.publish(payload)
|
|
137
|
+
})
|
|
138
|
+
}
|
|
152
139
|
|
|
153
|
-
return
|
|
154
|
-
return handler.apply(this, arguments)
|
|
155
|
-
})
|
|
140
|
+
return send.apply(this, arguments)
|
|
156
141
|
}
|
|
157
142
|
}
|
|
158
143
|
|
|
@@ -164,16 +149,15 @@ function getRes (reply) {
|
|
|
164
149
|
return reply && (reply.raw || reply.res || reply)
|
|
165
150
|
}
|
|
166
151
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
wrapped.default = wrapped
|
|
152
|
+
function publishError (error, resource) {
|
|
153
|
+
resource.runInAsyncScope(() => {
|
|
154
|
+
errorChannel.publish(error)
|
|
155
|
+
})
|
|
172
156
|
|
|
173
|
-
return
|
|
174
|
-
}
|
|
157
|
+
return error
|
|
158
|
+
}
|
|
175
159
|
|
|
176
|
-
addHook({ name: 'fastify', versions: ['3
|
|
160
|
+
addHook({ name: 'fastify', versions: ['>=3'] }, fastify => {
|
|
177
161
|
const wrapped = shimmer.wrap(fastify, wrapFastify(fastify, true))
|
|
178
162
|
|
|
179
163
|
wrapped.fastify = wrapped
|
|
@@ -182,6 +166,10 @@ addHook({ name: 'fastify', versions: ['3 - 3.25.1'] }, fastify => {
|
|
|
182
166
|
return wrapped
|
|
183
167
|
})
|
|
184
168
|
|
|
185
|
-
addHook({ name: 'fastify', versions: ['
|
|
169
|
+
addHook({ name: 'fastify', versions: ['2'] }, fastify => {
|
|
186
170
|
return shimmer.wrap(fastify, wrapFastify(fastify, true))
|
|
187
171
|
})
|
|
172
|
+
|
|
173
|
+
addHook({ name: 'fastify', versions: ['1'] }, fastify => {
|
|
174
|
+
return shimmer.wrap(fastify, wrapFastify(fastify, false))
|
|
175
|
+
})
|