dd-trace 2.12.1 → 3.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 (107) hide show
  1. package/LICENSE-3rdparty.csv +3 -2
  2. package/MIGRATING.md +119 -0
  3. package/ci/init.js +2 -27
  4. package/ext/formats.js +3 -5
  5. package/ext/tags.d.ts +2 -1
  6. package/ext/tags.js +2 -1
  7. package/index.d.ts +44 -38
  8. package/package.json +9 -8
  9. package/packages/datadog-core/src/storage/async_resource.js +19 -1
  10. package/packages/datadog-core/src/storage/index.js +1 -1
  11. package/packages/datadog-instrumentations/index.js +1 -52
  12. package/packages/datadog-instrumentations/src/connect.js +1 -1
  13. package/packages/datadog-instrumentations/src/crypto.js +30 -0
  14. package/packages/datadog-instrumentations/src/cucumber.js +15 -0
  15. package/packages/datadog-instrumentations/src/grpc/client.js +2 -2
  16. package/packages/datadog-instrumentations/src/grpc/server.js +1 -1
  17. package/packages/datadog-instrumentations/src/hapi.js +3 -31
  18. package/packages/datadog-instrumentations/src/helpers/hooks.js +69 -0
  19. package/packages/datadog-instrumentations/src/helpers/instrument.js +5 -34
  20. package/packages/datadog-instrumentations/src/helpers/instrumentations.js +7 -0
  21. package/packages/datadog-instrumentations/src/helpers/register.js +59 -0
  22. package/packages/datadog-instrumentations/src/http/server.js +1 -1
  23. package/packages/datadog-instrumentations/src/jest.js +33 -11
  24. package/packages/datadog-instrumentations/src/koa.js +1 -1
  25. package/packages/datadog-instrumentations/src/mocha.js +4 -1
  26. package/packages/datadog-instrumentations/src/net.js +13 -0
  27. package/packages/datadog-instrumentations/src/pg.js +2 -2
  28. package/packages/datadog-instrumentations/src/restify.js +27 -5
  29. package/packages/datadog-instrumentations/src/router.js +1 -1
  30. package/packages/datadog-plugin-aws-sdk/src/base.js +1 -2
  31. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -2
  32. package/packages/datadog-plugin-cucumber/src/index.js +4 -0
  33. package/packages/datadog-plugin-grpc/src/client.js +2 -2
  34. package/packages/datadog-plugin-grpc/src/server.js +2 -2
  35. package/packages/datadog-plugin-http/src/client.js +1 -1
  36. package/packages/datadog-plugin-http/src/server.js +1 -1
  37. package/packages/datadog-plugin-http2/src/client.js +1 -1
  38. package/packages/datadog-plugin-jest/src/index.js +25 -4
  39. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  40. package/packages/datadog-plugin-mongodb-core/src/index.js +32 -8
  41. package/packages/datadog-plugin-oracledb/src/index.js +12 -4
  42. package/packages/datadog-plugin-restify/src/index.js +7 -0
  43. package/packages/dd-trace/index.js +1 -1
  44. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +3 -0
  45. package/packages/dd-trace/src/appsec/iast/analyzers/index.js +20 -0
  46. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +48 -0
  47. package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +24 -0
  48. package/packages/dd-trace/src/appsec/iast/iast-context.js +50 -0
  49. package/packages/dd-trace/src/appsec/iast/index.js +59 -0
  50. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +94 -0
  51. package/packages/dd-trace/src/appsec/iast/path-line.js +70 -0
  52. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +113 -0
  53. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +50 -0
  54. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +53 -8
  55. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +23 -24
  56. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +220 -0
  57. package/packages/dd-trace/src/config.js +97 -10
  58. package/packages/dd-trace/src/constants.js +9 -1
  59. package/packages/dd-trace/src/encode/0.4.js +55 -58
  60. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +13 -34
  61. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +84 -0
  62. package/packages/dd-trace/src/encode/span-stats.js +155 -0
  63. package/packages/dd-trace/src/exporters/agent/index.js +25 -7
  64. package/packages/dd-trace/src/exporters/agent/writer.js +7 -4
  65. package/packages/dd-trace/src/{profiling/exporters → exporters/common}/form-data.js +0 -0
  66. package/packages/dd-trace/src/exporters/common/request.js +69 -39
  67. package/packages/dd-trace/src/exporters/common/writer.js +16 -6
  68. package/packages/dd-trace/src/exporters/span-stats/index.js +20 -0
  69. package/packages/dd-trace/src/exporters/span-stats/writer.js +54 -0
  70. package/packages/dd-trace/src/format.js +2 -0
  71. package/packages/dd-trace/src/id.js +16 -13
  72. package/packages/dd-trace/src/iitm.js +12 -1
  73. package/packages/dd-trace/src/index.js +10 -0
  74. package/packages/dd-trace/src/noop/proxy.js +77 -0
  75. package/packages/dd-trace/src/noop/scope.js +2 -6
  76. package/packages/dd-trace/src/noop/span.js +12 -12
  77. package/packages/dd-trace/src/noop/tracer.js +8 -9
  78. package/packages/dd-trace/src/opentracing/propagation/text_map.js +77 -6
  79. package/packages/dd-trace/src/opentracing/span.js +63 -49
  80. package/packages/dd-trace/src/opentracing/span_context.js +1 -5
  81. package/packages/dd-trace/src/opentracing/tracer.js +32 -37
  82. package/packages/dd-trace/src/plugin_manager.js +111 -64
  83. package/packages/dd-trace/src/plugins/index.js +57 -45
  84. package/packages/dd-trace/src/plugins/log_plugin.js +16 -9
  85. package/packages/dd-trace/src/plugins/util/ci.js +34 -9
  86. package/packages/dd-trace/src/plugins/util/git.js +52 -2
  87. package/packages/dd-trace/src/plugins/util/ip_blocklist.js +25 -0
  88. package/packages/dd-trace/src/plugins/util/tags.js +4 -1
  89. package/packages/dd-trace/src/plugins/util/web.js +149 -6
  90. package/packages/dd-trace/src/priority_sampler.js +36 -1
  91. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  92. package/packages/dd-trace/src/profiling/profilers/cpu.js +3 -3
  93. package/packages/dd-trace/src/proxy.js +21 -90
  94. package/packages/dd-trace/src/ritm.js +10 -1
  95. package/packages/dd-trace/src/scope.js +2 -184
  96. package/packages/dd-trace/src/span_processor.js +7 -1
  97. package/packages/dd-trace/src/span_stats.js +210 -0
  98. package/packages/dd-trace/src/startup-log.js +8 -19
  99. package/packages/dd-trace/src/telemetry/dependencies.js +83 -0
  100. package/packages/dd-trace/src/{telemetry.js → telemetry/index.js} +11 -79
  101. package/packages/dd-trace/src/telemetry/send-data.js +35 -0
  102. package/packages/dd-trace/src/tracer.js +0 -4
  103. package/scripts/install_plugin_modules.js +17 -26
  104. package/ci/jest/env.js +0 -39
  105. package/cypress/plugin.js +0 -5
  106. package/cypress/support.js +0 -1
  107. package/packages/datadog-plugin-fs/src/index.js +0 -548
@@ -6,9 +6,14 @@ const ext = require('../../../ext')
6
6
  const { setSamplingRules } = require('./startup-log')
7
7
 
8
8
  const {
9
+ SAMPLING_MECHANISM_DEFAULT,
10
+ SAMPLING_MECHANISM_AGENT,
11
+ SAMPLING_MECHANISM_RULE,
12
+ SAMPLING_MECHANISM_MANUAL,
9
13
  SAMPLING_RULE_DECISION,
10
14
  SAMPLING_LIMIT_DECISION,
11
- SAMPLING_AGENT_DECISION
15
+ SAMPLING_AGENT_DECISION,
16
+ DECISION_MAKER_KEY
12
17
  } = require('./constants')
13
18
 
14
19
  const SERVICE_NAME = ext.tags.SERVICE_NAME
@@ -45,6 +50,7 @@ class PrioritySampler {
45
50
  const context = this._getContext(span)
46
51
  const root = context._trace.started[0]
47
52
 
53
+ // TODO: remove the decision maker tag when priority is less than AUTO_KEEP
48
54
  if (context._sampling.priority !== undefined) return
49
55
  if (!root) return // noop span
50
56
 
@@ -52,9 +58,14 @@ class PrioritySampler {
52
58
 
53
59
  if (this.validate(tag)) {
54
60
  context._sampling.priority = tag
61
+ context._sampling.mechanism = SAMPLING_MECHANISM_MANUAL
55
62
  } else if (auto) {
56
63
  context._sampling.priority = this._getPriorityFromAuto(root)
64
+ } else {
65
+ return
57
66
  }
67
+
68
+ this._addDecisionMaker(root)
58
69
  }
59
70
 
60
71
  update (rates) {
@@ -115,6 +126,7 @@ class PrioritySampler {
115
126
 
116
127
  _getPriorityByRule (context, rule) {
117
128
  context._trace[SAMPLING_RULE_DECISION] = rule.sampleRate
129
+ context._sampling.mechanism = SAMPLING_MECHANISM_RULE
118
130
 
119
131
  return rule.sampler.isSampled(context) && this._isSampledByRateLimit(context) ? USER_KEEP : USER_REJECT
120
132
  }
@@ -133,10 +145,33 @@ class PrioritySampler {
133
145
 
134
146
  context._trace[SAMPLING_AGENT_DECISION] = sampler.rate()
135
147
 
148
+ if (sampler === defaultSampler) {
149
+ context._sampling.mechanism = SAMPLING_MECHANISM_DEFAULT
150
+ } else {
151
+ context._sampling.mechanism = SAMPLING_MECHANISM_AGENT
152
+ }
153
+
136
154
  return sampler.isSampled(context) ? AUTO_KEEP : AUTO_REJECT
137
155
  }
138
156
 
157
+ _addDecisionMaker (span) {
158
+ const context = span.context()
159
+ const trace = context._trace
160
+ const priority = context._sampling.priority
161
+ const mechanism = context._sampling.mechanism
162
+
163
+ if (priority >= AUTO_KEEP) {
164
+ if (!trace.tags[DECISION_MAKER_KEY]) {
165
+ trace.tags[DECISION_MAKER_KEY] = `-${mechanism}`
166
+ }
167
+ } else {
168
+ delete trace.tags[DECISION_MAKER_KEY]
169
+ }
170
+ }
171
+
139
172
  _normalizeRules (rules, sampleRate) {
173
+ rules = [].concat(rules || [])
174
+
140
175
  return rules
141
176
  .concat({ sampleRate })
142
177
  .map(rule => ({ ...rule, sampleRate: parseFloat(rule.sampleRate) }))
@@ -2,10 +2,10 @@
2
2
 
3
3
  const retry = require('retry')
4
4
  const { request } = require('http')
5
- const FormData = require('./form-data')
6
5
 
7
6
  // TODO: avoid using dd-trace internals. Make this a separate module?
8
7
  const docker = require('../../exporters/common/docker')
8
+ const FormData = require('../../exporters/common/form-data')
9
9
  const version = require('../../../../../package.json').version
10
10
 
11
11
  const containerId = docker.id()
@@ -20,7 +20,7 @@ function getStartedSpans (activeSpan) {
20
20
  }
21
21
 
22
22
  function getSpanContextTags (span) {
23
- return span._context()._tags
23
+ return span.context()._tags
24
24
  }
25
25
 
26
26
  function isWebServerSpan (tags) {
@@ -55,13 +55,13 @@ class NativeCpuProfiler {
55
55
  const active = getActiveSpan()
56
56
  if (!active) return
57
57
 
58
- const activeCtx = active._context()
58
+ const activeCtx = active.context()
59
59
  if (!activeCtx) return
60
60
 
61
61
  const spans = getStartedSpans(active)
62
62
  if (!spans || !spans.length) return
63
63
 
64
- const firstCtx = spans[0]._context()
64
+ const firstCtx = spans[0].context()
65
65
  if (!firstCtx) return
66
66
 
67
67
  const labels = {
@@ -1,36 +1,25 @@
1
1
  'use strict'
2
2
 
3
- const BaseTracer = require('opentracing').Tracer
4
- const NoopTracer = require('./noop/tracer')
3
+ const NoopProxy = require('./noop/proxy')
5
4
  const DatadogTracer = require('./tracer')
6
5
  const Config = require('./config')
7
- const Instrumenter = require('./instrumenter')
8
- const PluginManager = require('./plugin_manager')
9
6
  const metrics = require('./metrics')
10
7
  const log = require('./log')
11
- const { isFalse } = require('./util')
12
- const { setStartupLogInstrumenter } = require('./startup-log')
8
+ const { setStartupLogPluginManager } = require('./startup-log')
13
9
  const telemetry = require('./telemetry')
10
+ const PluginManager = require('./plugin_manager')
11
+ const { sendGitMetadata } = require('./ci-visibility/exporters/git/git_metadata')
14
12
 
15
- const noop = new NoopTracer()
16
-
17
- class Tracer extends BaseTracer {
13
+ class Tracer extends NoopProxy {
18
14
  constructor () {
19
15
  super()
20
16
 
21
17
  this._initialized = false
22
- this._tracer = noop
23
- this._instrumenter = new Instrumenter(this)
24
18
  this._pluginManager = new PluginManager(this)
25
- this._deprecate = method => log.deprecate(`tracer.${method}`, [
26
- `tracer.${method}() is deprecated.`,
27
- 'Please use tracer.startSpan() and tracer.scope() instead.',
28
- 'See: https://datadog.github.io/dd-trace-js/#manual-instrumentation.'
29
- ].join(' '))
30
19
  }
31
20
 
32
21
  init (options) {
33
- if (isFalse(process.env.DD_TRACE_ENABLED) || this._initialized) return this
22
+ if (this._initialized) return this
34
23
 
35
24
  this._initialized = true
36
25
 
@@ -59,12 +48,24 @@ class Tracer extends BaseTracer {
59
48
  if (config.appsec.enabled) {
60
49
  require('./appsec').enable(config)
61
50
  }
51
+ if (config.iast.enabled) {
52
+ require('./appsec/iast').enable(config)
53
+ }
62
54
 
63
55
  this._tracer = new DatadogTracer(config)
64
- this._instrumenter.enable(config)
65
56
  this._pluginManager.configure(config)
66
- setStartupLogInstrumenter(this._instrumenter)
67
- telemetry.start(config, this._instrumenter, this._pluginManager)
57
+ setStartupLogPluginManager(this._pluginManager)
58
+ telemetry.start(config, this._pluginManager)
59
+ }
60
+
61
+ if (config.isGitUploadEnabled) {
62
+ sendGitMetadata(config.site, (err) => {
63
+ if (err) {
64
+ log.error(`Error uploading git metadata: ${err}`)
65
+ } else {
66
+ log.debug('Successfully uploaded git metadata')
67
+ }
68
+ })
68
69
  }
69
70
  } catch (e) {
70
71
  log.error(e)
@@ -74,79 +75,9 @@ class Tracer extends BaseTracer {
74
75
  }
75
76
 
76
77
  use () {
77
- this._instrumenter.use(...arguments)
78
78
  this._pluginManager.configurePlugin(...arguments)
79
79
  return this
80
80
  }
81
-
82
- trace (name, options, fn) {
83
- if (!fn) {
84
- fn = options
85
- options = {}
86
- }
87
-
88
- if (typeof fn !== 'function') return
89
-
90
- options = options || {}
91
-
92
- return this._tracer.trace(name, options, fn)
93
- }
94
-
95
- wrap (name, options, fn) {
96
- if (!fn) {
97
- fn = options
98
- options = {}
99
- }
100
-
101
- if (typeof fn !== 'function') return fn
102
-
103
- options = options || {}
104
-
105
- return this._tracer.wrap(name, options, fn)
106
- }
107
-
108
- setUrl () {
109
- this._tracer.setUrl.apply(this._tracer, arguments)
110
- return this
111
- }
112
-
113
- startSpan () {
114
- return this._tracer.startSpan.apply(this._tracer, arguments)
115
- }
116
-
117
- inject () {
118
- return this._tracer.inject.apply(this._tracer, arguments)
119
- }
120
-
121
- extract () {
122
- return this._tracer.extract.apply(this._tracer, arguments)
123
- }
124
-
125
- scope () {
126
- return this._tracer.scope.apply(this._tracer, arguments)
127
- }
128
-
129
- currentSpan () {
130
- this._deprecate('currentSpan')
131
- return this._tracer.currentSpan.apply(this._tracer, arguments)
132
- }
133
-
134
- bind (callback) {
135
- this._deprecate('bind')
136
- return callback
137
- }
138
-
139
- bindEmitter () {
140
- this._deprecate('bindEmitter')
141
- }
142
-
143
- getRumData () {
144
- return this._tracer.getRumData.apply(this._tracer, arguments)
145
- }
146
-
147
- setUser () {
148
- return this._tracer.setUser.apply(this.tracer, arguments)
149
- }
150
81
  }
151
82
 
152
83
  module.exports = Tracer
@@ -3,6 +3,7 @@
3
3
  const path = require('path')
4
4
  const Module = require('module')
5
5
  const parse = require('module-details-from-path')
6
+ const dc = require('diagnostics_channel')
6
7
 
7
8
  const origRequire = Module.prototype.require
8
9
 
@@ -14,7 +15,7 @@ let moduleHooks = Object.create(null)
14
15
  let cache = Object.create(null)
15
16
  let patching = Object.create(null)
16
17
  let patchedRequire = null
17
-
18
+ const moduleLoadStartChannel = dc.channel('dd-trace:moduleLoadStart')
18
19
  function Hook (modules, options, onrequire) {
19
20
  if (!(this instanceof Hook)) return new Hook(modules, options, onrequire)
20
21
  if (typeof modules === 'function') {
@@ -78,6 +79,14 @@ function Hook (modules, options, onrequire) {
78
79
  // so the patching mark can be cleaned up.
79
80
  delete patching[filename]
80
81
 
82
+ if (moduleLoadStartChannel.hasSubscribers) {
83
+ moduleLoadStartChannel.publish({
84
+ filename,
85
+ module: exports,
86
+ request
87
+ })
88
+ }
89
+
81
90
  if (core) {
82
91
  hooks = moduleHooks[filename]
83
92
  if (!hooks) return exports // abort if module name isn't on whitelist
@@ -2,13 +2,9 @@
2
2
 
3
3
  const { storage } = require('../../datadog-core')
4
4
 
5
- // TODO: deprecate binding event emitters in 3.0
5
+ // TODO: refactor bind to use shimmer once the new internal tracer lands
6
6
 
7
7
  const originals = new WeakMap()
8
- const listenerMaps = new WeakMap()
9
- const emitterSpans = new WeakMap()
10
- const emitterScopes = new WeakMap()
11
- const emitters = new WeakSet()
12
8
 
13
9
  class Scope {
14
10
  active () {
@@ -38,23 +34,7 @@ class Scope {
38
34
  }
39
35
  }
40
36
 
41
- bind (target, span) {
42
- target = this._bindEmitter(target, span)
43
- target = this._bindPromise(target, span)
44
- target = this._bindFn(target, span)
45
-
46
- return target
47
- }
48
-
49
- unbind (target) {
50
- target = this._unbindFn(target)
51
- target = this._unbindPromise(target)
52
- target = this._unbindEmitter(target)
53
-
54
- return target
55
- }
56
-
57
- _bindFn (fn, span) {
37
+ bind (fn, span) {
58
38
  if (typeof fn !== 'function') return fn
59
39
 
60
40
  const scope = this
@@ -71,175 +51,13 @@ class Scope {
71
51
  return bound
72
52
  }
73
53
 
74
- _unbindFn (fn) {
75
- if (typeof fn !== 'function') return fn
76
-
77
- return originals.get(fn) || fn
78
- }
79
-
80
- _bindEmitter (emitter, span) {
81
- if (!this._isEmitter(emitter)) return emitter
82
- if (!emitters.has(emitter)) {
83
- Scope._wrapEmitter(emitter)
84
- }
85
- emitterSpans.set(emitter, span)
86
- emitterScopes.set(emitter, this)
87
- return emitter
88
- }
89
-
90
- // Occasionally we want to wrap a prototype rather than emitter instances,
91
- // so we're exposing this as a static method. This gives us a faster
92
- // path for binding instances of known EventEmitter subclasses.
93
- static _wrapEmitter (emitter) {
94
- wrapMethod(emitter, 'addListener', wrapAddListener)
95
- wrapMethod(emitter, 'prependListener', wrapAddListener)
96
- wrapMethod(emitter, 'on', wrapAddListener)
97
- wrapMethod(emitter, 'once', wrapAddListener)
98
- wrapMethod(emitter, 'removeListener', wrapRemoveListener)
99
- wrapMethod(emitter, 'off', wrapRemoveListener)
100
- wrapMethod(emitter, 'removeAllListeners', wrapRemoveAllListeners)
101
- emitters.add(emitter)
102
- }
103
-
104
- _unbindEmitter (emitter) {
105
- if (!this._isEmitter(emitter)) return emitter
106
- emitterScopes.delete(emitter)
107
- emitterSpans.delete(emitter)
108
- return emitter
109
- }
110
-
111
- _bindPromise (promise, span) {
112
- if (!this._isPromise(promise)) return promise
113
-
114
- wrapMethod(promise, 'then', wrapThen, this, span)
115
-
116
- return promise
117
- }
118
-
119
- _unbindPromise (promise) {
120
- if (!this._isPromise(promise)) return promise
121
-
122
- promise.then = originals.get(promise.then) || promise.then
123
-
124
- return promise
125
- }
126
-
127
54
  _spanOrActive (span) {
128
55
  return span !== undefined ? span : this.active()
129
56
  }
130
57
 
131
- _isEmitter (emitter) {
132
- return emitter &&
133
- typeof emitter.emit === 'function' &&
134
- typeof emitter.on === 'function' &&
135
- typeof emitter.addListener === 'function' &&
136
- typeof emitter.removeListener === 'function'
137
- }
138
-
139
58
  _isPromise (promise) {
140
59
  return promise && typeof promise.then === 'function'
141
60
  }
142
61
  }
143
62
 
144
- function getScope (emitter) {
145
- return emitterScopes.get(emitter) || emitterScopes.get(emitter.constructor.prototype)
146
- }
147
-
148
- function getSpan (emitter) {
149
- return emitterSpans.get(emitter) || emitterSpans.get(emitter.constructor.prototype)
150
- }
151
-
152
- function hasScope (emitter) {
153
- return emitterScopes.has(emitter) || emitterScopes.has(emitter.constructor.prototype)
154
- }
155
-
156
- function wrapThen (then, scope, span) {
157
- return function thenWithTrace (onFulfilled, onRejected) {
158
- const args = new Array(arguments.length)
159
-
160
- for (let i = 0, l = args.length; i < l; i++) {
161
- args[i] = scope.bind(arguments[i], span)
162
- }
163
-
164
- return then.apply(this, args)
165
- }
166
- }
167
-
168
- function wrapAddListener (addListener) {
169
- return function addListenerWithTrace (eventName, listener) {
170
- const scope = getScope(this)
171
- if (!scope || !listener || originals.has(listener) || listener.listener) {
172
- return addListener.apply(this, arguments)
173
- }
174
- const span = getSpan(this)
175
-
176
- const bound = scope.bind(listener, scope._spanOrActive(span))
177
- const listenerMap = listenerMaps.get(this) || {}
178
-
179
- listenerMaps.set(this, listenerMap)
180
-
181
- if (!listenerMap[eventName]) {
182
- listenerMap[eventName] = new WeakMap()
183
- }
184
-
185
- const events = listenerMap[eventName]
186
-
187
- if (!events.has(listener)) {
188
- events.set(listener, [])
189
- }
190
-
191
- events.get(listener).push(bound)
192
-
193
- return addListener.call(this, eventName, bound)
194
- }
195
- }
196
-
197
- function wrapRemoveListener (removeListener) {
198
- return function removeListenerWithTrace (eventName, listener) {
199
- if (!hasScope(this)) {
200
- return removeListener.apply(this, arguments)
201
- }
202
-
203
- const listenerMap = listenerMaps.get(this)
204
- const listeners = listenerMap && listenerMap[eventName]
205
-
206
- if (!listener || !listeners || !listeners.has(listener)) {
207
- return removeListener.apply(this, arguments)
208
- }
209
-
210
- for (const bound of listeners.get(listener)) {
211
- removeListener.call(this, eventName, bound)
212
- }
213
-
214
- listeners.delete(listener)
215
-
216
- return removeListener.apply(this, arguments)
217
- }
218
- }
219
-
220
- function wrapRemoveAllListeners (removeAllListeners) {
221
- return function removeAllListenersWithTrace (eventName) {
222
- const listenerMap = listenerMaps.get(this)
223
-
224
- if (hasScope(this) && listenerMap) {
225
- if (eventName) {
226
- delete listenerMap[eventName]
227
- } else {
228
- listenerMaps.delete(this)
229
- }
230
- }
231
-
232
- return removeAllListeners.apply(this, arguments)
233
- }
234
- }
235
-
236
- function wrapMethod (target, name, wrapper, ...args) {
237
- if (!target[name] || originals.has(target[name])) return
238
-
239
- const original = target[name]
240
-
241
- target[name] = wrapper(target[name], ...args)
242
- originals.set(target[name], original)
243
- }
244
-
245
63
  module.exports = Scope
@@ -3,6 +3,8 @@
3
3
  const log = require('./log')
4
4
  const format = require('./format')
5
5
 
6
+ const { SpanStatsProcessor } = require('./span_stats')
7
+
6
8
  const startedSpans = new WeakSet()
7
9
  const finishedSpans = new WeakSet()
8
10
 
@@ -11,6 +13,8 @@ class SpanProcessor {
11
13
  this._exporter = exporter
12
14
  this._prioritySampler = prioritySampler
13
15
  this._config = config
16
+
17
+ this._stats = new SpanStatsProcessor(config)
14
18
  }
15
19
 
16
20
  process (span) {
@@ -26,7 +30,9 @@ class SpanProcessor {
26
30
 
27
31
  for (const span of started) {
28
32
  if (span._duration !== undefined) {
29
- formatted.push(format(span))
33
+ const formattedSpan = format(span)
34
+ this._stats.onSpanFinished(formattedSpan)
35
+ formatted.push(formattedSpan)
30
36
  } else {
31
37
  active.push(span)
32
38
  }