dd-trace 2.2.0 → 2.3.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.
Files changed (55) hide show
  1. package/LICENSE-3rdparty.csv +0 -2
  2. package/index.d.ts +6 -12
  3. package/package.json +3 -5
  4. package/packages/datadog-instrumentations/index.js +9 -0
  5. package/packages/datadog-instrumentations/src/bunyan.js +22 -0
  6. package/packages/datadog-instrumentations/src/cucumber.js +116 -0
  7. package/packages/datadog-instrumentations/src/elasticsearch.js +15 -5
  8. package/packages/datadog-instrumentations/src/generic-pool.js +48 -0
  9. package/packages/datadog-instrumentations/src/ioredis.js +52 -0
  10. package/packages/datadog-instrumentations/src/mongoose.js +30 -0
  11. package/packages/datadog-instrumentations/src/pino.js +105 -0
  12. package/packages/datadog-instrumentations/src/redis.js +118 -0
  13. package/packages/datadog-instrumentations/src/sharedb.js +78 -0
  14. package/packages/datadog-instrumentations/src/winston.js +57 -0
  15. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -2
  16. package/packages/datadog-plugin-bunyan/src/index.js +5 -22
  17. package/packages/datadog-plugin-cucumber/src/index.js +83 -128
  18. package/packages/datadog-plugin-fastify/src/find-my-way.js +0 -1
  19. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +8 -6
  20. package/packages/datadog-plugin-graphql/src/index.js +34 -28
  21. package/packages/datadog-plugin-grpc/src/client.js +20 -6
  22. package/packages/datadog-plugin-http2/src/server.js +2 -0
  23. package/packages/datadog-plugin-ioredis/src/index.js +5 -35
  24. package/packages/datadog-plugin-jest/src/jest-environment.js +26 -30
  25. package/packages/datadog-plugin-koa/src/index.js +6 -2
  26. package/packages/datadog-plugin-microgateway-core/src/index.js +1 -3
  27. package/packages/datadog-plugin-mocha/src/index.js +5 -3
  28. package/packages/datadog-plugin-mongodb-core/src/util.js +31 -7
  29. package/packages/datadog-plugin-next/src/index.js +9 -4
  30. package/packages/datadog-plugin-oracledb/src/index.js +10 -7
  31. package/packages/datadog-plugin-pino/src/index.js +5 -158
  32. package/packages/datadog-plugin-redis/src/index.js +96 -80
  33. package/packages/datadog-plugin-restify/src/index.js +18 -3
  34. package/packages/datadog-plugin-rhea/src/index.js +8 -5
  35. package/packages/datadog-plugin-router/src/index.js +23 -14
  36. package/packages/datadog-plugin-sharedb/src/index.js +47 -87
  37. package/packages/datadog-plugin-winston/src/index.js +5 -113
  38. package/packages/datadog-shimmer/src/shimmer.js +1 -1
  39. package/packages/dd-trace/lib/version.js +1 -1
  40. package/packages/dd-trace/src/appsec/index.js +2 -1
  41. package/packages/dd-trace/src/appsec/reporter.js +3 -2
  42. package/packages/dd-trace/src/config.js +7 -1
  43. package/packages/dd-trace/src/constants.js +1 -6
  44. package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -34
  45. package/packages/dd-trace/src/opentracing/tracer.js +1 -1
  46. package/packages/dd-trace/src/plugins/index.js +0 -2
  47. package/packages/dd-trace/src/plugins/log_plugin.js +49 -0
  48. package/packages/dd-trace/src/plugins/plugin.js +7 -0
  49. package/packages/dd-trace/src/plugins/util/git.js +1 -1
  50. package/packages/dd-trace/src/plugins/util/web.js +102 -84
  51. package/packages/dd-trace/src/priority_sampler.js +1 -49
  52. package/packages/dd-trace/src/scope.js +47 -23
  53. package/packages/dd-trace/src/span_processor.js +22 -7
  54. package/packages/datadog-plugin-generic-pool/src/index.js +0 -52
  55. package/packages/datadog-plugin-mongoose/src/index.js +0 -51
@@ -1,104 +1,120 @@
1
1
  'use strict'
2
2
 
3
- // TODO: always use uppercase for command names
3
+ const Plugin = require('../../dd-trace/src/plugins/plugin')
4
+ const { storage } = require('../../datadog-core')
5
+ const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
6
+ const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
7
+
8
+ class RedisPlugin extends Plugin {
9
+ static get name () {
10
+ return 'redis'
11
+ }
4
12
 
5
- const tx = require('../../dd-trace/src/plugins/util/redis')
13
+ constructor (...args) {
14
+ super(...args)
6
15
 
7
- function createWrapAddCommand (tracer, config) {
8
- return function wrapAddCommand (addCommand) {
9
- return function addCommandWithTrace (command) {
10
- const name = command[0]
11
- const args = command.slice(1)
16
+ this.addSub(`apm:${this.constructor.name}:command:start`, (
17
+ { db, command, args, connectionOptions, connectionName }
18
+ ) => {
19
+ if (!this.config.filter(command)) {
20
+ return this.skip()
21
+ }
22
+ const store = storage.getStore()
23
+ const childOf = store ? store.span : store
24
+ const span = this.tracer.startSpan('redis.command', {
25
+ childOf,
26
+ tags: {
27
+ 'span.kind': 'client',
28
+ 'resource.name': command,
29
+ 'span.type': 'redis',
30
+ 'db.type': 'redis',
31
+ 'db.name': db || '0',
32
+ 'redis.raw_command': formatCommand(command, args)
33
+ }
34
+ })
35
+
36
+ span.setTag('service.name', this.config.service || `${span.context()._tags['service.name']}-redis`)
37
+
38
+ analyticsSampler.sample(span, this.config.measured)
39
+
40
+ if (connectionOptions) {
41
+ span.addTags({
42
+ 'out.host': connectionOptions.host,
43
+ 'out.port': connectionOptions.port
44
+ })
45
+ }
12
46
 
13
- if (!config.filter(name)) return addCommand.apply(this, arguments)
47
+ if (this.config.splitByInstance && connectionName) {
48
+ const service = this.config.service
49
+ ? `${this.config.service}-${connectionName}`
50
+ : connectionName
14
51
 
15
- const scope = tracer.scope()
16
- const span = startSpan(tracer, config, this, name, args)
52
+ span.setTag('service.name', service)
53
+ }
17
54
 
18
- return tx.wrap(span, scope.bind(addCommand, span).apply(this, arguments))
19
- }
20
- }
21
- }
55
+ this.enter(span, store)
56
+ })
22
57
 
23
- function createWrapInternalSendCommand (tracer, config) {
24
- return function wrapInternalSendCommand (internalSendCommand) {
25
- return function internalSendCommandWithTrace (options) {
26
- if (!config.filter(options.command)) return internalSendCommand.apply(this, arguments)
58
+ this.addSub(`apm:${this.constructor.name}:command:end`, () => {
59
+ this.exit()
60
+ })
27
61
 
28
- const scope = tracer.scope()
29
- const span = startSpan(tracer, config, this, options.command, options.args)
62
+ this.addSub(`apm:${this.constructor.name}:command:error`, err => {
63
+ const span = storage.getStore().span
64
+ span.setTag('error', err)
65
+ })
30
66
 
31
- options.callback = scope.bind(tx.wrap(span, options.callback))
67
+ this.addSub(`apm:${this.constructor.name}:command:async-end`, () => {
68
+ const span = storage.getStore().span
69
+ span.finish()
70
+ })
71
+ }
32
72
 
33
- return scope.bind(internalSendCommand, span).apply(this, arguments)
34
- }
73
+ configure (config) {
74
+ super.configure(normalizeConfig(config))
35
75
  }
36
76
  }
37
77
 
38
- function createWrapSendCommand (tracer, config) {
39
- return function wrapSendCommand (sendCommand) {
40
- return function sendCommandWithTrace (command, args, callback) {
41
- if (!config.filter(command)) return sendCommand.apply(this, arguments)
78
+ function formatCommand (command, args) {
79
+ command = command.toUpperCase()
42
80
 
43
- const scope = tracer.scope()
44
- const span = startSpan(tracer, config, this, command, args)
81
+ if (!args || command === 'AUTH') return command
45
82
 
46
- if (typeof callback === 'function') {
47
- arguments[2] = scope.bind(tx.wrap(span, callback))
48
- } else if (Array.isArray(args) && typeof args[args.length - 1] === 'function') {
49
- args[args.length - 1] = scope.bind(tx.wrap(span, args[args.length - 1]))
50
- } else {
51
- arguments[2] = tx.wrap(span)
52
- }
83
+ for (let i = 0, l = args.length; i < l; i++) {
84
+ if (typeof args[i] === 'function') continue
85
+
86
+ command = `${command} ${formatArg(args[i])}`
53
87
 
54
- return scope.bind(sendCommand, span).apply(this, arguments)
55
- }
88
+ if (command.length > 1000) return trim(command, 1000)
89
+ }
90
+
91
+ return command
92
+ }
93
+
94
+ function formatArg (arg) {
95
+ switch (typeof arg) {
96
+ case 'string':
97
+ case 'number':
98
+ return trim(String(arg), 100)
99
+ default:
100
+ return '?'
56
101
  }
57
102
  }
58
103
 
59
- function startSpan (tracer, config, client, command, args) {
60
- const db = client.selected_db
61
- const connectionOptions = client.connection_options || client.connection_option || client.connectionOption || {}
62
- const span = tx.instrument(tracer, config, db, command, args)
104
+ function trim (str, maxlen) {
105
+ if (str.length > maxlen) {
106
+ str = str.substr(0, maxlen - 3) + '...'
107
+ }
108
+
109
+ return str
110
+ }
63
111
 
64
- tx.setHost(span, connectionOptions.host, connectionOptions.port)
112
+ function normalizeConfig (config) {
113
+ const filter = urlFilter.getFilter(config)
65
114
 
66
- return span
115
+ return Object.assign({}, config, {
116
+ filter
117
+ })
67
118
  }
68
119
 
69
- module.exports = [
70
- {
71
- name: '@node-redis/client',
72
- versions: ['>=1'],
73
- file: 'dist/lib/client/commands-queue.js',
74
- patch (redis, tracer, config) {
75
- config = tx.normalizeConfig(config)
76
- this.wrap(redis.default.prototype, 'addCommand', createWrapAddCommand(tracer, config))
77
- },
78
- unpatch (redis) {
79
- this.unwrap(redis.default.prototype, 'addCommand')
80
- }
81
- },
82
- {
83
- name: 'redis',
84
- versions: ['>=2.6 <4'],
85
- patch (redis, tracer, config) {
86
- config = tx.normalizeConfig(config)
87
- this.wrap(redis.RedisClient.prototype, 'internal_send_command', createWrapInternalSendCommand(tracer, config))
88
- },
89
- unpatch (redis) {
90
- this.unwrap(redis.RedisClient.prototype, 'internal_send_command')
91
- }
92
- },
93
- {
94
- name: 'redis',
95
- versions: ['>=0.12 <2.6'],
96
- patch (redis, tracer, config) {
97
- config = tx.normalizeConfig(config)
98
- this.wrap(redis.RedisClient.prototype, 'send_command', createWrapSendCommand(tracer, config))
99
- },
100
- unpatch (redis) {
101
- this.unwrap(redis.RedisClient.prototype, 'send_command')
102
- }
103
- }
104
- ]
120
+ module.exports = RedisPlugin
@@ -4,14 +4,14 @@ const web = require('../../dd-trace/src/plugins/util/web')
4
4
  const handlers = ['use', 'pre']
5
5
  const methods = ['del', 'get', 'head', 'opts', 'post', 'put', 'patch']
6
6
 
7
- function createWrapSetupRequest (tracer, config) {
7
+ function createWrapSetupRequest (tracer, config, withRoute) {
8
8
  config = web.normalizeConfig(config)
9
9
 
10
10
  return function wrapSetupRequest (setupRequest) {
11
11
  return function setupRequestWithTrace (req, res) {
12
12
  return web.instrument(tracer, config, req, res, 'restify.request', () => {
13
13
  web.beforeEnd(req, () => {
14
- if (req.route && !req._datadog.routeEntered) {
14
+ if (req.route && withRoute) {
15
15
  web.enterRoute(req, req.route.path)
16
16
  }
17
17
  })
@@ -55,7 +55,7 @@ function wrapFn (fn) {
55
55
  module.exports = [
56
56
  {
57
57
  name: 'restify',
58
- versions: ['>=3'],
58
+ versions: ['>=7'],
59
59
  file: 'lib/server.js',
60
60
  patch (Server, tracer, config) {
61
61
  this.wrap(Server.prototype, '_setupRequest', createWrapSetupRequest(tracer, config))
@@ -67,5 +67,20 @@ module.exports = [
67
67
  this.unwrap(Server.prototype, handlers)
68
68
  this.unwrap(Server.prototype, methods)
69
69
  }
70
+ },
71
+ {
72
+ name: 'restify',
73
+ versions: ['3 - 6'],
74
+ file: 'lib/server.js',
75
+ patch (Server, tracer, config) {
76
+ this.wrap(Server.prototype, '_setupRequest', createWrapSetupRequest(tracer, config, true))
77
+ this.wrap(Server.prototype, handlers, createWrapHandler(tracer, config))
78
+ this.wrap(Server.prototype, methods, createWrapMethod(tracer, config))
79
+ },
80
+ unpatch (Server) {
81
+ this.unwrap(Server.prototype, '_setupRequest')
82
+ this.unwrap(Server.prototype, handlers)
83
+ this.unwrap(Server.prototype, methods)
84
+ }
70
85
  }
71
86
  ]
@@ -6,6 +6,8 @@ const dd = Symbol('datadog')
6
6
  const circularBufferConstructor = Symbol('circularBufferConstructor')
7
7
  const inFlightDeliveries = Symbol('inFlightDeliveries')
8
8
 
9
+ const patched = new WeakSet()
10
+
9
11
  function createWrapSend (tracer, config, instrumenter) {
10
12
  return function wrapSend (send) {
11
13
  return function sendWithTrace (msg, tag, format) {
@@ -133,9 +135,9 @@ function patchCircularBuffer (proto, instrumenter) {
133
135
  if (outgoing.deliveries) {
134
136
  CircularBuffer = outgoing.deliveries.constructor
135
137
  }
136
- if (CircularBuffer && !CircularBuffer.prototype._datadog_patched) {
138
+ if (CircularBuffer && !patched.has(CircularBuffer.prototype)) {
137
139
  instrumenter.wrap(CircularBuffer.prototype, 'pop_if', createWrapCircularBufferPopIf())
138
- CircularBuffer.prototype._datadog_patched = true
140
+ patched.add(CircularBuffer.prototype)
139
141
  const Session = proto.constructor
140
142
  if (Session) {
141
143
  Session[circularBufferConstructor] = CircularBuffer
@@ -260,9 +262,10 @@ module.exports = [
260
262
  patchCircularBuffer(Session.prototype, this)
261
263
  },
262
264
  unpatch (Session, tracer) {
263
- if (Session[circularBufferConstructor]) {
264
- delete Session[circularBufferConstructor].prototype._datadog_patched
265
- this.unwrap(Session[circularBufferConstructor].prototype, 'pop_if')
265
+ const CircularBuffer = Session[circularBufferConstructor]
266
+ if (CircularBuffer) {
267
+ patched.delete(CircularBuffer.prototype)
268
+ this.unwrap(CircularBuffer.prototype, 'pop_if')
266
269
  }
267
270
  }
268
271
  }
@@ -5,9 +5,10 @@ const pathToRegExp = require('path-to-regexp')
5
5
  const shimmer = require('../../datadog-shimmer')
6
6
  const web = require('../../dd-trace/src/plugins/util/web')
7
7
 
8
- // TODO: clean this up to not use web util internals
9
8
  // TODO: stop checking for fast star and fast slash
10
9
 
10
+ const contexts = new WeakMap()
11
+ const layerMatchers = new WeakMap()
11
12
  const regexpCache = Object.create(null)
12
13
 
13
14
  function createWrapHandle (tracer, config) {
@@ -15,17 +16,17 @@ function createWrapHandle (tracer, config) {
15
16
  return function handleWithTrace (req, res, done) {
16
17
  web.patch(req)
17
18
 
18
- if (!req._datadog.router) {
19
+ if (!contexts.has(req)) {
19
20
  const context = {
20
21
  route: '',
21
22
  stack: []
22
23
  }
23
24
 
24
25
  web.beforeEnd(req, () => {
25
- req._datadog.paths = [context.route]
26
+ web.enterRoute(req, context.route)
26
27
  })
27
28
 
28
- req._datadog.router = context
29
+ contexts.set(req, context)
29
30
  }
30
31
 
31
32
  return handle.apply(this, arguments)
@@ -78,7 +79,7 @@ function wrapStack (stack, offset, matchers) {
78
79
  layer.handle = wrapLayerHandle(layer, layer.handle)
79
80
  }
80
81
 
81
- layer._datadog_matchers = matchers
82
+ layerMatchers.set(layer, matchers)
82
83
 
83
84
  if (layer.route) {
84
85
  METHODS.forEach(method => {
@@ -96,10 +97,12 @@ function wrapNext (layer, req, next) {
96
97
  if (!next || !web.active(req)) return next
97
98
 
98
99
  const originalNext = next
100
+ const context = contexts.get(req)
101
+ const matchers = layerMatchers.get(layer)
99
102
 
100
103
  return function (error) {
101
- if (layer.path && !isFastStar(layer) && !isFastSlash(layer)) {
102
- req._datadog.router.stack.pop()
104
+ if (layer.path && !isFastStar(layer, matchers) && !isFastSlash(layer, matchers)) {
105
+ context.stack.pop()
103
106
  }
104
107
 
105
108
  web.finish(req, error)
@@ -109,13 +112,13 @@ function wrapNext (layer, req, next) {
109
112
  }
110
113
 
111
114
  function callHandle (layer, handle, req, args) {
112
- const matchers = layer._datadog_matchers
115
+ const matchers = layerMatchers.get(layer)
113
116
 
114
117
  if (web.active(req) && matchers) {
115
118
  // Try to guess which path actually matched
116
119
  for (let i = 0; i < matchers.length; i++) {
117
120
  if (matchers[i].test(layer)) {
118
- const context = req._datadog.router
121
+ const context = contexts.get(req)
119
122
 
120
123
  context.stack.push(matchers[i].path)
121
124
 
@@ -145,24 +148,30 @@ function extractMatchers (fn) {
145
148
 
146
149
  return arg.map(pattern => ({
147
150
  path: pattern instanceof RegExp ? `(${pattern})` : pattern,
148
- test: layer => !isFastStar(layer) && !isFastSlash(layer) && cachedPathToRegExp(pattern).test(layer.path)
151
+ test: layer => {
152
+ const matchers = layerMatchers.get(layer)
153
+
154
+ return !isFastStar(layer, matchers) &&
155
+ !isFastSlash(layer, matchers) &&
156
+ cachedPathToRegExp(pattern).test(layer.path)
157
+ }
149
158
  }))
150
159
  }
151
160
 
152
- function isFastStar (layer) {
161
+ function isFastStar (layer, matchers) {
153
162
  if (layer.regexp.fast_star !== undefined) {
154
163
  return layer.regexp.fast_star
155
164
  }
156
165
 
157
- return layer._datadog_matchers.some(matcher => matcher.path === '*')
166
+ return matchers.some(matcher => matcher.path === '*')
158
167
  }
159
168
 
160
- function isFastSlash (layer) {
169
+ function isFastSlash (layer, matchers) {
161
170
  if (layer.regexp.fast_slash !== undefined) {
162
171
  return layer.regexp.fast_slash
163
172
  }
164
173
 
165
- return layer._datadog_matchers.some(matcher => matcher.path === '/')
174
+ return matchers.some(matcher => matcher.path === '/')
166
175
  }
167
176
 
168
177
  function flatten (arr) {
@@ -1,35 +1,53 @@
1
1
  'use strict'
2
2
 
3
- /**
4
- * @description The enum values in this map are not exposed from ShareDB, so the keys are hard-coded here.
5
- * The values were derived from: https://github.com/share/sharedb/blob/master/lib/client/connection.js#L196
6
- */
7
- const READABLE_ACTION_NAMES = {
8
- hs: 'handshake',
9
- qf: 'query-fetch',
10
- qs: 'query-subscribe',
11
- qu: 'query-unsubscribe',
12
- bf: 'bulk-fetch',
13
- bs: 'bulk-subscribe',
14
- bu: 'bulk-unsubscribe',
15
- f: 'fetch',
16
- s: 'subscribe',
17
- u: 'unsubscribe',
18
- op: 'op',
19
- nf: 'snapshot-fetch',
20
- nt: 'snapshot-fetch-by-ts',
21
- p: 'presence-broadcast',
22
- pr: 'presence-request',
23
- ps: 'presence-subscribe',
24
- pu: 'presence-unsubscribe'
25
- }
3
+ const Plugin = require('../../dd-trace/src/plugins/plugin')
4
+ const { storage } = require('../../datadog-core')
5
+
6
+ class SharedbPlugin extends Plugin {
7
+ static get name () {
8
+ return 'sharedb'
9
+ }
10
+
11
+ constructor (...args) {
12
+ super(...args)
13
+
14
+ this.addSub(`apm:sharedb:request:start`, ({ actionName, request }) => {
15
+ const store = storage.getStore()
16
+ const childOf = store ? store.span : store
17
+ const span = this.tracer.startSpan('sharedb.request', {
18
+ childOf,
19
+ tags: {
20
+ 'service.name': this.config.service || this.tracer._service,
21
+ 'span.kind': 'server',
22
+ 'sharedb.action': actionName,
23
+ 'resource.name': getReadableResourceName(actionName, request.c, request.q)
24
+ }
25
+ })
26
+
27
+ if (this.config.hooks && this.config.hooks.receive) {
28
+ this.config.hooks.receive(span, request)
29
+ }
26
30
 
27
- function getReadableActionName (action) {
28
- const actionName = READABLE_ACTION_NAMES[action]
29
- if (actionName === undefined) {
30
- return action
31
+ this.enter(span, store)
32
+ })
33
+
34
+ this.addSub(`apm:sharedb:request:end`, () => {
35
+ this.exit()
36
+ })
37
+
38
+ this.addSub(`apm:sharedb:request:error`, err => {
39
+ const span = storage.getStore().span
40
+ span.setTag('error', err)
41
+ })
42
+
43
+ this.addSub(`apm:sharedb:request:async-end`, ({ request, res }) => {
44
+ const span = storage.getStore().span
45
+ if (this.config.hooks && this.config.hooks.reply) {
46
+ this.config.hooks.reply(span, request, res)
47
+ }
48
+ span.finish()
49
+ })
31
50
  }
32
- return actionName
33
51
  }
34
52
 
35
53
  function getReadableResourceName (readableActionName, collection, query) {
@@ -60,62 +78,4 @@ function isObject (val) {
60
78
  return typeof val === 'object' && val !== null && !(val instanceof Array)
61
79
  }
62
80
 
63
- function wrapCallback (config, tracer, request, span, done) {
64
- return tracer.scope().bind((err, res) => {
65
- if (err) {
66
- span.setTag('error', err)
67
- }
68
-
69
- if (config.hooks && config.hooks.reply) {
70
- config.hooks.reply(span, request, res)
71
- }
72
-
73
- span.finish()
74
-
75
- if (done) {
76
- done(err, res)
77
- }
78
- })
79
- }
80
-
81
- function createAgentWrapHandle (tracer, config) {
82
- return function wrapHandleMessage (origHandleMessageFn) { // called once
83
- return function handleMessageWithTrace (request, callback) { // called for each trigger
84
- const action = request.a
85
-
86
- const actionName = getReadableActionName(action)
87
-
88
- const scope = tracer.scope()
89
- const childOf = scope.active()
90
- const span = tracer.startSpan('sharedb.request', {
91
- childOf,
92
- tags: {
93
- 'service.name': config.service || tracer._service,
94
- 'span.kind': 'server',
95
- 'sharedb.action': actionName,
96
- 'resource.name': getReadableResourceName(actionName, request.c, request.q)
97
- }
98
- })
99
-
100
- if (config.hooks && config.hooks.receive) {
101
- config.hooks.receive(span, request)
102
- }
103
-
104
- arguments[1] = wrapCallback(config, tracer, request, span, callback)
105
-
106
- return tracer.scope().bind(origHandleMessageFn, span).apply(this, arguments)
107
- }
108
- }
109
- }
110
-
111
- module.exports = {
112
- name: 'sharedb',
113
- versions: ['>=1'],
114
- file: 'lib/agent.js',
115
- patch (Agent, tracer, config) {
116
- this.wrap(Agent.prototype, '_handleMessage', createAgentWrapHandle(tracer, config))
117
- },
118
- unpatch (Agent) {
119
- this.unwrap(Agent.prototype, '_handleMessage')
120
- }
121
- }
81
+ module.exports = SharedbPlugin
@@ -1,118 +1,10 @@
1
1
  'use strict'
2
2
 
3
- const { LOG } = require('../../../ext/formats')
3
+ const LogPlugin = require('../../dd-trace/src/plugins/log_plugin')
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
-
29
- function createWrapWrite (tracer, config) {
30
- return function wrapWrite (write) {
31
- return function writeWithTrace (chunk, encoding, callback) {
32
- const span = tracer.scope().active()
33
-
34
- const holder = {}
35
- tracer.inject(span, LOG, holder)
36
- arguments[0] = chunkProxy(chunk, holder)
37
-
38
- return write.apply(this, arguments)
39
- }
5
+ class WinstonPlugin extends LogPlugin {
6
+ static get name () {
7
+ return 'winston'
40
8
  }
41
9
  }
42
-
43
- function createWrapMethod (tracer, config) {
44
- return function wrapMethod (method) {
45
- return function methodWithTrace () {
46
- const result = method.apply(this, arguments)
47
-
48
- for (const name in this.transports) {
49
- const transport = this.transports[name]
50
-
51
- if (transport._dd_patched || typeof transport.log !== 'function') continue
52
-
53
- transport.log = createWrapLog(tracer, config)(transport.log)
54
- transport._dd_patched = true
55
- }
56
-
57
- return result
58
- }
59
- }
60
- }
61
-
62
- function createWrapLog (tracer, config) {
63
- return function wrapLog (log) {
64
- return function logWithTrace (level, msg, meta, callback) {
65
- const span = tracer.scope().active()
66
-
67
- meta = meta || {}
68
-
69
- const holder = {}
70
- tracer.inject(span, LOG, holder)
71
-
72
- arguments[2] = chunkProxy(meta, holder)
73
-
74
- return log.apply(this, arguments)
75
- }
76
- }
77
- }
78
-
79
- module.exports = [
80
- {
81
- name: 'winston',
82
- file: 'lib/winston/logger.js',
83
- versions: ['>=3'],
84
- patch (Logger, tracer, config) {
85
- if (!tracer._logInjection) return
86
- this.wrap(Logger.prototype, 'write', createWrapWrite(tracer, config))
87
- },
88
- unpatch (Logger) {
89
- this.unwrap(Logger.prototype, 'write')
90
- }
91
- },
92
- {
93
- name: 'winston',
94
- file: 'lib/winston/logger.js',
95
- versions: ['2'],
96
- patch (logger, tracer, config) {
97
- if (!tracer._logInjection) return
98
- this.wrap(logger.Logger.prototype, 'configure', createWrapMethod(tracer, config))
99
- this.wrap(logger.Logger.prototype, 'add', createWrapMethod(tracer, config))
100
- },
101
- unpatch (logger) {
102
- this.unwrap(logger.Logger.prototype, 'configure')
103
- this.unwrap(logger.Logger.prototype, 'add')
104
- }
105
- },
106
- {
107
- name: 'winston',
108
- file: 'lib/winston/logger.js',
109
- versions: ['1'],
110
- patch (logger, tracer, config) {
111
- if (!tracer._logInjection) return
112
- this.wrap(logger.Logger.prototype, 'add', createWrapMethod(tracer, config))
113
- },
114
- unpatch (logger) {
115
- this.unwrap(logger.Logger.prototype, 'add')
116
- }
117
- }
118
- ]
10
+ module.exports = WinstonPlugin
@@ -132,7 +132,7 @@ function assertFunction (target) {
132
132
  }
133
133
 
134
134
  function assertNotClass (target) {
135
- if (target.toString && target.toString().startsWith('class')) {
135
+ if (Function.prototype.toString.call(target).startsWith('class')) {
136
136
  throw new Error('Target is a native class constructor and cannot be wrapped.')
137
137
  }
138
138
  }
@@ -1 +1 @@
1
- module.exports = '2.2.0'
1
+ module.exports = '2.3.1'