dd-trace 2.2.0 → 2.2.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 (48) hide show
  1. package/LICENSE-3rdparty.csv +0 -2
  2. package/index.d.ts +0 -12
  3. package/package.json +3 -5
  4. package/packages/datadog-instrumentations/index.js +8 -0
  5. package/packages/datadog-instrumentations/src/bunyan.js +22 -0
  6. package/packages/datadog-instrumentations/src/elasticsearch.js +6 -1
  7. package/packages/datadog-instrumentations/src/generic-pool.js +48 -0
  8. package/packages/datadog-instrumentations/src/ioredis.js +49 -0
  9. package/packages/datadog-instrumentations/src/mongoose.js +30 -0
  10. package/packages/datadog-instrumentations/src/pino.js +105 -0
  11. package/packages/datadog-instrumentations/src/redis.js +118 -0
  12. package/packages/datadog-instrumentations/src/sharedb.js +78 -0
  13. package/packages/datadog-instrumentations/src/winston.js +57 -0
  14. package/packages/datadog-plugin-bunyan/src/index.js +5 -22
  15. package/packages/datadog-plugin-fastify/src/find-my-way.js +0 -1
  16. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +8 -6
  17. package/packages/datadog-plugin-graphql/src/index.js +34 -28
  18. package/packages/datadog-plugin-grpc/src/client.js +20 -6
  19. package/packages/datadog-plugin-http2/src/server.js +2 -0
  20. package/packages/datadog-plugin-ioredis/src/index.js +5 -35
  21. package/packages/datadog-plugin-jest/src/jest-environment.js +26 -30
  22. package/packages/datadog-plugin-koa/src/index.js +6 -2
  23. package/packages/datadog-plugin-microgateway-core/src/index.js +1 -3
  24. package/packages/datadog-plugin-mocha/src/index.js +5 -3
  25. package/packages/datadog-plugin-mongodb-core/src/util.js +31 -7
  26. package/packages/datadog-plugin-next/src/index.js +9 -4
  27. package/packages/datadog-plugin-oracledb/src/index.js +10 -7
  28. package/packages/datadog-plugin-pino/src/index.js +5 -158
  29. package/packages/datadog-plugin-redis/src/index.js +96 -80
  30. package/packages/datadog-plugin-restify/src/index.js +18 -3
  31. package/packages/datadog-plugin-rhea/src/index.js +8 -5
  32. package/packages/datadog-plugin-router/src/index.js +23 -14
  33. package/packages/datadog-plugin-sharedb/src/index.js +47 -87
  34. package/packages/datadog-plugin-winston/src/index.js +5 -113
  35. package/packages/datadog-shimmer/src/shimmer.js +1 -1
  36. package/packages/dd-trace/lib/version.js +1 -1
  37. package/packages/dd-trace/src/appsec/index.js +2 -1
  38. package/packages/dd-trace/src/appsec/reporter.js +3 -2
  39. package/packages/dd-trace/src/constants.js +1 -6
  40. package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -34
  41. package/packages/dd-trace/src/plugins/index.js +0 -2
  42. package/packages/dd-trace/src/plugins/log_plugin.js +44 -0
  43. package/packages/dd-trace/src/plugins/plugin.js +7 -0
  44. package/packages/dd-trace/src/plugins/util/web.js +102 -84
  45. package/packages/dd-trace/src/priority_sampler.js +1 -49
  46. package/packages/dd-trace/src/scope.js +47 -23
  47. package/packages/datadog-plugin-generic-pool/src/index.js +0 -52
  48. package/packages/datadog-plugin-mongoose/src/index.js +0 -51
@@ -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.2.1'
@@ -7,6 +7,7 @@ const { incomingHttpRequestStart, incomingHttpRequestEnd } = require('./gateway/
7
7
  const Gateway = require('./gateway/engine')
8
8
  const addresses = require('./addresses')
9
9
  const Reporter = require('./reporter')
10
+ const web = require('../plugins/util/web')
10
11
 
11
12
  function enable (config) {
12
13
  try {
@@ -39,7 +40,7 @@ function enable (config) {
39
40
 
40
41
  function incomingHttpStartTranslator (data) {
41
42
  // TODO: get span from datadog-core storage instead
42
- const topSpan = data.req._datadog && data.req._datadog.span
43
+ const topSpan = web.root(data.req)
43
44
  if (topSpan) {
44
45
  topSpan.addTags({
45
46
  '_dd.appsec.enabled': 1,
@@ -2,6 +2,7 @@
2
2
 
3
3
  const addresses = require('./addresses')
4
4
  const Limiter = require('../rate_limiter')
5
+ const web = require('../plugins/util/web')
5
6
 
6
7
  // default limiter, configurable with setRateLimit()
7
8
  let limiter = new Limiter(100)
@@ -83,7 +84,7 @@ function formatHeaderName (name) {
83
84
 
84
85
  function reportAttack (attackData, store) {
85
86
  const req = store && store.get('req')
86
- const topSpan = req && req._datadog && req._datadog.span
87
+ const topSpan = web.root(req)
87
88
  if (!topSpan) return false
88
89
 
89
90
  const currentTags = topSpan.context()._tags
@@ -129,7 +130,7 @@ function reportAttack (attackData, store) {
129
130
  }
130
131
 
131
132
  function finishAttacks (req, context) {
132
- const topSpan = req && req._datadog && req._datadog.span
133
+ const topSpan = web.root(req)
133
134
  if (!topSpan || !context) return false
134
135
 
135
136
  const resolvedResponse = resolveHTTPResponse(context)
@@ -8,10 +8,5 @@ module.exports = {
8
8
  SAMPLING_RULE_DECISION: '_dd.rule_psr',
9
9
  SAMPLING_LIMIT_DECISION: '_dd.limit_psr',
10
10
  SAMPLING_AGENT_DECISION: '_dd.agent_psr',
11
- SAMPLING_MECHANISM_DEFAULT: 0,
12
- SAMPLING_MECHANISM_AGENT: 1,
13
- SAMPLING_MECHANISM_RULE: 3,
14
- SAMPLING_MECHANISM_MANUAL: 4,
15
- DATADOG_LAMBDA_EXTENSION_PATH: '/opt/extensions/datadog-agent',
16
- UPSTREAM_SERVICES_KEY: '_dd.p.upstream_services'
11
+ DATADOG_LAMBDA_EXTENSION_PATH: '/opt/extensions/datadog-agent'
17
12
  }
@@ -11,7 +11,6 @@ const traceKey = 'x-datadog-trace-id'
11
11
  const spanKey = 'x-datadog-parent-id'
12
12
  const originKey = 'x-datadog-origin'
13
13
  const samplingKey = 'x-datadog-sampling-priority'
14
- const tagsKey = 'x-datadog-tags'
15
14
  const baggagePrefix = 'ot-baggage-'
16
15
  const b3TraceKey = 'x-b3-traceid'
17
16
  const b3TraceExpr = /^([0-9a-f]{16}){1,2}$/i
@@ -41,7 +40,6 @@ class TextMapPropagator {
41
40
  this._injectSamplingPriority(spanContext, carrier)
42
41
  this._injectBaggageItems(spanContext, carrier)
43
42
  this._injectB3(spanContext, carrier)
44
- this._injectTags(spanContext, carrier)
45
43
 
46
44
  log.debug(() => `Inject into carrier: ${JSON.stringify(pick(carrier, logKeys))}.`)
47
45
  }
@@ -78,25 +76,6 @@ class TextMapPropagator {
78
76
  })
79
77
  }
80
78
 
81
- _injectTags (spanContext, carrier) {
82
- const trace = spanContext._trace
83
- const tags = []
84
-
85
- for (const key in trace.tags) {
86
- if (!key.startsWith('_dd.p.')) continue
87
-
88
- tags.push(`${key}=${trace.tags[key]}`)
89
- }
90
-
91
- const header = tags.join(',')
92
-
93
- if (header.length <= 512) {
94
- carrier[tagsKey] = header
95
- } else {
96
- trace.tags['_dd.propagation_error:max_size'] = 1
97
- }
98
- }
99
-
100
79
  _injectB3 (spanContext, carrier) {
101
80
  if (!this._config.experimental.b3) return
102
81
 
@@ -124,7 +103,6 @@ class TextMapPropagator {
124
103
  this._extractOrigin(carrier, spanContext)
125
104
  this._extractBaggageItems(carrier, spanContext)
126
105
  this._extractSamplingPriority(carrier, spanContext)
127
- this._extractTags(carrier, spanContext)
128
106
  }
129
107
 
130
108
  return spanContext
@@ -262,18 +240,6 @@ class TextMapPropagator {
262
240
  }
263
241
  }
264
242
 
265
- _extractTags (carrier, spanContext) {
266
- if (!carrier[tagsKey]) return
267
-
268
- const pairs = carrier[tagsKey].split(',')
269
-
270
- for (const pair of pairs) {
271
- const [key, value] = pair.split('=')
272
-
273
- spanContext._trace.tags[key] = value
274
- }
275
- }
276
-
277
243
  _getPriority (sampled, debug) {
278
244
  if (debug) {
279
245
  return USER_KEEP
@@ -15,7 +15,6 @@ module.exports = {
15
15
  'express': require('../../../datadog-plugin-express/src'),
16
16
  'fastify': require('../../../datadog-plugin-fastify/src'),
17
17
  'fs': require('../../../datadog-plugin-fs/src'),
18
- 'generic-pool': require('../../../datadog-plugin-generic-pool/src'),
19
18
  'google-cloud-pubsub': require('../../../datadog-plugin-google-cloud-pubsub/src'),
20
19
  'graphql': require('../../../datadog-plugin-graphql/src'),
21
20
  'grpc': require('../../../datadog-plugin-grpc/src'),
@@ -33,7 +32,6 @@ module.exports = {
33
32
  'mocha': require('../../../datadog-plugin-mocha/src'),
34
33
  'moleculer': require('../../../datadog-plugin-moleculer/src'),
35
34
  'mongodb-core': require('../../../datadog-plugin-mongodb-core/src'),
36
- 'mongoose': require('../../../datadog-plugin-mongoose/src'),
37
35
  'mysql': require('../../../datadog-plugin-mysql/src'),
38
36
  'mysql2': require('../../../datadog-plugin-mysql2/src'),
39
37
  'net': require('../../../datadog-plugin-net/src'),
@@ -0,0 +1,44 @@
1
+ 'use strict'
2
+
3
+ const { LOG } = require('../../../../ext/formats')
4
+ const Plugin = require('./plugin')
5
+ const { storage } = require('../../../datadog-core')
6
+
7
+ const hasOwn = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
8
+
9
+ function messageProxy (message, holder) {
10
+ return new Proxy(message, {
11
+ get (target, p, receiver) {
12
+ switch (p) {
13
+ case Symbol.toStringTag:
14
+ return Object.prototype.toString.call(target).slice(8, -1)
15
+ case 'dd':
16
+ return holder.dd
17
+ default:
18
+ return Reflect.get(target, p, receiver)
19
+ }
20
+ },
21
+ ownKeys (target) {
22
+ const ownKeys = Reflect.ownKeys(target)
23
+ return hasOwn(target, 'dd') ? ownKeys : ['dd', ...ownKeys]
24
+ },
25
+ getOwnPropertyDescriptor (target, p) {
26
+ return Reflect.getOwnPropertyDescriptor(p === 'dd' ? holder : target, p)
27
+ }
28
+ })
29
+ }
30
+
31
+ module.exports = class LogPlugin extends Plugin {
32
+ constructor (...args) {
33
+ super(...args)
34
+ this.addSub(`apm:${this.constructor.name}:log`, (arg) => {
35
+ // TODO rather than checking this every time, setting it ought to enable/disable any plugin
36
+ // extending from this one
37
+ if (this.tracer._logInjection) {
38
+ const holder = {}
39
+ this.tracer.inject(storage.getStore().span, LOG, holder)
40
+ arg.message = messageProxy(arg.message, holder)
41
+ }
42
+ })
43
+ }
44
+ }
@@ -42,6 +42,13 @@ module.exports = class Plugin {
42
42
  storage.enterWith({ ...store, span })
43
43
  }
44
44
 
45
+ /** Prevents creation of spans here and for all async descendants. */
46
+ skip () {
47
+ const store = storage.getStore()
48
+ this._storeStack.push(store)
49
+ storage.enterWith({ noop: true })
50
+ }
51
+
45
52
  exit () {
46
53
  storage.enterWith(this._storeStack.pop())
47
54
  }