dd-trace 5.14.1 → 5.16.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 (73) hide show
  1. package/LICENSE-3rdparty.csv +0 -3
  2. package/README.md +8 -18
  3. package/ci/init.js +7 -0
  4. package/ext/exporters.d.ts +1 -0
  5. package/ext/exporters.js +2 -1
  6. package/ext/tags.d.ts +1 -0
  7. package/ext/tags.js +1 -0
  8. package/index.d.ts +18 -3
  9. package/initialize.mjs +52 -0
  10. package/package.json +9 -12
  11. package/packages/datadog-instrumentations/src/amqplib.js +5 -2
  12. package/packages/datadog-instrumentations/src/apollo-server-core.js +0 -1
  13. package/packages/datadog-instrumentations/src/apollo-server.js +0 -1
  14. package/packages/datadog-instrumentations/src/body-parser.js +0 -1
  15. package/packages/datadog-instrumentations/src/check_require_cache.js +67 -5
  16. package/packages/datadog-instrumentations/src/cookie-parser.js +0 -1
  17. package/packages/datadog-instrumentations/src/express.js +0 -1
  18. package/packages/datadog-instrumentations/src/graphql.js +0 -2
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  20. package/packages/datadog-instrumentations/src/helpers/register.js +5 -2
  21. package/packages/datadog-instrumentations/src/http/server.js +0 -1
  22. package/packages/datadog-instrumentations/src/jest.js +6 -3
  23. package/packages/datadog-instrumentations/src/mocha/common.js +48 -0
  24. package/packages/datadog-instrumentations/src/mocha/main.js +487 -0
  25. package/packages/datadog-instrumentations/src/mocha/utils.js +306 -0
  26. package/packages/datadog-instrumentations/src/mocha/worker.js +51 -0
  27. package/packages/datadog-instrumentations/src/mocha.js +4 -673
  28. package/packages/datadog-instrumentations/src/openai.js +188 -17
  29. package/packages/datadog-instrumentations/src/playwright.js +4 -3
  30. package/packages/datadog-instrumentations/src/router.js +1 -1
  31. package/packages/datadog-instrumentations/src/selenium.js +13 -6
  32. package/packages/datadog-plugin-graphql/src/resolve.js +4 -0
  33. package/packages/datadog-plugin-mocha/src/index.js +82 -8
  34. package/packages/datadog-plugin-next/src/index.js +1 -2
  35. package/packages/datadog-plugin-openai/src/index.js +219 -73
  36. package/packages/dd-trace/src/appsec/addresses.js +4 -2
  37. package/packages/dd-trace/src/appsec/blocking.js +19 -25
  38. package/packages/dd-trace/src/appsec/channels.js +2 -1
  39. package/packages/dd-trace/src/appsec/graphql.js +10 -3
  40. package/packages/dd-trace/src/appsec/index.js +11 -4
  41. package/packages/dd-trace/src/appsec/rasp.js +35 -0
  42. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
  43. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -0
  44. package/packages/dd-trace/src/appsec/rule_manager.js +15 -25
  45. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -5
  46. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +3 -1
  47. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -1
  48. package/packages/dd-trace/src/config.js +97 -22
  49. package/packages/dd-trace/src/constants.js +2 -0
  50. package/packages/dd-trace/src/encode/0.4.js +47 -8
  51. package/packages/dd-trace/src/exporter.js +1 -0
  52. package/packages/dd-trace/src/flare/file.js +44 -0
  53. package/packages/dd-trace/src/flare/index.js +98 -0
  54. package/packages/dd-trace/src/log/channels.js +54 -29
  55. package/packages/dd-trace/src/log/writer.js +7 -49
  56. package/packages/dd-trace/src/opentelemetry/span.js +8 -0
  57. package/packages/dd-trace/src/opentracing/propagation/text_map.js +57 -12
  58. package/packages/dd-trace/src/plugins/index.js +1 -0
  59. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
  60. package/packages/dd-trace/src/plugins/util/test.js +6 -0
  61. package/packages/dd-trace/src/priority_sampler.js +8 -4
  62. package/packages/dd-trace/src/profiler.js +2 -1
  63. package/packages/dd-trace/src/profiling/config.js +1 -0
  64. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  65. package/packages/dd-trace/src/profiling/{ssi-telemetry.js → ssi-heuristics.js} +64 -36
  66. package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +4 -9
  67. package/packages/dd-trace/src/proxy.js +49 -15
  68. package/packages/dd-trace/src/ritm.js +13 -1
  69. package/packages/dd-trace/src/sampling_rule.js +2 -1
  70. package/packages/dd-trace/src/startup-log.js +19 -15
  71. package/packages/dd-trace/src/telemetry/index.js +6 -2
  72. package/packages/dd-trace/src/tracer.js +3 -0
  73. package/packages/dd-trace/src/plugins/util/ip_blocklist.js +0 -51
@@ -12,17 +12,14 @@ require,dc-polyfill,MIT,Copyright 2023 Datadog Inc.
12
12
  require,ignore,MIT,Copyright 2013 Kael Zhang and contributors
13
13
  require,import-in-the-middle,Apache license 2.0,Copyright 2021 Datadog Inc.
14
14
  require,int64-buffer,MIT,Copyright 2015-2016 Yusuke Kawasaki
15
- require,ipaddr.js,MIT,Copyright 2011-2017 whitequark
16
15
  require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
17
16
  require,jest-docblock,MIT,Copyright Meta Platforms, Inc. and affiliates.
18
17
  require,koalas,MIT,Copyright 2013-2017 Brian Woodward
19
18
  require,limiter,MIT,Copyright 2011 John Hurliman
20
19
  require,lodash.sortby,MIT,Copyright JS Foundation and other contributors
21
20
  require,lru-cache,ISC,Copyright (c) 2010-2022 Isaac Z. Schlueter and Contributors
22
- require,methods,MIT,Copyright 2013-2014 TJ Holowaychuk
23
21
  require,module-details-from-path,MIT,Copyright 2016 Thomas Watson Steen
24
22
  require,msgpack-lite,MIT,Copyright 2015 Yusuke Kawasaki
25
- require,node-abort-controller,MIT,Copyright (c) 2019 Steve Faulkner
26
23
  require,opentracing,MIT,Copyright 2016 Resonance Labs Inc
27
24
  require,path-to-regexp,MIT,Copyright 2014 Blake Embrey
28
25
  require,pprof-format,MIT,Copyright 2022 Stephen Belanger
package/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  [![npm v5](https://img.shields.io/npm/v/dd-trace/latest?color=blue&label=dd-trace%40v5&logo=npm)](https://www.npmjs.com/package/dd-trace)
4
4
  [![npm v4](https://img.shields.io/npm/v/dd-trace/latest-node16?color=blue&label=dd-trace%40v4&logo=npm)](https://www.npmjs.com/package/dd-trace/v/latest-node16)
5
- [![npm v3](https://img.shields.io/npm/v/dd-trace/latest-node14?color=blue&label=dd-trace%40v3&logo=npm)](https://www.npmjs.com/package/dd-trace/v/latest-node14)
6
5
  [![codecov](https://codecov.io/gh/DataDog/dd-trace-js/branch/master/graph/badge.svg)](https://codecov.io/gh/DataDog/dd-trace-js)
7
6
 
8
7
  <img align="right" src="https://user-images.githubusercontent.com/551402/208212084-1d0c07e2-4135-4c61-b2da-8f2fddbc66ed.png" alt="Bits the dog JavaScript" width="200px"/>
@@ -28,12 +27,12 @@ Most of the documentation for `dd-trace` is available on these webpages:
28
27
  | :---: | :---: | :---: | :---: | :---: | :---: |
29
28
  | [`v1`](https://github.com/DataDog/dd-trace-js/tree/v1.x) | ![npm v1](https://img.shields.io/npm/v/dd-trace/legacy-v1?color=white&label=%20&style=flat-square) | `>= v12` | **End of Life** | 2021-07-13 | 2022-02-25 |
30
29
  | [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) | ![npm v2](https://img.shields.io/npm/v/dd-trace/latest-node12?color=white&label=%20&style=flat-square) | `>= v12` | **End of Life** | 2022-01-28 | 2023-08-15 |
31
- | [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) | ![npm v3](https://img.shields.io/npm/v/dd-trace/latest-node14?color=white&label=%20&style=flat-square) | `>= v14` | **Maintenance** | 2022-08-15 | 2024-05-15 |
30
+ | [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) | ![npm v3](https://img.shields.io/npm/v/dd-trace/latest-node14?color=white&label=%20&style=flat-square) | `>= v14` | **End of Life** | 2022-08-15 | 2024-05-15 |
32
31
  | [`v4`](https://github.com/DataDog/dd-trace-js/tree/v4.x) | ![npm v4](https://img.shields.io/npm/v/dd-trace/latest-node16?color=white&label=%20&style=flat-square) | `>= v16` | **Maintenance** | 2023-05-12 | 2025-01-11 |
33
32
  | [`v5`](https://github.com/DataDog/dd-trace-js/tree/v5.x) | ![npm v5](https://img.shields.io/npm/v/dd-trace/latest?color=white&label=%20&style=flat-square) | `>= v18` | **Current** | 2024-01-11 | Unknown |
34
33
 
35
- We currently maintain three release lines, namely `v5`, `v4` and `v3`.
36
- Features and bug fixes that are merged are released to the `v5` line and, if appropriate, also the `v4` & `v3` line.
34
+ We currently maintain two release lines, namely `v5`, and `v4`.
35
+ Features and bug fixes that are merged are released to the `v5` line and, if appropriate, also `v4`.
37
36
 
38
37
  For any new projects it is recommended to use the `v5` release line:
39
38
 
@@ -42,7 +41,7 @@ $ npm install dd-trace
42
41
  $ yarn add dd-trace
43
42
  ```
44
43
 
45
- However, existing projects that already use the `v4` & `v3` release line, or projects that need to support EOL versions of Node.js, may continue to use these release lines.
44
+ However, existing projects that already use the `v4` release line, or projects that need to support EOL versions of Node.js, may continue to use these release lines.
46
45
  This is done by specifying the version when installing the package.
47
46
 
48
47
  ```sh
@@ -67,18 +66,9 @@ Changes associated with each individual release are documented on the [GitHub Re
67
66
  Please read the [CONTRIBUTING.md](https://github.com/DataDog/dd-trace-js/blob/master/CONTRIBUTING.md) document before contributing to this open source project.
68
67
 
69
68
 
70
- ## Experimental ESM Support
69
+ ## EcmaScript Modules (ESM) Support
71
70
 
72
- > **Warning**
73
- >
74
- > ESM support has been temporarily disabled starting from Node 20 as significant
75
- > changes are in progress.
76
-
77
- ESM support is currently in the experimental stages, while CJS has been supported
78
- since inception. This means that code loaded using `require()` should work fine
79
- but code loaded using `import` might not always work.
80
-
81
- Use the following command to enable experimental ESM support with your application:
71
+ ESM support requires an additional command-line argument. Use the following to enable experimental ESM support with your application:
82
72
 
83
73
  Node.js < v20.6
84
74
 
@@ -110,9 +100,9 @@ If you would like to trace your bundled application then please read this page o
110
100
 
111
101
  Please refer to the [SECURITY.md](https://github.com/DataDog/dd-trace-js/blob/master/SECURITY.md) document if you have found a security issue.
112
102
 
103
+
113
104
  ## Datadog With OpenTelemetery
114
105
 
115
- Please refer to the [Node.js Custom Instrumentation using OpenTelemetry API](https://docs.datadoghq.com/tracing/trace_collection/custom_instrumentation/nodejs/otel/) document. It includes information on how to use the OpenTelemetry API with dd-trace-js
106
+ Please refer to the [Node.js Custom Instrumentation using OpenTelemetry API](https://docs.datadoghq.com/tracing/trace_collection/custom_instrumentation/nodejs/otel/) document. It includes information on how to use the OpenTelemetry API with dd-trace-js.
116
107
 
117
108
  Note that our internal implementation of the OpenTelemetry API is currently set within the version range `>=1.0.0 <1.9.0`. This range will be updated at a regular cadence therefore, we recommend updating your tracer to the latest release to ensure up to date support.
118
-
package/ci/init.js CHANGED
@@ -4,6 +4,7 @@ const { isTrue } = require('../packages/dd-trace/src/util')
4
4
 
5
5
  const isJestWorker = !!process.env.JEST_WORKER_ID
6
6
  const isCucumberWorker = !!process.env.CUCUMBER_WORKER_ID
7
+ const isMochaWorker = !!process.env.MOCHA_WORKER_ID
7
8
 
8
9
  const options = {
9
10
  startupLogs: false,
@@ -44,6 +45,12 @@ if (isCucumberWorker) {
44
45
  }
45
46
  }
46
47
 
48
+ if (isMochaWorker) {
49
+ options.experimental = {
50
+ exporter: 'mocha_worker'
51
+ }
52
+ }
53
+
47
54
  if (shouldInit) {
48
55
  tracer.init(options)
49
56
  tracer.use('fs', false)
@@ -5,6 +5,7 @@ declare const exporters: {
5
5
  AGENT_PROXY: 'agent_proxy',
6
6
  JEST_WORKER: 'jest_worker',
7
7
  CUCUMBER_WORKER: 'cucumber_worker'
8
+ MOCHA_WORKER: 'mocha_worker'
8
9
  }
9
10
 
10
11
  export = exporters
package/ext/exporters.js CHANGED
@@ -5,5 +5,6 @@ module.exports = {
5
5
  DATADOG: 'datadog',
6
6
  AGENT_PROXY: 'agent_proxy',
7
7
  JEST_WORKER: 'jest_worker',
8
- CUCUMBER_WORKER: 'cucumber_worker'
8
+ CUCUMBER_WORKER: 'cucumber_worker',
9
+ MOCHA_WORKER: 'mocha_worker'
9
10
  }
package/ext/tags.d.ts CHANGED
@@ -10,6 +10,7 @@ declare const tags: {
10
10
  MANUAL_DROP: 'manual.drop'
11
11
  MEASURED: '_dd.measured'
12
12
  BASE_SERVICE: '_dd.base_service'
13
+ DD_PARENT_ID: '_dd.parent_id'
13
14
  HTTP_URL: 'http.url'
14
15
  HTTP_METHOD: 'http.method'
15
16
  HTTP_STATUS_CODE: 'http.status_code'
package/ext/tags.js CHANGED
@@ -13,6 +13,7 @@ const tags = {
13
13
  MANUAL_DROP: 'manual.drop',
14
14
  MEASURED: '_dd.measured',
15
15
  BASE_SERVICE: '_dd.base_service',
16
+ DD_PARENT_ID: '_dd.parent_id',
16
17
 
17
18
  // HTTP
18
19
  HTTP_URL: 'http.url',
package/index.d.ts CHANGED
@@ -113,9 +113,15 @@ interface Tracer extends opentracing.Tracer {
113
113
  wrap<T = (...args: any[]) => any> (name: string, options: (...args: any[]) => tracer.TraceOptions & tracer.SpanOptions, fn: T): T;
114
114
 
115
115
  /**
116
- * Create and return a string that can be included in the <head> of a
117
- * document to enable RUM tracing to include it. The resulting string
118
- * should not be cached.
116
+ * Returns an HTML string containing <meta> tags that should be included in
117
+ * the <head> of a document to enable correlating the current trace with the
118
+ * RUM view. Otherwise, it is not possible to associate the trace used to
119
+ * generate the initial HTML document with a given RUM view. The resulting
120
+ * HTML document should not be cached as the meta tags are time-sensitive
121
+ * and are associated with a specific user.
122
+ *
123
+ * Note that this feature is currently not supported by the backend and
124
+ * using it will have no effect.
119
125
  */
120
126
  getRumData (): string;
121
127
 
@@ -684,6 +690,15 @@ declare namespace tracer {
684
690
  * @default 0.1
685
691
  */
686
692
  requestSampling?: number
693
+ },
694
+ /**
695
+ * Configuration for RASP
696
+ */
697
+ rasp?: {
698
+ /** Whether to enable RASP.
699
+ * @default false
700
+ */
701
+ enabled?: boolean
687
702
  }
688
703
  };
689
704
 
package/initialize.mjs ADDED
@@ -0,0 +1,52 @@
1
+ /**
2
+ * This file serves one of two purposes, depending on how it's used.
3
+ *
4
+ * If used with --import, it will import init.js and register the loader hook.
5
+ * If used with --loader, it will act as the loader hook, except that it will
6
+ * also import init.js inside the source code of the entrypoint file.
7
+ *
8
+ * The result is that no matter how this file is used, so long as it's with
9
+ * one of the two flags, the tracer will always be initialized, and the loader
10
+ * hook will always be active for ESM support.
11
+ */
12
+
13
+ import { isMainThread } from 'worker_threads'
14
+
15
+ import { fileURLToPath } from 'node:url'
16
+ import {
17
+ load as origLoad,
18
+ resolve as origResolve,
19
+ getFormat as origGetFormat,
20
+ getSource as origGetSource
21
+ } from 'import-in-the-middle/hook.mjs'
22
+
23
+ let hasInsertedInit = false
24
+ function insertInit (result) {
25
+ if (!hasInsertedInit) {
26
+ hasInsertedInit = true
27
+ result.source = `
28
+ import '${fileURLToPath(new URL('./init.js', import.meta.url))}';
29
+ ${result.source}`
30
+ }
31
+ return result
32
+ }
33
+
34
+ export async function load (...args) {
35
+ return insertInit(await origLoad(...args))
36
+ }
37
+
38
+ export const resolve = origResolve
39
+
40
+ export const getFormat = origGetFormat
41
+
42
+ export async function getSource (...args) {
43
+ return insertInit(await origGetSource(...args))
44
+ }
45
+
46
+ if (isMainThread) {
47
+ await import('./init.js')
48
+ const { register } = await import('node:module')
49
+ if (register) {
50
+ register('./loader-hook.mjs', import.meta.url)
51
+ }
52
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "5.14.1",
3
+ "version": "5.16.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -32,13 +32,13 @@
32
32
  "test:plugins:upstream": "node ./packages/dd-trace/test/plugins/suite.js",
33
33
  "test:profiler": "tap \"packages/dd-trace/test/profiling/**/*.spec.js\"",
34
34
  "test:profiler:ci": "npm run test:profiler -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/profiling/**/*.js\"",
35
- "test:integration": "mocha --colors --timeout 30000 \"integration-tests/*.spec.js\"",
36
- "test:integration:cucumber": "mocha --colors --timeout 30000 \"integration-tests/cucumber/*.spec.js\"",
37
- "test:integration:cypress": "mocha --colors --timeout 30000 \"integration-tests/cypress/*.spec.js\"",
38
- "test:integration:playwright": "mocha --colors --timeout 30000 \"integration-tests/playwright/*.spec.js\"",
39
- "test:integration:selenium": "mocha --colors --timeout 30000 \"integration-tests/selenium/*.spec.js\"",
40
- "test:integration:profiler": "mocha --colors --timeout 90000 \"integration-tests/profiler/*.spec.js\"",
41
- "test:integration:serverless": "mocha --colors --timeout 30000 \"integration-tests/serverless/*.spec.js\"",
35
+ "test:integration": "mocha --colors --timeout 30000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/*.spec.js\"",
36
+ "test:integration:cucumber": "mocha --colors --timeout 30000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/cucumber/*.spec.js\"",
37
+ "test:integration:cypress": "mocha --colors --timeout 30000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/cypress/*.spec.js\"",
38
+ "test:integration:playwright": "mocha --colors --timeout 30000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/playwright/*.spec.js\"",
39
+ "test:integration:selenium": "mocha --colors --timeout 30000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/selenium/*.spec.js\"",
40
+ "test:integration:profiler": "mocha --colors --timeout 90000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/profiler/*.spec.js\"",
41
+ "test:integration:serverless": "mocha --colors --timeout 30000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/serverless/*.spec.js\"",
42
42
  "test:integration:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/integration-test/**/*.spec.js\"",
43
43
  "test:unit:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-instrumentations/test/@($(echo $PLUGINS)).spec.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/**/*.spec.js\" --exclude \"packages/datadog-plugin-@($(echo $PLUGINS))/test/integration-test/**/*.spec.js\"",
44
44
  "test:shimmer": "mocha --colors 'packages/datadog-shimmer/test/**/*.spec.js'",
@@ -70,7 +70,7 @@
70
70
  "node": ">=18"
71
71
  },
72
72
  "dependencies": {
73
- "@datadog/native-appsec": "7.1.1",
73
+ "@datadog/native-appsec": "8.0.1",
74
74
  "@datadog/native-iast-rewriter": "2.3.1",
75
75
  "@datadog/native-iast-taint-tracking": "2.1.0",
76
76
  "@datadog/native-metrics": "^2.0.0",
@@ -83,17 +83,14 @@
83
83
  "ignore": "^5.2.4",
84
84
  "import-in-the-middle": "^1.7.4",
85
85
  "int64-buffer": "^0.1.9",
86
- "ipaddr.js": "^2.1.0",
87
86
  "istanbul-lib-coverage": "3.2.0",
88
87
  "jest-docblock": "^29.7.0",
89
88
  "koalas": "^1.0.2",
90
89
  "limiter": "1.1.5",
91
90
  "lodash.sortby": "^4.7.0",
92
91
  "lru-cache": "^7.14.0",
93
- "methods": "^1.1.2",
94
92
  "module-details-from-path": "^1.0.3",
95
93
  "msgpack-lite": "^0.1.26",
96
- "node-abort-controller": "^3.1.1",
97
94
  "opentracing": ">=0.12.1",
98
95
  "path-to-regexp": "^0.1.2",
99
96
  "pprof-format": "^2.1.0",
@@ -8,13 +8,16 @@ const {
8
8
  const kebabCase = require('../../datadog-core/src/utils/src/kebabcase')
9
9
  const shimmer = require('../../datadog-shimmer')
10
10
 
11
+ const { NODE_MAJOR, NODE_MINOR } = require('../../../version')
12
+ const MIN_VERSION = ((NODE_MAJOR > 22) || (NODE_MAJOR === 22 && NODE_MINOR >= 2)) ? '>=0.5.3' : '>=0.5.0'
13
+
11
14
  const startCh = channel('apm:amqplib:command:start')
12
15
  const finishCh = channel('apm:amqplib:command:finish')
13
16
  const errorCh = channel('apm:amqplib:command:error')
14
17
 
15
18
  let methods = {}
16
19
 
17
- addHook({ name: 'amqplib', file: 'lib/defs.js', versions: ['>=0.5'] }, defs => {
20
+ addHook({ name: 'amqplib', file: 'lib/defs.js', versions: [MIN_VERSION] }, defs => {
18
21
  methods = Object.keys(defs)
19
22
  .filter(key => Number.isInteger(defs[key]))
20
23
  .filter(key => isCamelCase(key))
@@ -22,7 +25,7 @@ addHook({ name: 'amqplib', file: 'lib/defs.js', versions: ['>=0.5'] }, defs => {
22
25
  return defs
23
26
  })
24
27
 
25
- addHook({ name: 'amqplib', file: 'lib/channel.js', versions: ['>=0.5'] }, channel => {
28
+ addHook({ name: 'amqplib', file: 'lib/channel.js', versions: [MIN_VERSION] }, channel => {
26
29
  shimmer.wrap(channel.Channel.prototype, 'sendImmediately', sendImmediately => function (method, fields) {
27
30
  return instrument(sendImmediately, this, arguments, methods[method], fields)
28
31
  })
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const { AbortController } = require('node-abort-controller')
4
3
  const { addHook } = require('./helpers/instrument')
5
4
  const shimmer = require('../../datadog-shimmer')
6
5
  const dc = require('dc-polyfill')
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const { AbortController } = require('node-abort-controller')
4
3
  const dc = require('dc-polyfill')
5
4
 
6
5
  const { addHook } = require('./helpers/instrument')
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const { AbortController } = require('node-abort-controller') // AbortController is not available in node <15
4
3
  const shimmer = require('../../datadog-shimmer')
5
4
  const { channel, addHook } = require('./helpers/instrument')
6
5
 
@@ -1,6 +1,30 @@
1
1
  'use strict'
2
2
 
3
- /* eslint-disable no-console */
3
+ // This code runs before the tracer is configured and before a logger is ready
4
+ // For that reason we queue up the messages now and decide what to do with them later
5
+ const warnings = []
6
+
7
+ /**
8
+ * Here we maintain a list of packages that an application
9
+ * may have installed which could potentially conflict with
10
+ */
11
+ const potentialConflicts = new Set([
12
+ '@appsignal/javascript',
13
+ '@appsignal/nodejs',
14
+ '@dynatrace/oneagent',
15
+ '@instana/aws-fargate',
16
+ '@instana/aws-lambda',
17
+ '@instana/azure-container-services',
18
+ '@instana/collector',
19
+ '@instana/google-cloud-run',
20
+ '@sentry/node',
21
+ 'appoptics-apm',
22
+ 'atatus-nodejs',
23
+ 'elastic-apm-node',
24
+ 'newrelic',
25
+ 'stackify-node-apm',
26
+ 'sqreen'
27
+ ])
4
28
 
5
29
  const extractPackageAndModulePath = require('./utils/src/extract-package-and-module-path')
6
30
 
@@ -13,14 +37,14 @@ const extractPackageAndModulePath = require('./utils/src/extract-package-and-mod
13
37
  *
14
38
  * Note that this only going to work for modules within npm
15
39
  * packages, like `express`, and not internal modules, like
16
- * `http`.
40
+ * `http`. It also only works with CJS, not with ESM imports.
17
41
  *
18
42
  * The output isn't necessarily 100% perfect. For example if the
19
43
  * app loads a package we instrument but outside of an
20
44
  * unsupported version then a warning would still be displayed.
21
45
  * This is OK as the tracer should be loaded earlier anyway.
22
46
  */
23
- module.exports = function () {
47
+ module.exports.checkForRequiredModules = function () {
24
48
  const packages = require('../../datadog-instrumentations/src/helpers/hooks')
25
49
  const naughties = new Set()
26
50
  let didWarn = false
@@ -31,11 +55,49 @@ module.exports = function () {
31
55
  if (naughties.has(pkg)) continue
32
56
  if (!(pkg in packages)) continue
33
57
 
34
- console.error(`Warning: Package '${pkg}' was loaded before dd-trace! This may break instrumentation.`)
58
+ warnings.push(`Warning: Package '${pkg}' was loaded before dd-trace! This may break instrumentation.`)
35
59
 
36
60
  naughties.add(pkg)
37
61
  didWarn = true
38
62
  }
39
63
 
40
- if (didWarn) console.error('Warning: Please ensure dd-trace is loaded before other modules.')
64
+ if (didWarn) warnings.push('Warning: Please ensure dd-trace is loaded before other modules.')
65
+ }
66
+
67
+ /**
68
+ * APM tools, and some other packages in the community, work
69
+ * by monkey-patching internal modules and possibly some
70
+ * globals. Usually this is done in a conflict-free way by
71
+ * wrapping an existing method with a new method that still
72
+ * calls the original method. Unfortunately it's possible
73
+ * that some of these packages (dd-trace included) may
74
+ * wrap methods in a way that make it unsafe for the methods
75
+ * to be wrapped again by another library.
76
+ *
77
+ * When encountered, and when debug mode is on, a warning is
78
+ * printed if such a package is discovered. This can help
79
+ * when debugging a faulty installation.
80
+ */
81
+ module.exports.checkForPotentialConflicts = function () {
82
+ const naughties = new Set()
83
+ let didWarn = false
84
+
85
+ for (const pathToModule of Object.keys(require.cache)) {
86
+ const { pkg } = extractPackageAndModulePath(pathToModule)
87
+ if (naughties.has(pkg)) continue
88
+ if (!potentialConflicts.has(pkg)) continue
89
+
90
+ warnings.push(`Warning: Package '${pkg}' may cause conflicts with dd-trace.`)
91
+
92
+ naughties.add(pkg)
93
+ didWarn = true
94
+ }
95
+
96
+ if (didWarn) warnings.push('Warning: Packages were loaded that may conflict with dd-trace.')
97
+ }
98
+
99
+ module.exports.flushStartupLogs = function (log) {
100
+ while (warnings.length) {
101
+ log.warn(warnings.shift())
102
+ }
41
103
  }
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const { AbortController } = require('node-abort-controller') // AbortController is not available in node <15
4
3
  const shimmer = require('../../datadog-shimmer')
5
4
  const { channel, addHook } = require('./helpers/instrument')
6
5
 
@@ -3,7 +3,6 @@
3
3
  const { createWrapRouterMethod } = require('./router')
4
4
  const shimmer = require('../../datadog-shimmer')
5
5
  const { addHook, channel } = require('./helpers/instrument')
6
- const { AbortController } = require('node-abort-controller')
7
6
 
8
7
  const handleChannel = channel('apm:express:request:handle')
9
8
 
@@ -1,7 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const { AbortController } = require('node-abort-controller')
4
-
5
3
  const {
6
4
  addHook,
7
5
  channel,
@@ -71,6 +71,7 @@ module.exports = {
71
71
  'microgateway-core': () => require('../microgateway-core'),
72
72
  mocha: () => require('../mocha'),
73
73
  'mocha-each': () => require('../mocha'),
74
+ workerpool: () => require('../mocha'),
74
75
  moleculer: () => require('../moleculer'),
75
76
  mongodb: () => require('../mongodb'),
76
77
  'mongodb-core': () => require('../mongodb-core'),
@@ -29,10 +29,13 @@ if (!disabledInstrumentations.has('fetch')) {
29
29
  }
30
30
 
31
31
  const HOOK_SYMBOL = Symbol('hookExportsMap')
32
- // TODO: make this more efficient
33
32
 
34
- if (DD_TRACE_DEBUG && DD_TRACE_DEBUG.toLowerCase() !== 'false') checkRequireCache()
33
+ if (DD_TRACE_DEBUG && DD_TRACE_DEBUG.toLowerCase() !== 'false') {
34
+ checkRequireCache.checkForRequiredModules()
35
+ setImmediate(checkRequireCache.checkForPotentialConflicts)
36
+ }
35
37
 
38
+ // TODO: make this more efficient
36
39
  for (const packageName of names) {
37
40
  if (disabledInstrumentations.has(packageName)) continue
38
41
 
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const { AbortController } = require('node-abort-controller') // AbortController is not available in node <15
4
3
  const {
5
4
  channel,
6
5
  addHook
@@ -148,7 +148,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
148
148
  }
149
149
  let hasSnapshotTests = true
150
150
  try {
151
- const { _snapshotData } = this.context.expect.getState().snapshotState
151
+ const { _snapshotData } = this.getVmContext().expect.getState().snapshotState
152
152
  hasSnapshotTests = Object.keys(_snapshotData).length > 0
153
153
  } catch (e) {
154
154
  // if we can't be sure, we'll err on the side of caution and assume it has snapshots
@@ -589,10 +589,13 @@ function coverageReporterWrapper (coverageReporter) {
589
589
 
590
590
  /**
591
591
  * If ITR is active, we're running fewer tests, so of course the total code coverage is reduced.
592
- * This calculation adds no value, so we'll skip it.
592
+ * This calculation adds no value, so we'll skip it, as long as the user has not manually opted in to code coverage,
593
+ * in which case we'll leave it.
593
594
  */
594
595
  shimmer.wrap(CoverageReporter.prototype, '_addUntestedFiles', addUntestedFiles => async function () {
595
- if (isSuitesSkippingEnabled) {
596
+ // If the user has added coverage manually, they're willing to pay the price of this execution, so
597
+ // we will not skip it.
598
+ if (isSuitesSkippingEnabled && !isUserCodeCoverageEnabled) {
596
599
  return Promise.resolve()
597
600
  }
598
601
  return addUntestedFiles.apply(this, arguments)
@@ -0,0 +1,48 @@
1
+ const { addHook, channel } = require('../helpers/instrument')
2
+ const shimmer = require('../../../datadog-shimmer')
3
+ const { getCallSites } = require('../../../dd-trace/src/plugins/util/test')
4
+ const { testToStartLine } = require('./utils')
5
+
6
+ const parameterizedTestCh = channel('ci:mocha:test:parameterize')
7
+ const patched = new WeakSet()
8
+
9
+ // mocha-each support
10
+ addHook({
11
+ name: 'mocha-each',
12
+ versions: ['>=2.0.1']
13
+ }, mochaEach => {
14
+ if (patched.has(mochaEach)) return mochaEach
15
+
16
+ patched.add(mochaEach)
17
+
18
+ return shimmer.wrap(mochaEach, function () {
19
+ const [params] = arguments
20
+ const { it, ...rest } = mochaEach.apply(this, arguments)
21
+ return {
22
+ it: function (title) {
23
+ parameterizedTestCh.publish({ title, params })
24
+ it.apply(this, arguments)
25
+ },
26
+ ...rest
27
+ }
28
+ })
29
+ })
30
+
31
+ // support for start line
32
+ addHook({
33
+ name: 'mocha',
34
+ versions: ['>=5.2.0'],
35
+ file: 'lib/suite.js'
36
+ }, (Suite) => {
37
+ shimmer.wrap(Suite.prototype, 'addTest', addTest => function (test) {
38
+ const callSites = getCallSites()
39
+ let startLine
40
+ const testCallSite = callSites.find(site => site.getFileName() === test.file)
41
+ if (testCallSite) {
42
+ startLine = testCallSite.getLineNumber()
43
+ testToStartLine.set(test, startLine)
44
+ }
45
+ return addTest.apply(this, arguments)
46
+ })
47
+ return Suite
48
+ })