dd-trace 2.4.2 → 2.7.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 (96) hide show
  1. package/LICENSE-3rdparty.csv +1 -2
  2. package/ci/init.js +6 -0
  3. package/ci/jest/env.js +16 -3
  4. package/ext/exporters.d.ts +2 -1
  5. package/ext/exporters.js +2 -1
  6. package/index.d.ts +17 -8
  7. package/package.json +20 -23
  8. package/packages/datadog-instrumentations/index.js +14 -0
  9. package/packages/datadog-instrumentations/src/connect.js +111 -0
  10. package/packages/datadog-instrumentations/src/cypress.js +8 -0
  11. package/packages/datadog-instrumentations/src/express.js +27 -0
  12. package/packages/datadog-instrumentations/src/fastify.js +187 -0
  13. package/packages/datadog-instrumentations/src/find-my-way.js +30 -0
  14. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +100 -0
  15. package/packages/datadog-instrumentations/src/http/server.js +1 -1
  16. package/packages/datadog-instrumentations/src/jest.js +175 -0
  17. package/packages/datadog-instrumentations/src/kafkajs.js +112 -0
  18. package/packages/datadog-instrumentations/src/knex.js +20 -0
  19. package/packages/datadog-instrumentations/src/koa.js +159 -0
  20. package/packages/datadog-instrumentations/src/limitd-client.js +21 -0
  21. package/packages/datadog-instrumentations/src/oracledb.js +128 -0
  22. package/packages/datadog-instrumentations/src/paperplane.js +77 -0
  23. package/packages/datadog-instrumentations/src/pg.js +2 -2
  24. package/packages/datadog-instrumentations/src/restify.js +58 -0
  25. package/packages/datadog-instrumentations/src/rhea.js +1 -1
  26. package/packages/datadog-instrumentations/src/router.js +177 -0
  27. package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -4
  28. package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
  29. package/packages/datadog-plugin-connect/src/index.js +10 -114
  30. package/packages/datadog-plugin-cucumber/src/index.js +16 -16
  31. package/packages/datadog-plugin-cypress/src/index.js +10 -5
  32. package/packages/datadog-plugin-cypress/src/plugin.js +18 -17
  33. package/packages/datadog-plugin-dns/src/index.js +12 -1
  34. package/packages/datadog-plugin-express/src/index.js +11 -25
  35. package/packages/datadog-plugin-fastify/src/index.js +17 -4
  36. package/packages/datadog-plugin-find-my-way/src/index.js +20 -0
  37. package/packages/datadog-plugin-fs/src/index.js +2 -0
  38. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +56 -111
  39. package/packages/datadog-plugin-http/src/server.js +2 -10
  40. package/packages/datadog-plugin-jest/src/index.js +101 -3
  41. package/packages/datadog-plugin-jest/src/util.js +1 -29
  42. package/packages/datadog-plugin-kafkajs/src/index.js +64 -90
  43. package/packages/datadog-plugin-koa/src/index.js +12 -164
  44. package/packages/datadog-plugin-mocha/src/index.js +14 -15
  45. package/packages/datadog-plugin-oracledb/src/index.js +34 -100
  46. package/packages/datadog-plugin-paperplane/src/index.js +14 -100
  47. package/packages/datadog-plugin-paperplane/src/logger.js +11 -0
  48. package/packages/datadog-plugin-paperplane/src/server.js +24 -0
  49. package/packages/datadog-plugin-restify/src/index.js +13 -75
  50. package/packages/datadog-plugin-router/src/index.js +67 -164
  51. package/packages/datadog-plugin-web/src/index.js +20 -0
  52. package/packages/dd-trace/lib/version.js +1 -1
  53. package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +34 -12
  54. package/packages/dd-trace/src/appsec/index.js +7 -3
  55. package/packages/dd-trace/src/appsec/recommended.json +15 -5
  56. package/packages/dd-trace/src/appsec/reporter.js +33 -3
  57. package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
  58. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +32 -0
  59. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +51 -0
  60. package/packages/dd-trace/src/config.js +33 -4
  61. package/packages/dd-trace/src/encode/0.4.js +0 -1
  62. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +193 -0
  63. package/packages/dd-trace/src/encode/tags-processors.js +116 -0
  64. package/packages/dd-trace/src/exporter.js +3 -0
  65. package/packages/dd-trace/src/exporters/agent/index.js +1 -1
  66. package/packages/dd-trace/src/exporters/agent/writer.js +7 -32
  67. package/packages/dd-trace/src/exporters/{agent → common}/docker.js +0 -0
  68. package/packages/dd-trace/src/exporters/common/request.js +83 -0
  69. package/packages/dd-trace/src/exporters/common/writer.js +36 -0
  70. package/packages/dd-trace/src/exporters/{agent/scheduler.js → scheduler.js} +0 -0
  71. package/packages/dd-trace/src/format.js +9 -5
  72. package/packages/dd-trace/src/instrumenter.js +3 -0
  73. package/packages/dd-trace/src/pkg.js +11 -6
  74. package/packages/dd-trace/src/plugin_manager.js +13 -7
  75. package/packages/dd-trace/src/plugins/index.js +1 -2
  76. package/packages/dd-trace/src/plugins/log_plugin.js +8 -4
  77. package/packages/dd-trace/src/plugins/plugin.js +8 -0
  78. package/packages/dd-trace/src/plugins/util/test.js +79 -1
  79. package/packages/dd-trace/src/plugins/util/web.js +41 -12
  80. package/packages/dd-trace/src/profiling/config.js +8 -8
  81. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  82. package/packages/dd-trace/src/profiling/index.js +4 -4
  83. package/packages/dd-trace/src/profiling/profilers/{heap.js → space.js} +2 -2
  84. package/packages/dd-trace/src/profiling/profilers/{cpu.js → wall.js} +3 -3
  85. package/packages/dd-trace/src/proxy.js +2 -0
  86. package/packages/dd-trace/src/span_processor.js +4 -1
  87. package/packages/dd-trace/src/telemetry.js +187 -0
  88. package/scripts/install_plugin_modules.js +1 -0
  89. package/packages/datadog-plugin-fastify/src/fastify.js +0 -198
  90. package/packages/datadog-plugin-fastify/src/find-my-way.js +0 -37
  91. package/packages/datadog-plugin-jest/src/jest-environment.js +0 -272
  92. package/packages/datadog-plugin-jest/src/jest-jasmine2.js +0 -185
  93. package/packages/datadog-plugin-knex/src/index.js +0 -23
  94. package/packages/datadog-plugin-limitd-client/src/index.js +0 -30
  95. package/packages/dd-trace/src/exporters/agent/request.js +0 -86
  96. package/scripts/postpublish.js +0 -24
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- class NativeHeapProfiler {
3
+ class NativeSpaceProfiler {
4
4
  constructor (options = {}) {
5
5
  this.type = 'space'
6
6
  this._samplingInterval = options.samplingInterval || 512 * 1024
@@ -27,4 +27,4 @@ class NativeHeapProfiler {
27
27
  }
28
28
  }
29
29
 
30
- module.exports = NativeHeapProfiler
30
+ module.exports = NativeSpaceProfiler
@@ -1,9 +1,9 @@
1
1
  'use strict'
2
2
 
3
- class NativeCpuProfiler {
3
+ class NativeWallProfiler {
4
4
  constructor (options = {}) {
5
5
  this.type = 'wall'
6
- this._samplingInterval = options.samplingInterval || 10 * 1000
6
+ this._samplingInterval = options.samplingInterval || 1e6 / 99 // 99hz
7
7
  this._mapper = undefined
8
8
  this._pprof = undefined
9
9
  }
@@ -43,4 +43,4 @@ class NativeCpuProfiler {
43
43
  }
44
44
  }
45
45
 
46
- module.exports = NativeCpuProfiler
46
+ module.exports = NativeWallProfiler
@@ -10,6 +10,7 @@ const metrics = require('./metrics')
10
10
  const log = require('./log')
11
11
  const { isFalse } = require('./util')
12
12
  const { setStartupLogInstrumenter } = require('./startup-log')
13
+ const telemetry = require('./telemetry')
13
14
 
14
15
  const noop = new NoopTracer()
15
16
 
@@ -63,6 +64,7 @@ class Tracer extends BaseTracer {
63
64
  this._instrumenter.enable(config)
64
65
  this._pluginManager.configure(config)
65
66
  setStartupLogInstrumenter(this._instrumenter)
67
+ telemetry.start(config, this._instrumenter, this._pluginManager)
66
68
  }
67
69
  } catch (e) {
68
70
  log.error(e)
@@ -32,7 +32,10 @@ class SpanProcessor {
32
32
  }
33
33
  }
34
34
 
35
- this._exporter.export(formatted)
35
+ if (formatted.length !== 0 && trace.isRecording !== false) {
36
+ this._exporter.export(formatted)
37
+ }
38
+
36
39
  this._erase(trace, active)
37
40
  }
38
41
  }
@@ -0,0 +1,187 @@
1
+ 'use strict'
2
+
3
+ const tracerVersion = require('../lib/version')
4
+ const pkg = require('./pkg')
5
+ const containerId = require('./exporters/common/docker').id()
6
+ const requirePackageJson = require('./require-package-json')
7
+ const path = require('path')
8
+ const os = require('os')
9
+ const request = require('./exporters/common/request')
10
+
11
+ let config
12
+ let instrumenter
13
+ let pluginManager
14
+
15
+ let seqId = 0
16
+ let application
17
+ let host
18
+ let interval
19
+ const sentIntegrations = new Set()
20
+
21
+ function getIntegrations () {
22
+ const newIntegrations = []
23
+ for (const plugin of instrumenter._instrumented.keys()) {
24
+ if (sentIntegrations.has(plugin.name)) {
25
+ continue
26
+ }
27
+ newIntegrations.push({
28
+ name: plugin.name,
29
+ enabled: true,
30
+ auto_enabled: true
31
+ })
32
+ sentIntegrations.add(plugin.name)
33
+ }
34
+ for (const pluginName in pluginManager._pluginsByName) {
35
+ if (sentIntegrations.has(pluginName)) {
36
+ continue
37
+ }
38
+ newIntegrations.push({
39
+ name: pluginName,
40
+ enabled: pluginManager._pluginsByName[pluginName]._enabled,
41
+ auto_enabled: true
42
+ })
43
+ sentIntegrations.add(pluginName)
44
+ }
45
+ return newIntegrations
46
+ }
47
+
48
+ function getDependencies () {
49
+ const deps = []
50
+ const { dependencies } = pkg
51
+ if (!dependencies) {
52
+ return deps
53
+ }
54
+ const rootDir = pkg.findRoot()
55
+ for (const [name, version] of Object.entries(dependencies)) {
56
+ const dep = { name }
57
+ try {
58
+ dep.version = requirePackageJson(
59
+ path.join(rootDir, 'node_modules', name.replace('/', path.sep))
60
+ ).version
61
+ } catch (e) {
62
+ dep.version = version
63
+ }
64
+ deps.push(dep)
65
+ }
66
+ return deps
67
+ }
68
+
69
+ function flatten (input, result = [], prefix = [], traversedObjects = null) {
70
+ traversedObjects = traversedObjects || new WeakSet()
71
+ if (traversedObjects.has(input)) {
72
+ return
73
+ }
74
+ traversedObjects.add(input)
75
+ for (const [key, value] of Object.entries(input)) {
76
+ if (typeof value === 'object' && value !== null) {
77
+ flatten(value, result, [...prefix, key], traversedObjects)
78
+ } else {
79
+ result.push({ name: [...prefix, key].join('.'), value })
80
+ }
81
+ }
82
+ return result
83
+ }
84
+
85
+ function appStarted () {
86
+ return {
87
+ integrations: getIntegrations(),
88
+ dependencies: getDependencies(),
89
+ configuration: flatten(config),
90
+ additional_payload: []
91
+ }
92
+ }
93
+
94
+ function onBeforeExit () {
95
+ process.removeListener('beforeExit', onBeforeExit)
96
+ sendData('app-closing')
97
+ }
98
+
99
+ function createAppObject () {
100
+ return {
101
+ service_name: config.service,
102
+ env: config.env,
103
+ service_version: config.version,
104
+ tracer_version: tracerVersion,
105
+ language_name: 'nodejs',
106
+ language_version: process.versions.node
107
+ }
108
+ }
109
+
110
+ function createHostObject () {
111
+ return {
112
+ hostname: os.hostname(), // TODO is this enough?
113
+ container_id: containerId
114
+ }
115
+ }
116
+
117
+ function sendData (reqType, payload = {}) {
118
+ const {
119
+ hostname,
120
+ port
121
+ } = config
122
+ const options = {
123
+ hostname,
124
+ port,
125
+ method: 'POST',
126
+ path: '/telemetry/proxy/api/v2/apmtelemetry',
127
+ headers: {
128
+ 'content-type': 'application/json',
129
+ 'dd-telemetry-api-version': 'v1',
130
+ 'dd-telemetry-request-type': reqType
131
+ }
132
+ }
133
+ const data = JSON.stringify({
134
+ api_version: 'v1',
135
+ request_type: reqType,
136
+ tracer_time: Math.floor(Date.now() / 1000),
137
+ runtime_id: config.tags['runtime-id'],
138
+ seq_id: ++seqId,
139
+ payload,
140
+ application,
141
+ host
142
+ })
143
+
144
+ request(data, options, true, () => {
145
+ // ignore errors
146
+ })
147
+ }
148
+
149
+ function start (aConfig, theInstrumenter, thePluginManager) {
150
+ if (!aConfig.telemetryEnabled) {
151
+ return
152
+ }
153
+ config = aConfig
154
+ instrumenter = theInstrumenter
155
+ pluginManager = thePluginManager
156
+ application = createAppObject()
157
+ host = createHostObject()
158
+ sendData('app-started', appStarted())
159
+ interval = setInterval(() => sendData('app-heartbeat'), 60000)
160
+ interval.unref()
161
+ process.on('beforeExit', onBeforeExit)
162
+ }
163
+
164
+ function stop () {
165
+ if (!config) {
166
+ return
167
+ }
168
+ clearInterval(interval)
169
+ process.removeListener('beforeExit', onBeforeExit)
170
+ }
171
+
172
+ function updateIntegrations () {
173
+ if (!config || !config.telemetryEnabled) {
174
+ return
175
+ }
176
+ const integrations = getIntegrations()
177
+ if (integrations.length === 0) {
178
+ return
179
+ }
180
+ sendData('app-integrations-change', { integrations })
181
+ }
182
+
183
+ module.exports = {
184
+ start,
185
+ stop,
186
+ updateIntegrations
187
+ }
@@ -186,6 +186,7 @@ const requirePackageJson = require('${requirePackageJsonPath}')
186
186
 
187
187
  module.exports = {
188
188
  get (id) { return require(id || '${name}') },
189
+ getPath (id) { return require.resolve(id || '${name}' ) },
189
190
  version () { return requirePackageJson('${name}', module).version }
190
191
  }
191
192
  `
@@ -1,198 +0,0 @@
1
- 'use strict'
2
-
3
- const methods = require('methods').concat('all')
4
- const web = require('../../dd-trace/src/plugins/util/web')
5
-
6
- function createWrapFastify (tracer, config) {
7
- config = web.normalizeConfig(config)
8
-
9
- return function wrapFastify (fastify) {
10
- if (typeof fastify !== 'function') return fastify
11
-
12
- return function fastifyWithTrace () {
13
- const app = fastify.apply(this, arguments)
14
-
15
- if (!app) return app
16
-
17
- if (typeof app.addHook === 'function') {
18
- app.addHook('onRequest', createOnRequest(tracer, config))
19
- app.addHook('preHandler', preHandler)
20
- app.addHook = createWrapAddHook(tracer, config)(app.addHook)
21
- }
22
-
23
- methods.forEach(method => {
24
- app[method] = wrapMethod(app[method])
25
- })
26
-
27
- app.route = wrapRoute(app.route)
28
-
29
- return app
30
- }
31
- }
32
- }
33
-
34
- function createWrapAddHook (tracer, config) {
35
- return function wrapAddHook (addHook) {
36
- return function addHookWithTrace (name, fn) {
37
- fn = arguments[arguments.length - 1]
38
-
39
- if (typeof fn !== 'function') return addHook.apply(this, arguments)
40
-
41
- arguments[arguments.length - 1] = safeWrap(fn, function (request, reply, done) {
42
- const req = getReq(request)
43
-
44
- if (!req) return fn.apply(this, arguments)
45
-
46
- done = arguments[arguments.length - 1]
47
-
48
- try {
49
- if (typeof done === 'function') {
50
- arguments[arguments.length - 1] = function (err) {
51
- web.addError(req, err)
52
- return done.apply(this, arguments)
53
- }
54
-
55
- return fn.apply(this, arguments)
56
- } else {
57
- const promise = fn.apply(this, arguments)
58
-
59
- if (promise && typeof promise.catch === 'function') {
60
- return promise.catch(err => {
61
- web.addError(req, err)
62
- throw err
63
- })
64
- }
65
-
66
- return promise
67
- }
68
- } catch (e) {
69
- web.addError(req, e)
70
- throw e
71
- }
72
- })
73
-
74
- return addHook.apply(this, arguments)
75
- }
76
- }
77
- }
78
-
79
- function createOnRequest (tracer, config) {
80
- return function onRequest (request, reply, next) {
81
- if (typeof next !== 'function') return
82
-
83
- const req = getReq(request)
84
- const res = getRes(reply)
85
- const name = 'fastify.request'
86
-
87
- return web.instrument(tracer, config, req, res, name, () => next())
88
- }
89
- }
90
-
91
- function preHandler (request, reply, next) {
92
- if (typeof next !== 'function') return
93
- if (!reply || typeof reply.send !== 'function') return next()
94
-
95
- reply.send = wrapSend(reply.send)
96
-
97
- next()
98
- }
99
-
100
- function wrapSend (send) {
101
- return function sendWithTrace (payload) {
102
- const req = getReq(this && this.request)
103
-
104
- web.addError(req, payload)
105
-
106
- return send.apply(this, arguments)
107
- }
108
- }
109
-
110
- function wrapRoute (route) {
111
- if (typeof route !== 'function') return route
112
-
113
- return function routeWithTrace (opts) {
114
- opts.handler = wrapHandler(opts.handler)
115
-
116
- return route.apply(this, arguments)
117
- }
118
- }
119
-
120
- function wrapMethod (method) {
121
- if (typeof method !== 'function') return method
122
-
123
- return function methodWithTrace (url, opts, handler) {
124
- const lastIndex = arguments.length - 1
125
-
126
- handler = arguments[lastIndex]
127
-
128
- if (typeof handler === 'function') {
129
- arguments[lastIndex] = wrapHandler(handler)
130
- } else if (handler) {
131
- arguments[lastIndex].handler = wrapHandler(handler.handler)
132
- }
133
-
134
- return method.apply(this, arguments)
135
- }
136
- }
137
-
138
- function wrapHandler (handler) {
139
- if (!handler || typeof handler !== 'function' || handler.name === 'handlerWithTrace') {
140
- return handler
141
- }
142
-
143
- return function handlerWithTrace (request, reply) {
144
- const req = getReq(request)
145
-
146
- return web.reactivate(req, () => handler.apply(this, arguments))
147
- }
148
- }
149
-
150
- // TODO: move this to a common util
151
- function safeWrap (fn, wrapper) {
152
- Object.defineProperty(wrapper, 'length', Object.getOwnPropertyDescriptor(fn, 'length'))
153
-
154
- return wrapper
155
- }
156
-
157
- function getReq (request) {
158
- return request && (request.raw || request.req || request)
159
- }
160
-
161
- function getRes (reply) {
162
- return reply && (reply.raw || reply.res || reply)
163
- }
164
-
165
- module.exports = [
166
- {
167
- name: 'fastify',
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'],
190
- patch (fastify, tracer, config) {
191
- // `fastify` is a function so we return a wrapper that will replace its export.
192
- return this.wrapExport(fastify, createWrapFastify(tracer, config)(fastify))
193
- },
194
- unpatch (fastify) {
195
- this.unwrapExport(fastify)
196
- }
197
- }
198
- ]
@@ -1,37 +0,0 @@
1
- 'use strict'
2
-
3
- const web = require('../../dd-trace/src/plugins/util/web')
4
-
5
- function createWrapOn () {
6
- return function wrapOn (on) {
7
- return function onWithTrace (method, path, opts) {
8
- const index = typeof opts === 'function' ? 2 : 3
9
- const handler = arguments[index]
10
- const wrapper = function (req) {
11
- web.patch(req)
12
- web.enterRoute(req, path)
13
-
14
- return handler.apply(this, arguments)
15
- }
16
-
17
- if (typeof handler === 'function') {
18
- arguments[index] = wrapper
19
- }
20
-
21
- return on.apply(this, arguments)
22
- }
23
- }
24
- }
25
-
26
- module.exports = [
27
- {
28
- name: 'find-my-way',
29
- versions: ['>=1'],
30
- patch (Router, tracer, config) {
31
- this.wrap(Router.prototype, 'on', createWrapOn(tracer, config))
32
- },
33
- unpatch (Router) {
34
- this.unwrap(Router.prototype, 'on')
35
- }
36
- }
37
- ]