dd-trace 2.21.0 → 2.22.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 (67) hide show
  1. package/LICENSE-3rdparty.csv +2 -0
  2. package/index.d.ts +11 -0
  3. package/package.json +4 -2
  4. package/packages/datadog-instrumentations/src/body-parser.js +26 -0
  5. package/packages/datadog-instrumentations/src/child-process.js +30 -0
  6. package/packages/datadog-instrumentations/src/cucumber.js +1 -1
  7. package/packages/datadog-instrumentations/src/hapi.js +3 -3
  8. package/packages/datadog-instrumentations/src/helpers/hooks.js +5 -0
  9. package/packages/datadog-instrumentations/src/jest.js +102 -42
  10. package/packages/datadog-instrumentations/src/mocha.js +87 -6
  11. package/packages/datadog-instrumentations/src/pg.js +1 -2
  12. package/packages/datadog-instrumentations/src/qs.js +24 -0
  13. package/packages/datadog-instrumentations/src/restify.js +1 -1
  14. package/packages/datadog-plugin-cucumber/src/index.js +13 -32
  15. package/packages/datadog-plugin-cypress/src/plugin.js +2 -1
  16. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +0 -1
  17. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +0 -1
  18. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +0 -1
  19. package/packages/datadog-plugin-http/src/client.js +5 -3
  20. package/packages/datadog-plugin-http/src/server.js +3 -0
  21. package/packages/datadog-plugin-http2/src/client.js +2 -0
  22. package/packages/datadog-plugin-http2/src/server.js +3 -0
  23. package/packages/datadog-plugin-jest/src/index.js +11 -131
  24. package/packages/datadog-plugin-mocha/src/index.js +33 -46
  25. package/packages/datadog-plugin-net/src/index.js +4 -0
  26. package/packages/datadog-plugin-next/src/index.js +3 -0
  27. package/packages/datadog-plugin-pg/src/index.js +5 -2
  28. package/packages/datadog-plugin-router/src/index.js +2 -0
  29. package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +3 -5
  30. package/packages/dd-trace/src/appsec/gateway/engine/index.js +1 -1
  31. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +3 -1
  32. package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +11 -0
  33. package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +19 -0
  34. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +13 -0
  35. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +1 -1
  36. package/packages/dd-trace/src/appsec/iast/index.js +6 -0
  37. package/packages/dd-trace/src/appsec/iast/path-line.js +8 -1
  38. package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +16 -0
  39. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +18 -0
  40. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +125 -0
  41. package/packages/dd-trace/src/appsec/iast/taint-tracking/origin-types.js +4 -0
  42. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +38 -0
  43. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +66 -0
  44. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +52 -6
  45. package/packages/dd-trace/src/appsec/index.js +8 -0
  46. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +7 -0
  47. package/packages/dd-trace/src/appsec/remote_config/index.js +34 -0
  48. package/packages/dd-trace/src/appsec/remote_config/manager.js +264 -0
  49. package/packages/dd-trace/src/{exporters → appsec/remote_config}/scheduler.js +9 -9
  50. package/packages/dd-trace/src/appsec/rule_manager.js +3 -0
  51. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +5 -7
  52. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +1 -3
  53. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +1 -3
  54. package/packages/dd-trace/src/config.js +25 -9
  55. package/packages/dd-trace/src/constants.js +6 -1
  56. package/packages/dd-trace/src/exporters/common/request.js +7 -1
  57. package/packages/dd-trace/src/format.js +12 -10
  58. package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -5
  59. package/packages/dd-trace/src/opentracing/span_context.js +9 -0
  60. package/packages/dd-trace/src/plugin_manager.js +4 -1
  61. package/packages/dd-trace/src/plugins/ci_plugin.js +132 -0
  62. package/packages/dd-trace/src/plugins/database.js +46 -0
  63. package/packages/dd-trace/src/plugins/tracing.js +2 -0
  64. package/packages/dd-trace/src/plugins/util/test.js +61 -8
  65. package/packages/dd-trace/src/plugins/util/web.js +9 -8
  66. package/packages/dd-trace/src/proxy.js +5 -1
  67. package/packages/dd-trace/src/tracer.js +4 -3
@@ -1,24 +1,18 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
3
+ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
4
4
  const { storage } = require('../../datadog-core')
5
5
 
6
6
  const {
7
- CI_APP_ORIGIN,
8
7
  TEST_SKIP_REASON,
9
- ERROR_MESSAGE,
10
8
  TEST_STATUS,
11
- TEST_CODE_OWNERS,
12
9
  finishAllTraceSpans,
13
- getTestEnvironmentMetadata,
14
- getTestSuitePath,
15
- getCodeOwnersFileEntries,
16
- getCodeOwnersForFilename,
17
- getTestCommonTags
10
+ getTestSuitePath
18
11
  } = require('../../dd-trace/src/plugins/util/test')
19
12
  const { RESOURCE_NAME } = require('../../../ext/tags')
13
+ const { COMPONENT, ERROR_MESSAGE } = require('../../dd-trace/src/constants')
20
14
 
21
- class CucumberPlugin extends Plugin {
15
+ class CucumberPlugin extends CiPlugin {
22
16
  static get name () {
23
17
  return 'cucumber'
24
18
  }
@@ -26,36 +20,18 @@ class CucumberPlugin extends Plugin {
26
20
  constructor (...args) {
27
21
  super(...args)
28
22
 
29
- const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber', this.config)
30
- const sourceRoot = process.cwd()
31
- const codeOwnersEntries = getCodeOwnersFileEntries(sourceRoot)
32
-
33
23
  this.addSub('ci:cucumber:session:finish', () => {
34
24
  this.tracer._exporter._writer.flush()
35
25
  })
36
26
 
37
- this.addSub('ci:cucumber:run:start', ({ pickleName, pickleUri }) => {
27
+ this.addSub('ci:cucumber:run:start', ({ testName, fullTestSuite }) => {
38
28
  const store = storage.getStore()
39
29
  const childOf = store ? store.span : store
40
- const testSuite = getTestSuitePath(pickleUri, sourceRoot)
41
-
42
- const commonTags = getTestCommonTags(pickleName, testSuite, this.tracer._version)
30
+ const testSuite = getTestSuitePath(fullTestSuite, process.cwd())
43
31
 
44
- const codeOwners = getCodeOwnersForFilename(testSuite, codeOwnersEntries)
45
- if (codeOwners) {
46
- commonTags[TEST_CODE_OWNERS] = codeOwners
47
- }
32
+ const testSpan = this.startTestSpan(testName, testSuite, childOf)
48
33
 
49
- const span = this.tracer.startSpan('cucumber.test', {
50
- childOf,
51
- tags: {
52
- ...commonTags,
53
- ...testEnvironmentMetadata
54
- }
55
- })
56
-
57
- span.context()._trace.origin = CI_APP_ORIGIN
58
- this.enter(span, store)
34
+ this.enter(testSpan, store)
59
35
  })
60
36
 
61
37
  this.addSub('ci:cucumber:run-step:start', ({ resource }) => {
@@ -64,6 +40,7 @@ class CucumberPlugin extends Plugin {
64
40
  const span = this.tracer.startSpan('cucumber.step', {
65
41
  childOf,
66
42
  tags: {
43
+ [COMPONENT]: this.constructor.name,
67
44
  'cucumber.step': resource,
68
45
  [RESOURCE_NAME]: resource
69
46
  }
@@ -98,6 +75,10 @@ class CucumberPlugin extends Plugin {
98
75
  }
99
76
  })
100
77
  }
78
+
79
+ startTestSpan (testName, testSuite, childOf) {
80
+ return super.startTestSpan(testName, testSuite, {}, childOf)
81
+ }
101
82
  }
102
83
 
103
84
  module.exports = CucumberPlugin
@@ -10,7 +10,7 @@ const {
10
10
  getTestCommonTags
11
11
  } = require('../../dd-trace/src/plugins/util/test')
12
12
 
13
- const { ORIGIN_KEY } = require('../../dd-trace/src/constants')
13
+ const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
14
14
 
15
15
  const CYPRESS_STATUS_TO_TEST_STATUS = {
16
16
  passed: 'pass',
@@ -62,6 +62,7 @@ module.exports = (on, config) => {
62
62
  activeSpan = tracer.startSpan('cypress.test', {
63
63
  childOf,
64
64
  tags: {
65
+ [COMPONENT]: 'cypress',
65
66
  [ORIGIN_KEY]: CI_APP_ORIGIN,
66
67
  ...testSpanMetadata,
67
68
  ...testEnvironmentMetadata
@@ -14,7 +14,6 @@ class GoogleCloudPubsubClientPlugin extends ClientPlugin {
14
14
  resource: [cfg.method, cfg.reqOpts.name].filter(x => x).join(' '),
15
15
  kind: 'client',
16
16
  meta: {
17
- 'component': '@google-cloud/pubsub',
18
17
  'pubsub.method': cfg.method,
19
18
  'gcloud.project_id': projectId
20
19
  }
@@ -18,7 +18,6 @@ class GoogleCloudPubsubConsumerPlugin extends ConsumerPlugin {
18
18
  kind: 'consumer',
19
19
  type: 'worker',
20
20
  meta: {
21
- 'component': '@google-cloud/pubsub',
22
21
  'gcloud.project_id': subscription.pubsub.projectId,
23
22
  'pubsub.topic': topic
24
23
  },
@@ -15,7 +15,6 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
15
15
  resource: `${cfg.method} ${topic}`,
16
16
  kind: 'producer',
17
17
  meta: {
18
- 'component': '@google-cloud/pubsub',
19
18
  'gcloud.project_id': projectId,
20
19
  'pubsub.method': cfg.method, // TODO: remove
21
20
  'pubsub.topic': topic
@@ -9,6 +9,7 @@ const HTTP_HEADERS = formats.HTTP_HEADERS
9
9
  const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
10
10
  const log = require('../../dd-trace/src/log')
11
11
  const url = require('url')
12
+ const { COMPONENT, ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../dd-trace/src/constants')
12
13
 
13
14
  const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
14
15
  const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
@@ -38,6 +39,7 @@ class HttpClientPlugin extends Plugin {
38
39
  const span = this.tracer.startSpan('http.request', {
39
40
  childOf,
40
41
  tags: {
42
+ [COMPONENT]: this.constructor.name,
41
43
  'span.kind': 'client',
42
44
  'service.name': getServiceName(this.tracer, this.config, options),
43
45
  'resource.name': method,
@@ -91,9 +93,9 @@ function errorHandler (err) {
91
93
 
92
94
  if (err) {
93
95
  span.addTags({
94
- 'error.type': err.name,
95
- 'error.msg': err.message,
96
- 'error.stack': err.stack
96
+ [ERROR_TYPE]: err.name,
97
+ [ERROR_MESSAGE]: err.message,
98
+ [ERROR_STACK]: err.stack
97
99
  })
98
100
  } else {
99
101
  span.setTag('error', 1)
@@ -4,6 +4,7 @@ const Plugin = require('../../dd-trace/src/plugins/plugin')
4
4
  const { storage } = require('../../datadog-core')
5
5
  const web = require('../../dd-trace/src/plugins/util/web')
6
6
  const { incomingHttpRequestStart } = require('../../dd-trace/src/appsec/gateway/channels')
7
+ const { COMPONENT } = require('../../dd-trace/src/constants')
7
8
 
8
9
  class HttpServerPlugin extends Plugin {
9
10
  static get name () {
@@ -17,6 +18,8 @@ class HttpServerPlugin extends Plugin {
17
18
  const store = storage.getStore()
18
19
  const span = web.startSpan(this.tracer, this.config, req, res, 'http.request')
19
20
 
21
+ span.setTag(COMPONENT, this.constructor.name)
22
+
20
23
  this.enter(span, { ...store, req })
21
24
 
22
25
  const context = web.getContext(req)
@@ -9,6 +9,7 @@ const tags = require('../../../ext/tags')
9
9
  const kinds = require('../../../ext/kinds')
10
10
  const formats = require('../../../ext/formats')
11
11
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
12
+ const { COMPONENT } = require('../../dd-trace/src/constants')
12
13
  const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
13
14
 
14
15
  const HTTP_HEADERS = formats.HTTP_HEADERS
@@ -44,6 +45,7 @@ class Http2ClientPlugin extends Plugin {
44
45
  const span = this.tracer.startSpan('http.request', {
45
46
  childOf,
46
47
  tags: {
48
+ [COMPONENT]: this.constructor.name,
47
49
  [SPAN_KIND]: CLIENT,
48
50
  'service.name': getServiceName(this.tracer, this.config, sessionDetails),
49
51
  'resource.name': method,
@@ -6,6 +6,7 @@ const Plugin = require('../../dd-trace/src/plugins/plugin')
6
6
  const { storage } = require('../../datadog-core')
7
7
  const web = require('../../dd-trace/src/plugins/util/web')
8
8
  const { incomingHttpRequestStart } = require('../../dd-trace/src/appsec/gateway/channels')
9
+ const { COMPONENT } = require('../../dd-trace/src/constants')
9
10
 
10
11
  class Http2ServerPlugin extends Plugin {
11
12
  static get name () {
@@ -19,6 +20,8 @@ class Http2ServerPlugin extends Plugin {
19
20
  const store = storage.getStore()
20
21
  const span = web.startSpan(this.tracer, this.config, req, res, 'web.request')
21
22
 
23
+ span.setTag(COMPONENT, this.constructor.name)
24
+
22
25
  this.enter(span, { ...store, req })
23
26
 
24
27
  const context = web.getContext(req)
@@ -1,53 +1,28 @@
1
- const { channel } = require('diagnostics_channel')
2
-
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
1
+ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
4
2
  const { storage } = require('../../datadog-core')
5
3
 
6
4
  const {
7
- CI_APP_ORIGIN,
8
5
  TEST_STATUS,
9
6
  JEST_TEST_RUNNER,
10
7
  finishAllTraceSpans,
11
8
  getTestEnvironmentMetadata,
12
9
  getTestParentSpan,
13
- getTestCommonTags,
14
10
  getTestSessionCommonTags,
15
11
  getTestSuiteCommonTags,
16
12
  TEST_PARAMETERS,
17
13
  getCodeOwnersFileEntries,
18
- getCodeOwnersForFilename,
19
- TEST_CODE_OWNERS,
20
14
  TEST_SESSION_ID,
21
15
  TEST_SUITE_ID,
22
16
  TEST_COMMAND,
23
17
  TEST_ITR_TESTS_SKIPPED,
24
18
  TEST_CODE_COVERAGE_LINES_TOTAL
25
19
  } = require('../../dd-trace/src/plugins/util/test')
26
-
27
- const { getSkippableSuites } = require('../../dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites')
28
- const {
29
- getItrConfiguration
30
- } = require('../../dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration')
20
+ const { COMPONENT } = require('../../dd-trace/src/constants')
31
21
 
32
22
  // https://github.com/facebook/jest/blob/d6ad15b0f88a05816c2fe034dd6900d28315d570/packages/jest-worker/src/types.ts#L38
33
23
  const CHILD_MESSAGE_END = 2
34
24
 
35
- function getTestSpanMetadata (tracer, test) {
36
- const childOf = getTestParentSpan(tracer)
37
-
38
- const { suite, name, runner, testParameters } = test
39
-
40
- const commonTags = getTestCommonTags(name, suite, tracer._version)
41
-
42
- return {
43
- childOf,
44
- ...commonTags,
45
- [JEST_TEST_RUNNER]: runner,
46
- [TEST_PARAMETERS]: testParameters
47
- }
48
- }
49
-
50
- class JestPlugin extends Plugin {
25
+ class JestPlugin extends CiPlugin {
51
26
  static get name () {
52
27
  return 'jest'
53
28
  }
@@ -55,16 +30,6 @@ class JestPlugin extends Plugin {
55
30
  constructor (...args) {
56
31
  super(...args)
57
32
 
58
- const gitMetadataUploadFinishCh = channel('ci:git-metadata-upload:finish')
59
- // `gitMetadataPromise` is used to wait until git metadata is uploaded to
60
- // proceed with calculating the suites to skip
61
- // TODO: add timeout after which the promise is resolved
62
- const gitMetadataPromise = new Promise(resolve => {
63
- gitMetadataUploadFinishCh.subscribe(err => {
64
- resolve(err)
65
- })
66
- })
67
-
68
33
  // Used to handle the end of a jest worker to be able to flush
69
34
  const handler = ([message]) => {
70
35
  if (message === CHILD_MESSAGE_END) {
@@ -82,78 +47,6 @@ class JestPlugin extends Plugin {
82
47
  this.testEnvironmentMetadata = getTestEnvironmentMetadata('jest', this.config)
83
48
  this.codeOwnersEntries = getCodeOwnersFileEntries()
84
49
 
85
- const {
86
- 'git.repository_url': repositoryUrl,
87
- 'git.commit.sha': sha,
88
- 'os.version': osVersion,
89
- 'os.platform': osPlatform,
90
- 'os.architecture': osArchitecture,
91
- 'runtime.name': runtimeName,
92
- 'runtime.version': runtimeVersion,
93
- 'git.branch': gitBranch
94
- } = this.testEnvironmentMetadata
95
-
96
- this.addSub('ci:jest:configuration', ({ onResponse, onError }) => {
97
- if (!this.config.isAgentlessEnabled || !this.config.isIntelligentTestRunnerEnabled) {
98
- onResponse({})
99
- return
100
- }
101
- const testConfiguration = {
102
- url: this.config.url,
103
- site: this.config.site,
104
- env: this.tracer._env,
105
- service: this.config.service || this.tracer._service,
106
- repositoryUrl,
107
- sha,
108
- osVersion,
109
- osPlatform,
110
- osArchitecture,
111
- runtimeName,
112
- runtimeVersion,
113
- branch: gitBranch
114
- }
115
- getItrConfiguration(testConfiguration, (err, config) => {
116
- if (err) {
117
- onError(err)
118
- } else {
119
- onResponse(config)
120
- }
121
- })
122
- })
123
-
124
- this.addSub('ci:jest:test-suite:skippable', ({ onResponse, onError }) => {
125
- if (!this.config.isAgentlessEnabled || !this.config.isIntelligentTestRunnerEnabled) {
126
- return onResponse([])
127
- }
128
- // we only request after git upload has happened, if it didn't fail
129
- gitMetadataPromise.then((gitUploadError) => {
130
- if (gitUploadError) {
131
- return onError(gitUploadError)
132
- }
133
- const testConfiguration = {
134
- url: this.config.url,
135
- site: this.config.site,
136
- env: this.tracer._env,
137
- service: this.config.service || this.tracer._service,
138
- repositoryUrl,
139
- sha,
140
- osVersion,
141
- osPlatform,
142
- osArchitecture,
143
- runtimeName,
144
- runtimeVersion,
145
- branch: gitBranch
146
- }
147
- getSkippableSuites(testConfiguration, (err, skippableTests) => {
148
- if (err) {
149
- onError(err)
150
- } else {
151
- onResponse(skippableTests)
152
- }
153
- })
154
- })
155
- })
156
-
157
50
  this.addSub('ci:jest:session:start', (command) => {
158
51
  if (!this.config.isAgentlessEnabled) {
159
52
  return
@@ -165,6 +58,7 @@ class JestPlugin extends Plugin {
165
58
  const testSessionSpan = this.tracer.startSpan('jest.test_session', {
166
59
  childOf,
167
60
  tags: {
61
+ [COMPONENT]: this.constructor.name,
168
62
  ...this.testEnvironmentMetadata,
169
63
  ...testSessionSpanMetadata
170
64
  }
@@ -222,6 +116,7 @@ class JestPlugin extends Plugin {
222
116
  const testSuiteSpan = this.tracer.startSpan('jest.test_suite', {
223
117
  childOf: testSessionSpanContext,
224
118
  tags: {
119
+ [COMPONENT]: this.constructor.name,
225
120
  ...this.testEnvironmentMetadata,
226
121
  ...testSuiteMetadata
227
122
  }
@@ -292,30 +187,15 @@ class JestPlugin extends Plugin {
292
187
  suiteTags[TEST_COMMAND] = testSuiteSpan.context()._tags[TEST_COMMAND]
293
188
  }
294
189
 
295
- const {
296
- childOf,
297
- ...testSpanMetadata
298
- } = getTestSpanMetadata(this.tracer, test)
299
-
300
- const codeOwners = getCodeOwnersForFilename(test.suite, this.codeOwnersEntries)
190
+ const { suite, name, runner, testParameters } = test
301
191
 
302
- if (codeOwners) {
303
- testSpanMetadata[TEST_CODE_OWNERS] = codeOwners
192
+ const extraTags = {
193
+ [JEST_TEST_RUNNER]: runner,
194
+ [TEST_PARAMETERS]: testParameters,
195
+ ...suiteTags
304
196
  }
305
197
 
306
- const testSpan = this.tracer
307
- .startSpan('jest.test', {
308
- childOf,
309
- tags: {
310
- ...this.testEnvironmentMetadata,
311
- ...testSpanMetadata,
312
- ...suiteTags
313
- }
314
- })
315
-
316
- testSpan.context()._trace.origin = CI_APP_ORIGIN
317
-
318
- return testSpan
198
+ return super.startTestSpan(name, suite, extraTags)
319
199
  }
320
200
  }
321
201
 
@@ -1,45 +1,24 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
3
+ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
4
4
  const { storage } = require('../../datadog-core')
5
5
 
6
6
  const {
7
- CI_APP_ORIGIN,
8
- TEST_CODE_OWNERS,
9
- TEST_SUITE,
10
7
  TEST_STATUS,
11
8
  TEST_PARAMETERS,
12
9
  finishAllTraceSpans,
13
- getTestEnvironmentMetadata,
14
10
  getTestSuitePath,
15
11
  getTestParentSpan,
16
12
  getTestParametersString,
17
- getCodeOwnersFileEntries,
18
- getCodeOwnersForFilename,
19
- getTestCommonTags,
20
13
  getTestSessionCommonTags,
21
14
  getTestSuiteCommonTags,
22
15
  TEST_SUITE_ID,
23
16
  TEST_SESSION_ID,
24
17
  TEST_COMMAND
25
18
  } = require('../../dd-trace/src/plugins/util/test')
19
+ const { COMPONENT } = require('../../dd-trace/src/constants')
26
20
 
27
- function getTestSpanMetadata (tracer, test, sourceRoot) {
28
- const childOf = getTestParentSpan(tracer)
29
-
30
- const { file: testSuiteAbsolutePath } = test
31
- const fullTestName = test.fullTitle()
32
- const testSuite = getTestSuitePath(testSuiteAbsolutePath, sourceRoot)
33
-
34
- const commonTags = getTestCommonTags(fullTestName, testSuite, tracer._version)
35
-
36
- return {
37
- childOf,
38
- ...commonTags
39
- }
40
- }
41
-
42
- class MochaPlugin extends Plugin {
21
+ class MochaPlugin extends CiPlugin {
43
22
  static get name () {
44
23
  return 'mocha'
45
24
  }
@@ -49,9 +28,25 @@ class MochaPlugin extends Plugin {
49
28
 
50
29
  this._testSuites = new Map()
51
30
  this._testNameToParams = {}
52
- this.testEnvironmentMetadata = getTestEnvironmentMetadata('mocha', this.config)
53
31
  this.sourceRoot = process.cwd()
54
- this.codeOwnersEntries = getCodeOwnersFileEntries(this.sourceRoot)
32
+
33
+ this.addSub('ci:mocha:test-suite:code-coverage', ({ coverageFiles, suiteFile }) => {
34
+ if (!this.config.isAgentlessEnabled || !this.config.isIntelligentTestRunnerEnabled) {
35
+ return
36
+ }
37
+ if (!this.itrConfig || !this.itrConfig.isCodeCoverageEnabled) {
38
+ return
39
+ }
40
+ const testSuiteSpan = this._testSuites.get(suiteFile)
41
+
42
+ const relativeCoverageFiles = [...coverageFiles, suiteFile]
43
+ .map(filename => getTestSuitePath(filename, this.sourceRoot))
44
+
45
+ this.tracer._exporter.exportCoverage({
46
+ span: testSuiteSpan,
47
+ coverageFiles: relativeCoverageFiles
48
+ })
49
+ })
55
50
 
56
51
  this.addSub('ci:mocha:session:start', (command) => {
57
52
  if (!this.config.isAgentlessEnabled) {
@@ -64,6 +59,7 @@ class MochaPlugin extends Plugin {
64
59
  this.testSessionSpan = this.tracer.startSpan('mocha.test_session', {
65
60
  childOf,
66
61
  tags: {
62
+ [COMPONENT]: this.constructor.name,
67
63
  ...this.testEnvironmentMetadata,
68
64
  ...testSessionSpanMetadata
69
65
  }
@@ -83,6 +79,7 @@ class MochaPlugin extends Plugin {
83
79
  const testSuiteSpan = this.tracer.startSpan('mocha.test_suite', {
84
80
  childOf: this.testSessionSpan,
85
81
  tags: {
82
+ [COMPONENT]: this.constructor.name,
86
83
  ...this.testEnvironmentMetadata,
87
84
  ...testSuiteMetadata
88
85
  }
@@ -161,13 +158,13 @@ class MochaPlugin extends Plugin {
161
158
  finishAllTraceSpans(this.testSessionSpan)
162
159
  }
163
160
  this.tracer._exporter._writer.flush()
161
+ this.itrConfig = null
164
162
  })
165
163
  }
166
164
 
167
165
  startTestSpan (test) {
168
166
  const testSuiteTags = {}
169
167
  const testSuiteSpan = this._testSuites.get(test.parent.file)
170
-
171
168
  if (testSuiteSpan) {
172
169
  const testSuiteId = testSuiteSpan.context()._spanId.toString(10)
173
170
  testSuiteTags[TEST_SUITE_ID] = testSuiteId
@@ -179,30 +176,20 @@ class MochaPlugin extends Plugin {
179
176
  testSuiteTags[TEST_COMMAND] = this.command
180
177
  }
181
178
 
182
- const { childOf, ...testSpanMetadata } = getTestSpanMetadata(this.tracer, test, this.sourceRoot)
179
+ const { file: testSuiteAbsolutePath } = test
180
+ const fullTestName = test.fullTitle()
181
+ const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.sourceRoot)
183
182
 
184
- const testParametersString = getTestParametersString(this._testNameToParams, test.title)
185
- if (testParametersString) {
186
- testSpanMetadata[TEST_PARAMETERS] = testParametersString
183
+ const extraTags = {
184
+ ...testSuiteTags
187
185
  }
188
- const codeOwners = getCodeOwnersForFilename(testSpanMetadata[TEST_SUITE], this.codeOwnersEntries)
189
186
 
190
- if (codeOwners) {
191
- testSpanMetadata[TEST_CODE_OWNERS] = codeOwners
187
+ const testParametersString = getTestParametersString(this._testNameToParams, test.title)
188
+ if (testParametersString) {
189
+ extraTags[TEST_PARAMETERS] = testParametersString
192
190
  }
193
191
 
194
- const testSpan = this.tracer
195
- .startSpan('mocha.test', {
196
- childOf,
197
- tags: {
198
- ...this.testEnvironmentMetadata,
199
- ...testSpanMetadata,
200
- ...testSuiteTags
201
- }
202
- })
203
- testSpan.context()._trace.origin = CI_APP_ORIGIN
204
-
205
- return testSpan
192
+ return super.startTestSpan(fullTestName, testSuite, extraTags)
206
193
  }
207
194
  }
208
195
 
@@ -3,6 +3,7 @@
3
3
  const Plugin = require('../../dd-trace/src/plugins/plugin')
4
4
  const { storage } = require('../../datadog-core')
5
5
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
6
+ const { COMPONENT } = require('../../dd-trace/src/constants')
6
7
 
7
8
  class NetPlugin extends Plugin {
8
9
  static get name () {
@@ -19,6 +20,7 @@ class NetPlugin extends Plugin {
19
20
  const span = this.tracer.startSpan('ipc.connect', {
20
21
  childOf,
21
22
  tags: {
23
+ [COMPONENT]: this.constructor.name,
22
24
  'resource.name': options.path,
23
25
  'ipc.path': options.path,
24
26
  'span.kind': 'client',
@@ -45,6 +47,7 @@ class NetPlugin extends Plugin {
45
47
  const span = this.tracer.startSpan('tcp.connect', {
46
48
  childOf,
47
49
  tags: {
50
+ [COMPONENT]: this.constructor.name,
48
51
  'resource.name': [host, port].filter(val => val).join(':'),
49
52
  'tcp.remote.host': host,
50
53
  'tcp.remote.port': port,
@@ -67,6 +70,7 @@ class NetPlugin extends Plugin {
67
70
  this.addSub(`apm:net:tcp:connection`, ({ socket }) => {
68
71
  const span = storage.getStore().span
69
72
  span.addTags({
73
+ [COMPONENT]: this.constructor.name,
70
74
  'tcp.local.address': socket.localAddress,
71
75
  'tcp.local.port': socket.localPort
72
76
  })
@@ -3,6 +3,7 @@
3
3
  const Plugin = require('../../dd-trace/src/plugins/plugin')
4
4
  const { storage } = require('../../datadog-core')
5
5
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
6
+ const { COMPONENT } = require('../../dd-trace/src/constants')
6
7
 
7
8
  class NextPlugin extends Plugin {
8
9
  static get name () {
@@ -20,6 +21,7 @@ class NextPlugin extends Plugin {
20
21
  const span = this.tracer.startSpan('next.request', {
21
22
  childOf,
22
23
  tags: {
24
+ [COMPONENT]: this.constructor.name,
23
25
  'service.name': this.config.service || this.tracer._service,
24
26
  'resource.name': req.method,
25
27
  'span.type': 'web',
@@ -67,6 +69,7 @@ class NextPlugin extends Plugin {
67
69
  const req = this._requests.get(span)
68
70
 
69
71
  span.addTags({
72
+ [COMPONENT]: this.constructor.name,
70
73
  'resource.name': `${req.method} ${page}`.trim(),
71
74
  'next.page': page
72
75
  })
@@ -7,12 +7,13 @@ class PGPlugin extends DatabasePlugin {
7
7
  static get operation () { return 'query' }
8
8
  static get system () { return 'postgres' }
9
9
 
10
- start ({ params = {}, statement, processId }) {
10
+ start ({ params = {}, query, processId }) {
11
11
  const service = getServiceName(this.config, params)
12
+ const originalStatement = query.text
12
13
 
13
14
  this.startSpan('pg.query', {
14
15
  service,
15
- resource: statement,
16
+ resource: originalStatement,
16
17
  type: 'sql',
17
18
  kind: 'client',
18
19
  meta: {
@@ -24,6 +25,8 @@ class PGPlugin extends DatabasePlugin {
24
25
  'out.port': params.port
25
26
  }
26
27
  })
28
+
29
+ query.text = this.injectDbmQuery(query.text)
27
30
  }
28
31
  }
29
32
 
@@ -4,6 +4,7 @@ const web = require('../../dd-trace/src/plugins/util/web')
4
4
  const WebPlugin = require('../../datadog-plugin-web/src')
5
5
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
6
6
  const { storage } = require('../../datadog-core')
7
+ const { COMPONENT } = require('../../dd-trace/src/constants')
7
8
 
8
9
  class RouterPlugin extends WebPlugin {
9
10
  static get name () {
@@ -97,6 +98,7 @@ class RouterPlugin extends WebPlugin {
97
98
  const span = this.tracer.startSpan(`${this.constructor.name}.middleware`, {
98
99
  childOf,
99
100
  tags: {
101
+ [COMPONENT]: this.constructor.name,
100
102
  'resource.name': name || '<anonymous>'
101
103
  }
102
104
  })