dd-trace 5.0.0 → 6.0.0-pre-8343722

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.
package/MIGRATING.md CHANGED
@@ -4,6 +4,21 @@ This guide describes the steps to upgrade dd-trace from a major version to the
4
4
  next. If you are having any issues related to migrating, please feel free to
5
5
  open an issue or contact our [support](https://www.datadoghq.com/support/) team.
6
6
 
7
+ ## 4.0 to 5.0
8
+
9
+ ### Node 16 is no longer supported
10
+
11
+ Node.js 16 has reached EOL in September 2023 and is no longer supported. Generally
12
+ speaking, we highly recommend always keeping Node.js up to date regardless of
13
+ our support policy.
14
+
15
+ ### Update `trace<T>` TypeScript declaration
16
+
17
+ The TypeScript declaration for `trace<T>` has been updated to enforce
18
+ that calls to `tracer.trace(name, fn)` must receive a function which takes at least
19
+ the span object. Previously the span was technically optional when it should not have
20
+ been as the span must be handled.
21
+
7
22
  ## 3.0 to 4.0
8
23
 
9
24
  ### Node 14 is no longer supported
package/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # `dd-trace`: Node.js APM Tracer Library
2
2
 
3
- [![npm v4](https://img.shields.io/npm/v/dd-trace/latest?color=blue&label=dd-trace%40v4&logo=npm)](https://www.npmjs.com/package/dd-trace)
4
- [![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-node12)
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
+ [![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)
5
6
  [![codecov](https://codecov.io/gh/DataDog/dd-trace-js/branch/master/graph/badge.svg)](https://codecov.io/gh/DataDog/dd-trace-js)
6
7
 
7
8
  <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,24 +29,25 @@ Most of the documentation for `dd-trace` is available on these webpages:
28
29
  | [`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 |
29
30
  | [`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 |
30
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 |
31
- | [`v4`](https://github.com/DataDog/dd-trace-js/tree/v4.x) | ![npm v4](https://img.shields.io/npm/v/dd-trace/latest?color=white&label=%20&style=flat-square) | `>= v16` | **Current** | 2023-05-12 | Unknown |
32
+ | [`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
+ | [`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 |
32
34
 
33
- We currently maintain two release lines, namely `v3` and `v4`.
34
- Features and bug fixes that are merged are released to the `v4` line and, if appropriate, also the `v3` line.
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.
35
37
 
36
- For any new projects it is recommended to use the `v4` release line:
38
+ For any new projects it is recommended to use the `v5` release line:
37
39
 
38
40
  ```sh
39
41
  $ npm install dd-trace
40
42
  $ yarn add dd-trace
41
43
  ```
42
44
 
43
- However, existing projects that already use the `v3` release line, or projects that need to support EOL versions of Node.js, may continue to use these release lines.
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
46
  This is done by specifying the version when installing the package.
45
47
 
46
48
  ```sh
47
- $ npm install dd-trace@3
48
- $ yarn add dd-trace@3
49
+ $ npm install dd-trace@4
50
+ $ yarn add dd-trace@4
49
51
  ```
50
52
 
51
53
  Any backwards-breaking functionality that is introduced into the library will result in an increase of the major version of the library and therefore a new release line.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "5.0.0",
3
+ "version": "6.0.0-pre-8343722",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -169,12 +169,12 @@ class CucumberPlugin extends CiPlugin {
169
169
  }
170
170
 
171
171
  span.finish()
172
- this.telemetry.ciVisEvent(
173
- TELEMETRY_EVENT_FINISHED,
174
- 'test',
175
- { hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
176
- )
177
172
  if (!isStep) {
173
+ this.telemetry.ciVisEvent(
174
+ TELEMETRY_EVENT_FINISHED,
175
+ 'test',
176
+ { hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
177
+ )
178
178
  finishAllTraceSpans(span)
179
179
  }
180
180
  })
@@ -39,6 +39,7 @@ const {
39
39
  incrementCountMetric,
40
40
  distributionMetric
41
41
  } = require('../../dd-trace/src/ci-visibility/telemetry')
42
+ const { appClosing: appClosingTelemetry } = require('../../dd-trace/src/telemetry')
42
43
  const {
43
44
  GIT_REPOSITORY_URL,
44
45
  GIT_COMMIT_SHA,
@@ -429,10 +430,12 @@ module.exports = (on, config) => {
429
430
  }
430
431
  if (exporter.flush) {
431
432
  exporter.flush(() => {
433
+ appClosingTelemetry()
432
434
  resolve(null)
433
435
  })
434
436
  } else if (exporter._writer) {
435
437
  exporter._writer.flush(() => {
438
+ appClosingTelemetry()
436
439
  resolve(null)
437
440
  })
438
441
  }
@@ -17,6 +17,7 @@ const {
17
17
  TELEMETRY_EVENT_CREATED,
18
18
  TELEMETRY_EVENT_FINISHED
19
19
  } = require('../../dd-trace/src/ci-visibility/telemetry')
20
+ const { appClosing: appClosingTelemetry } = require('../../dd-trace/src/telemetry')
20
21
 
21
22
  class PlaywrightPlugin extends CiPlugin {
22
23
  static get id () {
@@ -37,6 +38,7 @@ class PlaywrightPlugin extends CiPlugin {
37
38
  this.testSessionSpan.finish()
38
39
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
39
40
  finishAllTraceSpans(this.testSessionSpan)
41
+ appClosingTelemetry()
40
42
  this.tracer._exporter.flush(onDone)
41
43
  })
42
44
 
@@ -48,7 +48,7 @@ class HeaderInjectionAnalyzer extends InjectionAnalyzer {
48
48
  if (ranges?.length > 0) {
49
49
  return !(this.isCookieExclusion(lowerCasedHeaderName, ranges) ||
50
50
  this.isSameHeaderExclusion(lowerCasedHeaderName, ranges) ||
51
- this.isAccessControlAllowOriginExclusion(lowerCasedHeaderName, ranges))
51
+ this.isAccessControlAllowExclusion(lowerCasedHeaderName, ranges))
52
52
  }
53
53
 
54
54
  return false
@@ -84,8 +84,8 @@ class HeaderInjectionAnalyzer extends InjectionAnalyzer {
84
84
  return false
85
85
  }
86
86
 
87
- isAccessControlAllowOriginExclusion (name, ranges) {
88
- if (name === 'access-control-allow-origin') {
87
+ isAccessControlAllowExclusion (name, ranges) {
88
+ if (name?.startsWith('access-control-allow-')) {
89
89
  return ranges
90
90
  .every(range => range.iinfo.type === HTTP_REQUEST_HEADER_VALUE)
91
91
  }
@@ -25,7 +25,8 @@ class RemoteConfigManager extends EventEmitter {
25
25
  super()
26
26
 
27
27
  const pollInterval = Math.floor(config.remoteConfig.pollInterval * 1000)
28
- const url = config.url || new URL(format({
28
+
29
+ this.url = config.url || new URL(format({
29
30
  protocol: 'http:',
30
31
  hostname: config.hostname || 'localhost',
31
32
  port: config.port
@@ -33,12 +34,6 @@ class RemoteConfigManager extends EventEmitter {
33
34
 
34
35
  this.scheduler = new Scheduler((cb) => this.poll(cb), pollInterval)
35
36
 
36
- this.requestOptions = {
37
- url,
38
- method: 'POST',
39
- path: '/v0.7/config'
40
- }
41
-
42
37
  this.state = {
43
38
  client: {
44
39
  state: { // updated by `parseConfig()`
@@ -122,7 +117,13 @@ class RemoteConfigManager extends EventEmitter {
122
117
  }
123
118
 
124
119
  poll (cb) {
125
- request(this.getPayload(), this.requestOptions, (err, data, statusCode) => {
120
+ const options = {
121
+ url: this.url,
122
+ method: 'POST',
123
+ path: '/v0.7/config'
124
+ }
125
+
126
+ request(this.getPayload(), options, (err, data, statusCode) => {
126
127
  // 404 means RC is disabled, ignore it
127
128
  if (statusCode === 404) return cb()
128
129
 
@@ -795,9 +795,9 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
795
795
  tagger.add(tags, DD_TRACE_TAGS)
796
796
  tagger.add(tags, DD_TRACE_GLOBAL_TAGS)
797
797
 
798
- this._setValue(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service)
799
- this._setValue(env, 'env', DD_ENV || tags.env)
800
- this._setValue(env, 'version', DD_VERSION || tags.version)
798
+ this._setString(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service)
799
+ this._setString(env, 'env', DD_ENV || tags.env)
800
+ this._setString(env, 'version', DD_VERSION || tags.version)
801
801
  this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE)
802
802
  this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
803
803
  this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
@@ -812,9 +812,9 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
812
812
 
813
813
  tagger.add(tags, options.tags)
814
814
 
815
- this._setValue(opts, 'service', options.service || tags.service)
816
- this._setValue(opts, 'env', options.env || tags.env)
817
- this._setValue(opts, 'version', options.version || tags.version)
815
+ this._setString(opts, 'service', options.service || tags.service)
816
+ this._setString(opts, 'env', options.env || tags.env)
817
+ this._setString(opts, 'version', options.version || tags.version)
818
818
  this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))
819
819
  this._setBoolean(opts, 'logInjection', options.logInjection)
820
820
  this._setArray(opts, 'headerTags', options.headerTags)
@@ -875,6 +875,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
875
875
  }
876
876
  }
877
877
 
878
+ _setString (obj, name, value) {
879
+ obj[name] = value || undefined // unset for empty strings
880
+ }
881
+
878
882
  _setTags (obj, name, value) {
879
883
  if (!value || Object.keys(value).length === 0) {
880
884
  return this._setValue(obj, name, null)
@@ -140,8 +140,7 @@ function appStarted (config) {
140
140
  return app
141
141
  }
142
142
 
143
- function onBeforeExit () {
144
- process.removeListener('beforeExit', onBeforeExit)
143
+ function appClosing () {
145
144
  const { reqType, payload } = createPayload('app-closing')
146
145
  sendData(config, application, host, reqType, payload)
147
146
  // we flush before shutting down. Only in CI Visibility
@@ -150,6 +149,11 @@ function onBeforeExit () {
150
149
  }
151
150
  }
152
151
 
152
+ function onBeforeExit () {
153
+ process.removeListener('beforeExit', onBeforeExit)
154
+ appClosing()
155
+ }
156
+
153
157
  function createAppObject (config) {
154
158
  return {
155
159
  service_name: config.service,
@@ -339,5 +343,6 @@ module.exports = {
339
343
  start,
340
344
  stop,
341
345
  updateIntegrations,
342
- updateConfig
346
+ updateConfig,
347
+ appClosing
343
348
  }
@@ -1,6 +1,7 @@
1
1
 
2
2
  const request = require('../exporters/common/request')
3
3
  const log = require('../log')
4
+ const { isTrue } = require('../util')
4
5
 
5
6
  let agentTelemetry = true
6
7
 
@@ -49,13 +50,12 @@ function sendData (config, application, host, reqType, payload = {}, cb = () =>
49
50
  const {
50
51
  hostname,
51
52
  port,
52
- experimental,
53
53
  isCiVisibility
54
54
  } = config
55
55
 
56
56
  let url = config.url
57
57
 
58
- const isCiVisibilityAgentlessMode = isCiVisibility && experimental?.exporter === 'datadog'
58
+ const isCiVisibilityAgentlessMode = isCiVisibility && isTrue(process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED)
59
59
 
60
60
  if (isCiVisibilityAgentlessMode) {
61
61
  try {
package/scripts/st.js ADDED
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env node
2
+ /* eslint-disable no-console, no-fallthrough */
3
+ 'use strict'
4
+
5
+ const path = require('path')
6
+ const { writeFileSync } = require('fs')
7
+ const { execSync } = require('child_process')
8
+
9
+ const ddtracePath = path.join(__dirname, '..')
10
+ const defaultTestPath = process.env.DD_ST_PATH || path.join(ddtracePath, '..', 'system-tests')
11
+
12
+ const { buildAll, npm, testDir, testArgs } = parseArgs()
13
+
14
+ const binariesPath = path.join(testDir, 'binaries')
15
+
16
+ if (npm) {
17
+ console.log('Using NPM package:', npm)
18
+
19
+ writeFileSync(path.join(binariesPath, 'nodejs-load-from-npm'), npm)
20
+ } else {
21
+ console.log('Using local repo')
22
+
23
+ const packName = execSync(`npm pack ${ddtracePath}`, {
24
+ cwd: binariesPath,
25
+ stdio: [null, null, 'inherit'],
26
+ encoding: 'utf8'
27
+ }).slice(0, -1) // remove trailing newline
28
+
29
+ writeFileSync(path.join(binariesPath, 'nodejs-load-from-npm'), `/binaries/${packName}`)
30
+ }
31
+
32
+ try {
33
+ execSync(`./build.sh ${buildAll ? '' : '-i weblog'} && ./run.sh ${testArgs}`, {
34
+ cwd: testDir,
35
+ stdio: [null, 'inherit', 'inherit']
36
+ })
37
+ } catch (err) {
38
+ process.exit(err.status || 1)
39
+ }
40
+
41
+ function parseArgs () {
42
+ const args = {
43
+ buildAll: false,
44
+ npm: null,
45
+ testDir: defaultTestPath,
46
+ testArgs: ''
47
+ }
48
+
49
+ for (let i = 2; i < process.argv.length; i++) {
50
+ switch (process.argv[i]) {
51
+ case '-b':
52
+ case '--build-all':
53
+ args.buildAll = true
54
+ break
55
+
56
+ case '-h':
57
+ case '--help':
58
+ helpAndExit()
59
+ break
60
+
61
+ case '-n':
62
+ case '--npm': {
63
+ const arg = process.argv[i + 1]
64
+ if (!arg || arg[0] === '-') {
65
+ args.npm = 'dd-trace'
66
+ } else {
67
+ args.npm = arg
68
+ i++
69
+ }
70
+ break
71
+ }
72
+
73
+ case '-t':
74
+ case '--test-dir': {
75
+ const arg = process.argv[++i]
76
+ if (!arg || arg[0] === '-') helpAndExit()
77
+ args.testDir = arg
78
+ break
79
+ }
80
+
81
+ case '--':
82
+ args.testArgs = process.argv.slice(i + 1).join(' ')
83
+ return args
84
+
85
+ default:
86
+ console.log('Unknown option:', process.argv[i], '\n')
87
+ helpAndExit()
88
+ }
89
+ }
90
+
91
+ return args
92
+ }
93
+
94
+ function helpAndExit () {
95
+ console.log('Usage: node st.js [options...] [-- test-args]')
96
+ console.log('Options:')
97
+ console.log(' -b, --build-all Rebuild all images (default: only build weblog)')
98
+ console.log(' -h, --help Print this message')
99
+ console.log(' -n, --npm [package] Build a remote package instead of the local repo (default: "dd-trace")')
100
+ console.log(' Can be a package name (e.g. "dd-trace@4.2.0") or a git URL (e.g.')
101
+ console.log(' "git+https://github.com/DataDog/dd-trace-js.git#mybranch")')
102
+ console.log(' -t, --test-dir <path> Specify the system-tests directory (default: "dd-trace/../system-tests/")')
103
+ console.log(' -- <test-args> Passed to system-tests run.sh (e.g. "-- SCENARIO_NAME tests/path_to_test.py")')
104
+ process.exit()
105
+ }