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.
Files changed (31) hide show
  1. package/index.d.ts +22 -0
  2. package/package.json +2 -2
  3. package/packages/datadog-instrumentations/index.js +6 -3
  4. package/packages/datadog-instrumentations/src/couchbase.js +143 -0
  5. package/packages/datadog-instrumentations/src/elasticsearch.js +74 -0
  6. package/packages/datadog-instrumentations/src/mysql.js +2 -2
  7. package/packages/datadog-instrumentations/src/mysql2.js +76 -0
  8. package/packages/datadog-instrumentations/src/q.js +9 -1
  9. package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -3
  10. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +48 -0
  11. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +56 -6
  12. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +33 -6
  13. package/packages/datadog-plugin-couchbase/src/index.js +51 -148
  14. package/packages/datadog-plugin-elasticsearch/src/index.js +41 -82
  15. package/packages/datadog-plugin-fastify/src/fastify.js +22 -1
  16. package/packages/datadog-plugin-mysql/src/index.js +4 -4
  17. package/packages/datadog-plugin-mysql2/src/index.js +5 -88
  18. package/packages/datadog-plugin-next/src/index.js +10 -6
  19. package/packages/datadog-plugin-winston/src/index.js +33 -12
  20. package/packages/dd-trace/lib/version.js +1 -1
  21. package/packages/dd-trace/src/appsec/index.js +4 -0
  22. package/packages/dd-trace/src/appsec/recommended.json +5708 -1
  23. package/packages/dd-trace/src/profiling/config.js +5 -1
  24. package/packages/dd-trace/src/profiling/profiler.js +15 -6
  25. package/packages/dd-trace/src/profiling/profilers/cpu.js +1 -1
  26. package/packages/dd-trace/src/profiling/profilers/heap.js +3 -2
  27. package/packages/dd-trace/src/tagger.js +14 -21
  28. package/packages/dd-trace/src/tracer.js +1 -1
  29. package/scripts/publish_docs.js +1 -1
  30. package/NOTICE +0 -4
  31. package/packages/dd-trace/src/profiling/mapper.js +0 -91
@@ -1,171 +1,74 @@
1
1
  'use strict'
2
2
 
3
- const Tags = require('../../../ext/tags')
4
- const Kinds = require('../../../ext/kinds')
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
- function startSpan (tracer, config, operation, resource) {
8
- const childOf = tracer.scope().active()
9
- const span = tracer.startSpan(`couchbase.${operation}`, {
10
- childOf,
11
- tags: {
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': resource,
16
- [Tags.SPAN_KIND]: Kinds.CLIENT
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
- const scope = tracer.scope()
41
- const callbackIndex = args.length - 1
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
- function createWrapQuery (tracer) {
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
- callback = arguments[arguments.length - 1]
36
+ span.setTag('couchbase.bucket.name', bucket.name || bucket._name)
59
37
 
60
- if (typeof callback === 'function') {
61
- arguments[arguments.length - 1] = scope.bind(callback)
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
- span.setTag('span.type', 'sql')
42
+ constructor (...args) {
43
+ super(...args)
79
44
 
80
- addBucketTag(span, this)
81
- onRequestFinish(emitter, span)
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
- return scope.bind(_n1qlReq, span).apply(this, arguments)
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
- function createWrapStore (tracer, config, operation) {
89
- return function wrapStore (store) {
90
- return function storeWithTrace (key, value, options, callback) {
91
- const callbackIndex = findCallbackIndex(arguments)
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 addBucketTag (span, bucket) {
108
- span.setTag('couchbase.bucket.name', bucket.name || bucket._name)
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 wrapCallback (span, callback) {
120
- return function (err, result) {
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 Tags = require('opentracing').Tags
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
- function createWrapRequest (tracer, config) {
7
- config = normalizeConfig(config)
8
- return function wrapRequest (request) {
9
- return function requestWithTrace (params, options, cb) {
10
- if (!params) return request.apply(this, arguments)
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 lastIndex = arguments.length - 1
18
+ const store = storage.getStore()
19
+ const childOf = store ? store.span : store
13
20
  const body = getBody(params.body || params.bulkBody)
14
- const childOf = tracer.scope().active()
15
- const span = tracer.startSpan('elasticsearch.query', {
21
+ const span = this.tracer.startSpan('elasticsearch.query', {
16
22
  childOf,
17
23
  tags: {
18
- [Tags.SPAN_KIND]: Tags.SPAN_KIND_RPC_CLIENT,
19
- [Tags.DB_TYPE]: 'elasticsearch',
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
- analyticsSampler.sample(span, config.measured)
31
-
32
- cb = arguments[lastIndex]
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
- function wrapCallback (tracer, span, params, config, done) {
54
- return tracer.scope().bind(function (err) {
55
- finish(span, params, config, err)
56
- done.apply(null, arguments)
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
- function finish (span, params, config, err) {
61
- if (err) {
62
- span.addTags({
63
- 'error.type': err.name,
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
- module.exports = [
98
- {
99
- name: 'elasticsearch',
100
- file: 'src/lib/transport.js',
101
- versions: ['>=10'],
102
- patch (Transport, tracer, config) {
103
- this.wrap(Transport.prototype, 'request', createWrapRequest(tracer, config))
104
- },
105
- unpatch (Transport) {
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: ['>=1'],
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('apm:mysql:query:start', ([sql, conf]) => {
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('apm:mysql:query:end', () => {
40
+ this.addSub(`apm:${this.constructor.name}:query:end`, () => {
41
41
  this.exit()
42
42
  })
43
43
 
44
- this.addSub('apm:mysql:query:error', err => {
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('apm:mysql:query:async-end', () => {
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 Tags = require('opentracing').Tags
4
- const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
3
+ const MySQLPlugin = require('../../datadog-plugin-mysql/src')
5
4
 
6
- function createWrapAddCommand (tracer, config) {
7
- return function wrapAddCommand (addCommand) {
8
- return function addCommandWithTrace (cmd) {
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
- function wrapExecute (tracer, config, execute) {
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(() => finish(span, config, req, res), err => {
119
- span.setTag('error', err)
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
- tracer.inject(span, LOG, chunk)
34
+ const holder = {}
35
+ tracer.inject(span, LOG, holder)
36
+ arguments[0] = chunkProxy(chunk, holder)
11
37
 
12
- const result = write.apply(this, arguments)
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 = arguments[2] = meta || {}
67
+ meta = meta || {}
46
68
 
47
- tracer.inject(span, LOG, meta)
69
+ const holder = {}
70
+ tracer.inject(span, LOG, holder)
48
71
 
49
- const result = log.apply(this, arguments)
72
+ arguments[2] = chunkProxy(meta, holder)
50
73
 
51
- delete meta.dd
52
-
53
- return result
74
+ return log.apply(this, arguments)
54
75
  }
55
76
  }
56
77
  }
@@ -1 +1 @@
1
- module.exports = '2.0.0'
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
  }