dd-trace 2.30.0 → 2.31.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 (48) hide show
  1. package/LICENSE-3rdparty.csv +1 -1
  2. package/esbuild.js +3 -0
  3. package/index.d.ts +10 -9
  4. package/package.json +8 -8
  5. package/packages/datadog-core/src/storage/async_resource.js +1 -1
  6. package/packages/datadog-esbuild/index.js +9 -2
  7. package/packages/datadog-instrumentations/src/cucumber.js +11 -1
  8. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
  9. package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
  10. package/packages/datadog-instrumentations/src/jest.js +6 -3
  11. package/packages/datadog-instrumentations/src/mocha.js +19 -2
  12. package/packages/datadog-instrumentations/src/playwright.js +2 -2
  13. package/packages/datadog-plugin-cucumber/src/index.js +6 -4
  14. package/packages/datadog-plugin-cypress/src/plugin.js +5 -1
  15. package/packages/datadog-plugin-cypress/src/support.js +4 -0
  16. package/packages/datadog-plugin-http/src/client.js +1 -1
  17. package/packages/datadog-plugin-jest/src/index.js +10 -5
  18. package/packages/datadog-plugin-mocha/src/index.js +9 -4
  19. package/packages/datadog-plugin-next/src/index.js +6 -0
  20. package/packages/datadog-plugin-playwright/src/index.js +6 -5
  21. package/packages/datadog-plugin-redis/src/index.js +16 -5
  22. package/packages/dd-trace/src/appsec/gateway/channels.js +1 -1
  23. package/packages/dd-trace/src/appsec/iast/index.js +1 -1
  24. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +21 -13
  25. package/packages/dd-trace/src/appsec/iast/telemetry/logs.js +1 -1
  26. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -1
  27. package/packages/dd-trace/src/config.js +1 -0
  28. package/packages/dd-trace/src/dcitm.js +2 -0
  29. package/packages/dd-trace/src/encode/tags-processors.js +40 -68
  30. package/packages/dd-trace/src/exporters/common/request.js +2 -2
  31. package/packages/dd-trace/src/format.js +2 -1
  32. package/packages/dd-trace/src/iitm.js +1 -1
  33. package/packages/dd-trace/src/lambda/handler.js +30 -6
  34. package/packages/dd-trace/src/log/channels.js +11 -12
  35. package/packages/dd-trace/src/opentracing/propagation/text_map.js +2 -2
  36. package/packages/dd-trace/src/plugin_manager.js +1 -1
  37. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  38. package/packages/dd-trace/src/plugins/util/test.js +19 -1
  39. package/packages/dd-trace/src/profiling/profilers/cpu.js +1 -1
  40. package/packages/dd-trace/src/ritm.js +1 -1
  41. package/packages/dd-trace/src/span_stats.js +1 -1
  42. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  43. package/packages/dd-trace/src/telemetry/index.js +1 -1
  44. package/packages/diagnostics_channel/index.js +3 -0
  45. package/packages/diagnostics_channel/src/index.js +57 -0
  46. package/scripts/install_plugin_modules.js +2 -0
  47. package/packages/dd-trace/src/instrumenter.js +0 -203
  48. package/packages/dd-trace/src/loader.js +0 -131
@@ -40,6 +40,7 @@ dev,esbuild,MIT,Copyright (c) 2020 Evan Wallace
40
40
  dev,eslint,MIT,Copyright JS Foundation and other contributors https://js.foundation
41
41
  dev,eslint-config-standard,MIT,Copyright Feross Aboukhadijeh
42
42
  dev,eslint-plugin-import,MIT,Copyright 2015 Ben Mosher
43
+ dev,eslint-plugin-n,MIT,Copyright 2015 Toru Nagashima
43
44
  dev,eslint-plugin-node,MIT,Copyright 2015 Toru Nagashima
44
45
  dev,eslint-plugin-promise,ISC,jden and other contributors
45
46
  dev,eslint-plugin-standard,MIT,Copyright 2015 Jamund Ferguson
@@ -62,6 +63,5 @@ dev,sinon,BSD-3-Clause,Copyright 2010-2017 Christian Johansen
62
63
  dev,sinon-chai,WTFPL and BSD-2-Clause,Copyright 2004 Sam Hocevar 2012–2017 Domenic Denicola
63
64
  dev,tap,ISC,Copyright 2011-2022 Isaac Z. Schlueter and Contributors
64
65
  dev,tape,MIT,Copyright James Halliday
65
- dev,wait-on,MIT,Copyright 2015 Jeff Barczewski
66
66
  file,aws-lambda-nodejs-runtime-interface-client,Apache 2.0,Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
67
67
  file,profile.proto,Apache license 2.0,Copyright 2016 Google Inc.
package/esbuild.js ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict'
2
+
3
+ module.exports = require('./packages/datadog-esbuild/index.js')
package/index.d.ts CHANGED
@@ -882,7 +882,7 @@ declare namespace plugins {
882
882
  /**
883
883
  * Hook to execute just before the request span finishes.
884
884
  */
885
- request?: (span?: opentracing.Span, req?: IncomingMessage, res?: ServerResponse) => any;
885
+ request?: (span?: Span, req?: IncomingMessage, res?: ServerResponse) => any;
886
886
  };
887
887
 
888
888
  /**
@@ -918,7 +918,7 @@ declare namespace plugins {
918
918
  /**
919
919
  * Hook to execute just before the request span finishes.
920
920
  */
921
- request?: (span?: opentracing.Span, req?: ClientRequest, res?: IncomingMessage) => any;
921
+ request?: (span?: Span, req?: ClientRequest, res?: IncomingMessage) => any;
922
922
  };
923
923
 
924
924
  /**
@@ -1008,7 +1008,7 @@ declare namespace plugins {
1008
1008
  /**
1009
1009
  * Hook to execute just before the aws span finishes.
1010
1010
  */
1011
- request?: (span?: opentracing.Span, response?: anyObject) => any;
1011
+ request?: (span?: Span, response?: anyObject) => any;
1012
1012
  };
1013
1013
 
1014
1014
  /**
@@ -1077,7 +1077,7 @@ declare namespace plugins {
1077
1077
  /**
1078
1078
  * Hook to execute just before the query span finishes.
1079
1079
  */
1080
- query?: (span?: opentracing.Span, params?: TransportRequestParams) => any;
1080
+ query?: (span?: Span, params?: TransportRequestParams) => any;
1081
1081
  };
1082
1082
  }
1083
1083
 
@@ -1183,7 +1183,8 @@ declare namespace plugins {
1183
1183
 
1184
1184
  /**
1185
1185
  * Whether to enable signature calculation for the resource name. This can
1186
- * be disabled if your GraphQL operations always have a name.
1186
+ * be disabled if your GraphQL operations always have a name. Note that when
1187
+ * disabled all queries will need to be named for this to work properly.
1187
1188
  *
1188
1189
  * @default true
1189
1190
  */
@@ -1252,7 +1253,7 @@ declare namespace plugins {
1252
1253
  * Hook to execute just before the request span finishes.
1253
1254
  */
1254
1255
  request?: (
1255
- span?: opentracing.Span,
1256
+ span?: Span,
1256
1257
  req?: IncomingMessage | ClientRequest,
1257
1258
  res?: ServerResponse | IncomingMessage
1258
1259
  ) => any;
@@ -1445,7 +1446,7 @@ declare namespace plugins {
1445
1446
  /**
1446
1447
  * Hook to execute just before the request span finishes.
1447
1448
  */
1448
- request?: (span?: opentracing.Span, req?: IncomingMessage, res?: ServerResponse) => any;
1449
+ request?: (span?: Span, req?: IncomingMessage, res?: ServerResponse) => any;
1449
1450
  };
1450
1451
  }
1451
1452
 
@@ -1564,12 +1565,12 @@ declare namespace plugins {
1564
1565
  /**
1565
1566
  * Hook to execute just when the span is created.
1566
1567
  */
1567
- receive?: (span?: opentracing.Span, request?: any) => any;
1568
+ receive?: (span?: Span, request?: any) => any;
1568
1569
 
1569
1570
  /**
1570
1571
  * Hook to execute just when the span is finished.
1571
1572
  */
1572
- reply?: (span?: opentracing.Span, request?: any, response?: any) => any;
1573
+ reply?: (span?: Span, request?: any, response?: any) => any;
1573
1574
  };
1574
1575
  }
1575
1576
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "2.30.0",
3
+ "version": "2.31.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -67,15 +67,15 @@
67
67
  "dependencies": {
68
68
  "@datadog/native-appsec": "2.0.0",
69
69
  "@datadog/native-iast-rewriter": "2.0.1",
70
- "@datadog/native-iast-taint-tracking": "1.3.1",
71
- "@datadog/native-metrics": "^1.5.0",
72
- "@datadog/pprof": "^2.1.0",
70
+ "@datadog/native-iast-taint-tracking": "^1.4.0",
71
+ "@datadog/native-metrics": "^1.6.0",
72
+ "@datadog/pprof": "^2.2.0",
73
73
  "@datadog/sketches-js": "^2.1.0",
74
74
  "@types/node": "<18.13",
75
75
  "crypto-randomuuid": "^1.0.0",
76
76
  "diagnostics_channel": "^1.1.0",
77
77
  "ignore": "^5.2.0",
78
- "import-in-the-middle": "^1.3.4",
78
+ "import-in-the-middle": "^1.3.5",
79
79
  "ipaddr.js": "^2.0.1",
80
80
  "istanbul-lib-coverage": "3.2.0",
81
81
  "koalas": "^1.0.2",
@@ -92,7 +92,7 @@
92
92
  "path-to-regexp": "^0.1.2",
93
93
  "protobufjs": "^7.1.2",
94
94
  "retry": "^0.10.1",
95
- "semver": "^5.5.0"
95
+ "semver": "^7.3.8"
96
96
  },
97
97
  "devDependencies": {
98
98
  "autocannon": "^4.5.2",
@@ -108,6 +108,7 @@
108
108
  "eslint": "^8.23.0",
109
109
  "eslint-config-standard": "^11.0.0-beta.0",
110
110
  "eslint-plugin-import": "^2.8.0",
111
+ "eslint-plugin-n": "^15.7.0",
111
112
  "eslint-plugin-node": "^5.2.1",
112
113
  "eslint-plugin-promise": "^3.6.0",
113
114
  "eslint-plugin-standard": "^3.0.1",
@@ -129,7 +130,6 @@
129
130
  "sinon": "^11.1.2",
130
131
  "sinon-chai": "^3.7.0",
131
132
  "tap": "^16.3.4",
132
- "tape": "^4.9.1",
133
- "wait-on": "^5.0.0"
133
+ "tape": "^4.9.1"
134
134
  }
135
135
  }
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { createHook, executionAsyncResource } = require('async_hooks')
4
- const { channel } = require('diagnostics_channel')
4
+ const { channel } = require('../../../diagnostics_channel')
5
5
 
6
6
  const beforeCh = channel('dd-trace:storage:before')
7
7
  const afterCh = channel('dd-trace:storage:after')
@@ -93,11 +93,18 @@ module.exports.setup = function (build) {
93
93
  })
94
94
  }
95
95
 
96
+ // Currently esbuild support requires Node.js >=v16.17 or >=v18.7
97
+ // Better yet it would support Node >=v14.17 or >=v16
98
+ // Of course, the most ideal would be to support all versions of Node that dd-trace supports.
99
+ // Version constraints based on Node's diagnostics_channel support
96
100
  function warnIfUnsupported () {
97
101
  const [major, minor] = process.versions.node.split('.').map(Number)
98
- if (major < 14 || (major === 14 && minor < 17)) {
102
+ if (
103
+ major < 16 ||
104
+ (major === 16 && minor < 17) ||
105
+ (major === 18 && minor < 7)) {
99
106
  console.error('WARNING: Esbuild support isn\'t available for older versions of Node.js.')
100
- console.error(`Expected: Node.js >= v14.17. Actual: Node.js = ${process.version}.`)
107
+ console.error(`Expected: Node.js >=v16.17 or >=v18.7. Actual: Node.js = ${process.version}.`)
101
108
  console.error('This application may build properly with this version of Node.js, but unless a')
102
109
  console.error('more recent version is used at runtime, third party packages won\'t be instrumented.')
103
110
  }
@@ -90,7 +90,17 @@ function wrapRun (pl, isLatestVersion) {
90
90
  if (!pickleResultByFile[testSuiteFullPath]) { // first test in suite
91
91
  testSuiteStartCh.publish(testSuiteFullPath)
92
92
  }
93
- testStartCh.publish({ testName: this.pickle.name, fullTestSuite: testSuiteFullPath })
93
+
94
+ const testSourceLine = this.gherkinDocument &&
95
+ this.gherkinDocument.feature &&
96
+ this.gherkinDocument.feature.location &&
97
+ this.gherkinDocument.feature.location.line
98
+
99
+ testStartCh.publish({
100
+ testName: this.pickle.name,
101
+ fullTestSuite: testSuiteFullPath,
102
+ testSourceLine
103
+ })
94
104
  try {
95
105
  const promise = run.apply(this, arguments)
96
106
  promise.finally(() => {
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const dc = require('diagnostics_channel')
3
+ const dc = require('../../../diagnostics_channel')
4
4
  const semver = require('semver')
5
5
  const instrumentations = require('./instrumentations')
6
6
  const { AsyncResource } = require('async_hooks')
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { channel } = require('diagnostics_channel')
3
+ const { channel } = require('../../../diagnostics_channel')
4
4
  const path = require('path')
5
5
  const semver = require('semver')
6
6
  const Hook = require('./hook')
@@ -5,7 +5,8 @@ const log = require('../../dd-trace/src/log')
5
5
  const {
6
6
  getCoveredFilenamesFromCoverage,
7
7
  JEST_WORKER_TRACE_PAYLOAD_CODE,
8
- JEST_WORKER_COVERAGE_PAYLOAD_CODE
8
+ JEST_WORKER_COVERAGE_PAYLOAD_CODE,
9
+ getTestLineStart
9
10
  } = require('../../dd-trace/src/plugins/util/test')
10
11
 
11
12
  const testSessionStartCh = channel('ci:jest:session:start')
@@ -125,7 +126,8 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
125
126
  suite: this.testSuite,
126
127
  runner: 'jest-circus',
127
128
  testParameters,
128
- frameworkVersion: jestVersion
129
+ frameworkVersion: jestVersion,
130
+ testStartLine: getTestLineStart(event.test.asyncError, this.testSuite)
129
131
  })
130
132
  originalTestFns.set(event.test, event.test.fn)
131
133
  event.test.fn = asyncResource.bind(event.test.fn)
@@ -152,7 +154,8 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
152
154
  name: getJestTestName(event.test),
153
155
  suite: this.testSuite,
154
156
  runner: 'jest-circus',
155
- frameworkVersion: jestVersion
157
+ frameworkVersion: jestVersion,
158
+ testStartLine: getTestLineStart(event.test.asyncError, this.testSuite)
156
159
  })
157
160
  })
158
161
  }
@@ -9,7 +9,8 @@ const {
9
9
  resetCoverage,
10
10
  mergeCoverage,
11
11
  getTestSuitePath,
12
- fromCoverageMapToCoverage
12
+ fromCoverageMapToCoverage,
13
+ getTestLineStart
13
14
  } = require('../../dd-trace/src/plugins/util/test')
14
15
 
15
16
  const testStartCh = channel('ci:mocha:test:start')
@@ -35,6 +36,7 @@ const patched = new WeakSet()
35
36
  const testToAr = new WeakMap()
36
37
  const originalFns = new WeakMap()
37
38
  const testFileToSuiteAr = new Map()
39
+ const testToStartLine = new WeakMap()
38
40
 
39
41
  // `isWorker` is true if it's a Mocha worker
40
42
  let isWorker = false
@@ -207,10 +209,11 @@ function mochaHook (Runner) {
207
209
  if (isRetry(test)) {
208
210
  return
209
211
  }
212
+ const testStartLine = testToStartLine.get(test)
210
213
  const asyncResource = new AsyncResource('bound-anonymous-fn')
211
214
  testToAr.set(test.fn, asyncResource)
212
215
  asyncResource.runInAsyncScope(() => {
213
- testStartCh.publish(test)
216
+ testStartCh.publish({ test, testStartLine })
214
217
  })
215
218
  })
216
219
 
@@ -384,6 +387,20 @@ addHook({
384
387
  return Mocha
385
388
  })
386
389
 
390
+ addHook({
391
+ name: 'mocha',
392
+ versions: ['>=5.2.0'],
393
+ file: 'lib/suite.js'
394
+ }, (Suite) => {
395
+ shimmer.wrap(Suite.prototype, 'addTest', addTest => function (test) {
396
+ // In here, the test definition is in the stack, so we search for it.
397
+ const startLine = getTestLineStart(new Error(), test.file)
398
+ testToStartLine.set(test, startLine)
399
+ return addTest.apply(this, arguments)
400
+ })
401
+ return Suite
402
+ })
403
+
387
404
  addHook({
388
405
  name: 'mocha',
389
406
  versions: ['>=5.2.0'],
@@ -76,7 +76,7 @@ function getRootDir (playwrightRunner) {
76
76
  }
77
77
 
78
78
  function testBeginHandler (test) {
79
- const { _requireFile: testSuiteAbsolutePath, title: testName, _type } = test
79
+ const { _requireFile: testSuiteAbsolutePath, title: testName, _type, location: { line: testSourceLine } } = test
80
80
 
81
81
  if (_type === 'beforeAll' || _type === 'afterAll') {
82
82
  return
@@ -96,7 +96,7 @@ function testBeginHandler (test) {
96
96
  const testAsyncResource = new AsyncResource('bound-anonymous-fn')
97
97
  testToAr.set(test, testAsyncResource)
98
98
  testAsyncResource.runInAsyncScope(() => {
99
- testStartCh.publish({ testName, testSuiteAbsolutePath })
99
+ testStartCh.publish({ testName, testSuiteAbsolutePath, testSourceLine })
100
100
  })
101
101
  }
102
102
 
@@ -6,6 +6,7 @@ const { storage } = require('../../datadog-core')
6
6
  const {
7
7
  TEST_SKIP_REASON,
8
8
  TEST_STATUS,
9
+ TEST_SOURCE_START,
9
10
  finishAllTraceSpans,
10
11
  getTestSuitePath,
11
12
  getTestSuiteCommonTags,
@@ -80,10 +81,10 @@ class CucumberPlugin extends CiPlugin {
80
81
  this.tracer._exporter.exportCoverage(formattedCoverage)
81
82
  })
82
83
 
83
- this.addSub('ci:cucumber:test:start', ({ testName, fullTestSuite }) => {
84
+ this.addSub('ci:cucumber:test:start', ({ testName, fullTestSuite, testSourceLine }) => {
84
85
  const store = storage.getStore()
85
86
  const testSuite = getTestSuitePath(fullTestSuite, this.sourceRoot)
86
- const testSpan = this.startTestSpan(testName, testSuite)
87
+ const testSpan = this.startTestSpan(testName, testSuite, testSourceLine)
87
88
 
88
89
  this.enter(testSpan, store)
89
90
  })
@@ -130,11 +131,12 @@ class CucumberPlugin extends CiPlugin {
130
131
  })
131
132
  }
132
133
 
133
- startTestSpan (testName, testSuite) {
134
+ startTestSpan (testName, testSuite, testSourceLine) {
134
135
  return super.startTestSpan(
135
136
  testName,
136
137
  testSuite,
137
- this.testSuiteSpan
138
+ this.testSuiteSpan,
139
+ { [TEST_SOURCE_START]: testSourceLine }
138
140
  )
139
141
  }
140
142
  }
@@ -16,6 +16,7 @@ const {
16
16
  TEST_SESSION_ID,
17
17
  TEST_COMMAND,
18
18
  TEST_MODULE,
19
+ TEST_SOURCE_START,
19
20
  finishAllTraceSpans
20
21
  } = require('../../dd-trace/src/plugins/util/test')
21
22
 
@@ -204,7 +205,7 @@ module.exports = (on, config) => {
204
205
  return activeSpan ? activeSpan.context().toTraceId() : null
205
206
  },
206
207
  'dd:afterEach': (test) => {
207
- const { state, error, isRUMActive } = test
208
+ const { state, error, isRUMActive, testSourceLine } = test
208
209
  if (activeSpan) {
209
210
  activeSpan.setTag(TEST_STATUS, CYPRESS_STATUS_TO_TEST_STATUS[state])
210
211
  if (error) {
@@ -213,6 +214,9 @@ module.exports = (on, config) => {
213
214
  if (isRUMActive) {
214
215
  activeSpan.setTag(TEST_IS_RUM_ACTIVE, 'true')
215
216
  }
217
+ if (testSourceLine) {
218
+ activeSpan.setTag(TEST_SOURCE_START, testSourceLine)
219
+ }
216
220
  activeSpan.finish()
217
221
  }
218
222
  activeSpan = null
@@ -29,6 +29,10 @@ afterEach(() => {
29
29
  state: currentTest.state,
30
30
  error: currentTest.err,
31
31
  }
32
+ try {
33
+ testInfo.testSourceLine = Cypress.mocha.getRunner().currentRunnable.invocationDetails.line
34
+ } catch (e) {}
35
+
32
36
  if (win.DD_RUM) {
33
37
  testInfo.isRUMActive = true
34
38
  }
@@ -94,7 +94,7 @@ function errorHandler (err) {
94
94
  if (err) {
95
95
  span.addTags({
96
96
  [ERROR_TYPE]: err.name,
97
- [ERROR_MESSAGE]: err.message,
97
+ [ERROR_MESSAGE]: err.message || err.code,
98
98
  [ERROR_STACK]: err.stack
99
99
  })
100
100
  } else {
@@ -9,7 +9,8 @@ const {
9
9
  addIntelligentTestRunnerSpanTags,
10
10
  TEST_PARAMETERS,
11
11
  TEST_COMMAND,
12
- TEST_FRAMEWORK_VERSION
12
+ TEST_FRAMEWORK_VERSION,
13
+ TEST_SOURCE_START
13
14
  } = require('../../dd-trace/src/plugins/util/test')
14
15
  const { COMPONENT } = require('../../dd-trace/src/constants')
15
16
  const id = require('../../dd-trace/src/id')
@@ -31,8 +32,11 @@ class JestPlugin extends CiPlugin {
31
32
  // Used to handle the end of a jest worker to be able to flush
32
33
  const handler = ([message]) => {
33
34
  if (message === CHILD_MESSAGE_END) {
34
- this.testSuiteSpan.finish()
35
- finishAllTraceSpans(this.testSuiteSpan)
35
+ // testSuiteSpan is not defined for older versions of jest, where jest-jasmine2 is still used
36
+ if (this.testSuiteSpan) {
37
+ this.testSuiteSpan.finish()
38
+ finishAllTraceSpans(this.testSuiteSpan)
39
+ }
36
40
  this.tracer._exporter.flush()
37
41
  process.removeListener('message', handler)
38
42
  }
@@ -187,12 +191,13 @@ class JestPlugin extends CiPlugin {
187
191
  }
188
192
 
189
193
  startTestSpan (test) {
190
- const { suite, name, runner, testParameters, frameworkVersion } = test
194
+ const { suite, name, runner, testParameters, frameworkVersion, testStartLine } = test
191
195
 
192
196
  const extraTags = {
193
197
  [JEST_TEST_RUNNER]: runner,
194
198
  [TEST_PARAMETERS]: testParameters,
195
- [TEST_FRAMEWORK_VERSION]: frameworkVersion
199
+ [TEST_FRAMEWORK_VERSION]: frameworkVersion,
200
+ [TEST_SOURCE_START]: testStartLine
196
201
  }
197
202
 
198
203
  return super.startTestSpan(name, suite, this.testSuiteSpan, extraTags)
@@ -10,7 +10,8 @@ const {
10
10
  getTestSuitePath,
11
11
  getTestParametersString,
12
12
  getTestSuiteCommonTags,
13
- addIntelligentTestRunnerSpanTags
13
+ addIntelligentTestRunnerSpanTags,
14
+ TEST_SOURCE_START
14
15
  } = require('../../dd-trace/src/plugins/util/test')
15
16
  const { COMPONENT } = require('../../dd-trace/src/constants')
16
17
 
@@ -85,9 +86,9 @@ class MochaPlugin extends CiPlugin {
85
86
  }
86
87
  })
87
88
 
88
- this.addSub('ci:mocha:test:start', (test) => {
89
+ this.addSub('ci:mocha:test:start', ({ test, testStartLine }) => {
89
90
  const store = storage.getStore()
90
- const span = this.startTestSpan(test)
91
+ const span = this.startTestSpan(test, testStartLine)
91
92
 
92
93
  this.enter(span, store)
93
94
  })
@@ -153,7 +154,7 @@ class MochaPlugin extends CiPlugin {
153
154
  })
154
155
  }
155
156
 
156
- startTestSpan (test) {
157
+ startTestSpan (test, testStartLine) {
157
158
  const testName = test.fullTitle()
158
159
  const { file: testSuiteAbsolutePath, title } = test
159
160
 
@@ -163,6 +164,10 @@ class MochaPlugin extends CiPlugin {
163
164
  extraTags[TEST_PARAMETERS] = testParametersString
164
165
  }
165
166
 
167
+ if (testStartLine) {
168
+ extraTags[TEST_SOURCE_START] = testStartLine
169
+ }
170
+
166
171
  const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.sourceRoot)
167
172
  const testSuiteSpan = this._testSuites.get(testSuiteAbsolutePath)
168
173
 
@@ -68,6 +68,12 @@ class NextPlugin extends Plugin {
68
68
  const span = store.span
69
69
  const req = this._requests.get(span)
70
70
 
71
+ // Only use error page names if there's not already a name
72
+ const current = span.context()._tags['next.page']
73
+ if (current && (page === '/404' || page === '/500' || page === '/_error')) {
74
+ return
75
+ }
76
+
71
77
  span.addTags({
72
78
  [COMPONENT]: this.constructor.id,
73
79
  'resource.name': `${req.method} ${page}`.trim(),
@@ -7,7 +7,8 @@ const {
7
7
  TEST_STATUS,
8
8
  finishAllTraceSpans,
9
9
  getTestSuitePath,
10
- getTestSuiteCommonTags
10
+ getTestSuiteCommonTags,
11
+ TEST_SOURCE_START
11
12
  } = require('../../dd-trace/src/plugins/util/test')
12
13
  const { RESOURCE_NAME } = require('../../../ext/tags')
13
14
  const { COMPONENT } = require('../../dd-trace/src/constants')
@@ -64,10 +65,10 @@ class PlaywrightPlugin extends CiPlugin {
64
65
  span.finish()
65
66
  })
66
67
 
67
- this.addSub('ci:playwright:test:start', ({ testName, testSuiteAbsolutePath }) => {
68
+ this.addSub('ci:playwright:test:start', ({ testName, testSuiteAbsolutePath, testSourceLine }) => {
68
69
  const store = storage.getStore()
69
70
  const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.rootDir)
70
- const span = this.startTestSpan(testName, testSuite)
71
+ const span = this.startTestSpan(testName, testSuite, testSourceLine)
71
72
 
72
73
  this.enter(span, store)
73
74
  })
@@ -104,9 +105,9 @@ class PlaywrightPlugin extends CiPlugin {
104
105
  })
105
106
  }
106
107
 
107
- startTestSpan (testName, testSuite) {
108
+ startTestSpan (testName, testSuite, testSourceLine) {
108
109
  const testSuiteSpan = this._testSuites.get(testSuite)
109
- return super.startTestSpan(testName, testSuite, testSuiteSpan)
110
+ return super.startTestSpan(testName, testSuite, testSuiteSpan, { [TEST_SOURCE_START]: testSourceLine })
110
111
  }
111
112
  }
112
113
 
@@ -9,17 +9,19 @@ class RedisPlugin extends CachePlugin {
9
9
  static get system () { return 'redis' }
10
10
 
11
11
  start ({ db, command, args, connectionOptions = {}, connectionName }) {
12
- if (!this.config.filter(command)) return this.skip()
12
+ const resource = command
13
+ const normalizedCommand = command.toUpperCase()
14
+ if (!this.config.filter(normalizedCommand)) return this.skip()
13
15
 
14
16
  this.startSpan('redis.command', {
15
17
  service: getService(this.config, connectionName),
16
- resource: command,
18
+ resource,
17
19
  type: 'redis',
18
20
  kind: 'client',
19
21
  meta: {
20
22
  'db.type': 'redis',
21
23
  'db.name': db || '0',
22
- 'redis.raw_command': formatCommand(command, args),
24
+ 'redis.raw_command': formatCommand(normalizedCommand, args),
23
25
  'out.host': connectionOptions.host,
24
26
  [CLIENT_PORT_KEY]: connectionOptions.port
25
27
  }
@@ -42,8 +44,6 @@ function getService (config, connectionName) {
42
44
  }
43
45
 
44
46
  function formatCommand (command, args) {
45
- command = command.toUpperCase()
46
-
47
47
  if (!args || command === 'AUTH') return command
48
48
 
49
49
  for (let i = 0, l = args.length; i < l; i++) {
@@ -76,6 +76,11 @@ function trim (str, maxlen) {
76
76
  }
77
77
 
78
78
  function normalizeConfig (config) {
79
+ if (config.allowlist) uppercaseAllEntries(config.allowlist)
80
+ if (config.whitelist) uppercaseAllEntries(config.whitelist)
81
+ if (config.blocklist) uppercaseAllEntries(config.blocklist)
82
+ if (config.blacklist) uppercaseAllEntries(config.blacklist)
83
+
79
84
  const filter = urlFilter.getFilter(config)
80
85
 
81
86
  return Object.assign({}, config, {
@@ -83,4 +88,10 @@ function normalizeConfig (config) {
83
88
  })
84
89
  }
85
90
 
91
+ function uppercaseAllEntries (entries) {
92
+ for (let i = 0; i < entries.length; i++) {
93
+ entries[i] = String(entries[i]).toUpperCase()
94
+ }
95
+ }
96
+
86
97
  module.exports = RedisPlugin
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const dc = require('diagnostics_channel')
3
+ const dc = require('../../../../diagnostics_channel')
4
4
 
5
5
  // TODO: use TBD naming convention
6
6
  // or directly use http plugin's channels
@@ -3,7 +3,7 @@ const { enableAllAnalyzers, disableAllAnalyzers } = require('./analyzers')
3
3
  const web = require('../../plugins/util/web')
4
4
  const { storage } = require('../../../../datadog-core')
5
5
  const overheadController = require('./overhead-controller')
6
- const dc = require('diagnostics_channel')
6
+ const dc = require('../../../../diagnostics_channel')
7
7
  const iastContextFunctions = require('./iast-context')
8
8
  const { enableTaintTracking, disableTaintTracking, createTransaction, removeTransaction } = require('./taint-tracking')
9
9
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  const TaintedUtils = require('@datadog/native-iast-taint-tracking')
4
4
  const { IAST_TRANSACTION_ID } = require('../iast-context')
5
+ const iastLog = require('../iast-log')
5
6
  const { TaintTracking, TaintTrackingDummy } = require('./taint-tracking-impl')
6
7
 
7
8
  function createTransaction (id, iastContext) {
@@ -37,20 +38,27 @@ function taintObject (iastContext, object, type) {
37
38
  const visited = new WeakSet()
38
39
  while (queue.length > 0) {
39
40
  const { parent, property, value } = queue.pop()
40
- if (typeof value === 'string') {
41
- const tainted = TaintedUtils.newTaintedString(transactionId, value, property, type)
42
- if (!parent) {
43
- result = tainted
44
- } else {
45
- parent[property] = tainted
46
- }
47
- } else if (typeof value === 'object' && !visited.has(value)) {
48
- visited.add(value)
49
- const keys = Object.keys(value)
50
- for (let i = 0; i < keys.length; i++) {
51
- const key = keys[i]
52
- queue.push({ parent: value, property: property ? `${property}.${key}` : key, value: value[key] })
41
+ if (value === null) {
42
+ continue
43
+ }
44
+ try {
45
+ if (typeof value === 'string') {
46
+ const tainted = TaintedUtils.newTaintedString(transactionId, value, property, type)
47
+ if (!parent) {
48
+ result = tainted
49
+ } else {
50
+ parent[property] = tainted
51
+ }
52
+ } else if (typeof value === 'object' && !visited.has(value)) {
53
+ visited.add(value)
54
+ const keys = Object.keys(value)
55
+ for (let i = 0; i < keys.length; i++) {
56
+ const key = keys[i]
57
+ queue.push({ parent: value, property: property ? `${property}.${key}` : key, value: value[key] })
58
+ }
53
59
  }
60
+ } catch (e) {
61
+ iastLog.error(`Error visiting property : ${property}`).errorAndPublish(e)
54
62
  }
55
63
  }
56
64
  }