dd-trace 2.4.2 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE-3rdparty.csv +1 -2
  2. package/ci/init.js +6 -0
  3. package/ci/jest/env.js +16 -3
  4. package/ext/exporters.d.ts +2 -1
  5. package/ext/exporters.js +2 -1
  6. package/index.d.ts +17 -8
  7. package/package.json +20 -23
  8. package/packages/datadog-instrumentations/index.js +14 -0
  9. package/packages/datadog-instrumentations/src/connect.js +111 -0
  10. package/packages/datadog-instrumentations/src/cypress.js +8 -0
  11. package/packages/datadog-instrumentations/src/express.js +27 -0
  12. package/packages/datadog-instrumentations/src/fastify.js +187 -0
  13. package/packages/datadog-instrumentations/src/find-my-way.js +30 -0
  14. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +100 -0
  15. package/packages/datadog-instrumentations/src/http/server.js +1 -1
  16. package/packages/datadog-instrumentations/src/jest.js +175 -0
  17. package/packages/datadog-instrumentations/src/kafkajs.js +112 -0
  18. package/packages/datadog-instrumentations/src/knex.js +20 -0
  19. package/packages/datadog-instrumentations/src/koa.js +159 -0
  20. package/packages/datadog-instrumentations/src/limitd-client.js +21 -0
  21. package/packages/datadog-instrumentations/src/oracledb.js +128 -0
  22. package/packages/datadog-instrumentations/src/paperplane.js +77 -0
  23. package/packages/datadog-instrumentations/src/pg.js +2 -2
  24. package/packages/datadog-instrumentations/src/restify.js +58 -0
  25. package/packages/datadog-instrumentations/src/rhea.js +1 -1
  26. package/packages/datadog-instrumentations/src/router.js +177 -0
  27. package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -4
  28. package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
  29. package/packages/datadog-plugin-connect/src/index.js +10 -114
  30. package/packages/datadog-plugin-cucumber/src/index.js +16 -16
  31. package/packages/datadog-plugin-cypress/src/index.js +10 -5
  32. package/packages/datadog-plugin-cypress/src/plugin.js +18 -17
  33. package/packages/datadog-plugin-dns/src/index.js +12 -1
  34. package/packages/datadog-plugin-express/src/index.js +11 -25
  35. package/packages/datadog-plugin-fastify/src/index.js +17 -4
  36. package/packages/datadog-plugin-find-my-way/src/index.js +20 -0
  37. package/packages/datadog-plugin-fs/src/index.js +2 -0
  38. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +56 -111
  39. package/packages/datadog-plugin-http/src/server.js +2 -10
  40. package/packages/datadog-plugin-jest/src/index.js +101 -3
  41. package/packages/datadog-plugin-jest/src/util.js +1 -29
  42. package/packages/datadog-plugin-kafkajs/src/index.js +64 -90
  43. package/packages/datadog-plugin-koa/src/index.js +12 -164
  44. package/packages/datadog-plugin-mocha/src/index.js +14 -15
  45. package/packages/datadog-plugin-oracledb/src/index.js +34 -100
  46. package/packages/datadog-plugin-paperplane/src/index.js +14 -100
  47. package/packages/datadog-plugin-paperplane/src/logger.js +11 -0
  48. package/packages/datadog-plugin-paperplane/src/server.js +24 -0
  49. package/packages/datadog-plugin-restify/src/index.js +13 -75
  50. package/packages/datadog-plugin-router/src/index.js +67 -164
  51. package/packages/datadog-plugin-web/src/index.js +20 -0
  52. package/packages/dd-trace/lib/version.js +1 -1
  53. package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +34 -12
  54. package/packages/dd-trace/src/appsec/index.js +7 -3
  55. package/packages/dd-trace/src/appsec/recommended.json +15 -5
  56. package/packages/dd-trace/src/appsec/reporter.js +33 -3
  57. package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
  58. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +32 -0
  59. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +51 -0
  60. package/packages/dd-trace/src/config.js +33 -4
  61. package/packages/dd-trace/src/encode/0.4.js +0 -1
  62. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +193 -0
  63. package/packages/dd-trace/src/encode/tags-processors.js +116 -0
  64. package/packages/dd-trace/src/exporter.js +3 -0
  65. package/packages/dd-trace/src/exporters/agent/index.js +1 -1
  66. package/packages/dd-trace/src/exporters/agent/writer.js +7 -32
  67. package/packages/dd-trace/src/exporters/{agent → common}/docker.js +0 -0
  68. package/packages/dd-trace/src/exporters/common/request.js +83 -0
  69. package/packages/dd-trace/src/exporters/common/writer.js +36 -0
  70. package/packages/dd-trace/src/exporters/{agent/scheduler.js → scheduler.js} +0 -0
  71. package/packages/dd-trace/src/format.js +9 -5
  72. package/packages/dd-trace/src/instrumenter.js +3 -0
  73. package/packages/dd-trace/src/pkg.js +11 -6
  74. package/packages/dd-trace/src/plugin_manager.js +13 -7
  75. package/packages/dd-trace/src/plugins/index.js +1 -2
  76. package/packages/dd-trace/src/plugins/log_plugin.js +8 -4
  77. package/packages/dd-trace/src/plugins/plugin.js +8 -0
  78. package/packages/dd-trace/src/plugins/util/test.js +79 -1
  79. package/packages/dd-trace/src/plugins/util/web.js +41 -12
  80. package/packages/dd-trace/src/profiling/config.js +8 -8
  81. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  82. package/packages/dd-trace/src/profiling/index.js +4 -4
  83. package/packages/dd-trace/src/profiling/profilers/{heap.js → space.js} +2 -2
  84. package/packages/dd-trace/src/profiling/profilers/{cpu.js → wall.js} +3 -3
  85. package/packages/dd-trace/src/proxy.js +2 -0
  86. package/packages/dd-trace/src/span_processor.js +4 -1
  87. package/packages/dd-trace/src/telemetry.js +187 -0
  88. package/scripts/install_plugin_modules.js +1 -0
  89. package/packages/datadog-plugin-fastify/src/fastify.js +0 -198
  90. package/packages/datadog-plugin-fastify/src/find-my-way.js +0 -37
  91. package/packages/datadog-plugin-jest/src/jest-environment.js +0 -272
  92. package/packages/datadog-plugin-jest/src/jest-jasmine2.js +0 -185
  93. package/packages/datadog-plugin-knex/src/index.js +0 -23
  94. package/packages/datadog-plugin-limitd-client/src/index.js +0 -30
  95. package/packages/dd-trace/src/exporters/agent/request.js +0 -86
  96. package/scripts/postpublish.js +0 -24
@@ -5,20 +5,18 @@ const { storage } = require('../../datadog-core')
5
5
 
6
6
  const {
7
7
  CI_APP_ORIGIN,
8
- TEST_TYPE,
9
- TEST_NAME,
10
- TEST_SUITE,
11
8
  TEST_SKIP_REASON,
12
- TEST_FRAMEWORK_VERSION,
13
9
  ERROR_MESSAGE,
14
10
  TEST_STATUS,
11
+ TEST_CODE_OWNERS,
15
12
  finishAllTraceSpans,
16
13
  getTestEnvironmentMetadata,
17
- getTestSuitePath
14
+ getTestSuitePath,
15
+ getCodeOwnersFileEntries,
16
+ getCodeOwnersForFilename,
17
+ getTestCommonTags
18
18
  } = require('../../dd-trace/src/plugins/util/test')
19
- const { SPAN_TYPE, RESOURCE_NAME, SAMPLING_PRIORITY } = require('../../../ext/tags')
20
- const { SAMPLING_RULE_DECISION } = require('../../dd-trace/src/constants')
21
- const { AUTO_KEEP } = require('../../../ext/priority')
19
+ const { RESOURCE_NAME } = require('../../../ext/tags')
22
20
 
23
21
  class CucumberPlugin extends Plugin {
24
22
  static get name () {
@@ -30,26 +28,28 @@ class CucumberPlugin extends Plugin {
30
28
 
31
29
  const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber', this.config)
32
30
  const sourceRoot = process.cwd()
31
+ const codeOwnersEntries = getCodeOwnersFileEntries(sourceRoot)
33
32
 
34
33
  this.addSub('ci:cucumber:run:start', ({ pickleName, pickleUri }) => {
35
34
  const store = storage.getStore()
36
35
  const childOf = store ? store.span : store
37
36
  const testSuite = getTestSuitePath(pickleUri, sourceRoot)
38
37
 
38
+ const commonTags = getTestCommonTags(pickleName, testSuite, this.tracer._version)
39
+
40
+ const codeOwners = getCodeOwnersForFilename(testSuite, codeOwnersEntries)
41
+ if (codeOwners) {
42
+ commonTags[TEST_CODE_OWNERS] = codeOwners
43
+ }
44
+
39
45
  const span = this.tracer.startSpan('cucumber.test', {
40
46
  childOf,
41
47
  tags: {
42
- [SPAN_TYPE]: 'test',
43
- [RESOURCE_NAME]: pickleName,
44
- [TEST_TYPE]: 'test',
45
- [TEST_NAME]: pickleName,
46
- [TEST_SUITE]: testSuite,
47
- [SAMPLING_RULE_DECISION]: 1,
48
- [SAMPLING_PRIORITY]: AUTO_KEEP,
49
- [TEST_FRAMEWORK_VERSION]: this.tracer._version,
48
+ ...commonTags,
50
49
  ...testEnvironmentMetadata
51
50
  }
52
51
  })
52
+
53
53
  span.context()._trace.origin = CI_APP_ORIGIN
54
54
  this.enter(span, store)
55
55
  })
@@ -1,6 +1,11 @@
1
- module.exports = [
2
- {
3
- name: 'cypress',
4
- versions: ['>=6.7.0']
1
+ const Plugin = require('../../dd-trace/src/plugins/plugin')
2
+
3
+ // Cypress plugin does not patch any library. This is just a placeholder to
4
+ // follow the structure of the plugins
5
+ class CypressPlugin extends Plugin {
6
+ static get name () {
7
+ return 'cypress'
5
8
  }
6
- ]
9
+ }
10
+
11
+ module.exports = CypressPlugin
@@ -1,18 +1,16 @@
1
1
  const {
2
- TEST_TYPE,
3
- TEST_NAME,
4
- TEST_SUITE,
5
2
  TEST_STATUS,
6
- TEST_FRAMEWORK_VERSION,
7
3
  TEST_IS_RUM_ACTIVE,
4
+ TEST_CODE_OWNERS,
8
5
  getTestEnvironmentMetadata,
9
6
  CI_APP_ORIGIN,
10
- getTestParentSpan
7
+ getTestParentSpan,
8
+ getCodeOwnersFileEntries,
9
+ getCodeOwnersForFilename,
10
+ getTestCommonTags
11
11
  } = require('../../dd-trace/src/plugins/util/test')
12
12
 
13
- const { SAMPLING_RULE_DECISION, ORIGIN_KEY } = require('../../dd-trace/src/constants')
14
- const { SAMPLING_PRIORITY, SPAN_TYPE, RESOURCE_NAME } = require('../../../ext/tags')
15
- const { AUTO_KEEP } = require('../../../ext/priority')
13
+ const { ORIGIN_KEY } = require('../../dd-trace/src/constants')
16
14
 
17
15
  const CYPRESS_STATUS_TO_TEST_STATUS = {
18
16
  passed: 'pass',
@@ -24,21 +22,20 @@ const CYPRESS_STATUS_TO_TEST_STATUS = {
24
22
  function getTestSpanMetadata (tracer, testName, testSuite, cypressConfig) {
25
23
  const childOf = getTestParentSpan(tracer)
26
24
 
25
+ const commonTags = getTestCommonTags(testName, testSuite, cypressConfig.version)
26
+
27
27
  return {
28
28
  childOf,
29
- resource: `${testSuite}.${testName}`,
30
- [TEST_TYPE]: 'test',
31
- [TEST_NAME]: testName,
32
- [TEST_SUITE]: testSuite,
33
- [SAMPLING_RULE_DECISION]: 1,
34
- [SAMPLING_PRIORITY]: AUTO_KEEP,
35
- [TEST_FRAMEWORK_VERSION]: cypressConfig.version
29
+ ...commonTags
36
30
  }
37
31
  }
38
32
 
39
33
  module.exports = (on, config) => {
40
34
  const tracer = require('../../dd-trace')
41
35
  const testEnvironmentMetadata = getTestEnvironmentMetadata('cypress')
36
+
37
+ const codeOwnersEntries = getCodeOwnersFileEntries()
38
+
42
39
  let activeSpan = null
43
40
  on('after:run', () => {
44
41
  return new Promise(resolve => {
@@ -55,12 +52,16 @@ module.exports = (on, config) => {
55
52
  ...testSpanMetadata
56
53
  } = getTestSpanMetadata(tracer, testName, testSuite, config)
57
54
 
55
+ const codeOwners = getCodeOwnersForFilename(testSuite, codeOwnersEntries)
56
+
57
+ if (codeOwners) {
58
+ testSpanMetadata[TEST_CODE_OWNERS] = codeOwners
59
+ }
60
+
58
61
  if (!activeSpan) {
59
62
  activeSpan = tracer.startSpan('cypress.test', {
60
63
  childOf,
61
64
  tags: {
62
- [SPAN_TYPE]: 'test',
63
- [RESOURCE_NAME]: resource,
64
65
  [ORIGIN_KEY]: CI_APP_ORIGIN,
65
66
  ...testSpanMetadata,
66
67
  ...testEnvironmentMetadata
@@ -44,7 +44,18 @@ class DNSPlugin extends Plugin {
44
44
  this.enter(span, store)
45
45
  }, (result) => {
46
46
  const { span } = storage.getStore()
47
- span.setTag('dns.address', result)
47
+
48
+ if (Array.isArray(result)) {
49
+ const addresses = Array.isArray(result)
50
+ ? result.map(address => address.address).sort()
51
+ : [result]
52
+
53
+ span.setTag('dns.address', addresses[0])
54
+ span.setTag('dns.addresses', addresses.join(','))
55
+ } else {
56
+ span.setTag('dns.address', result)
57
+ }
58
+
48
59
  span.finish()
49
60
  })
50
61
 
@@ -1,33 +1,19 @@
1
1
  'use strict'
2
2
 
3
- const web = require('../../dd-trace/src/plugins/util/web')
4
- const routerPlugin = require('../../datadog-plugin-router/src')
3
+ const RouterPlugin = require('../../datadog-plugin-router/src')
5
4
 
6
- function createWrapHandle (tracer, config) {
7
- config = web.normalizeConfig(config)
8
-
9
- return function wrapHandle (handle) {
10
- return function handleWithTrace (req, res) {
11
- web.instrument(tracer, config, req, res, 'express.request')
12
-
13
- return handle.apply(this, arguments)
14
- }
5
+ class ExpressPlugin extends RouterPlugin {
6
+ static get name () {
7
+ return 'express'
15
8
  }
16
- }
17
9
 
18
- function patch (express, tracer, config) {
19
- this.wrap(express.application, 'handle', createWrapHandle(tracer, config))
20
- routerPlugin.patch.call(this, { prototype: express.Router }, tracer, config)
21
- }
10
+ constructor (...args) {
11
+ super(...args)
22
12
 
23
- function unpatch (express) {
24
- this.unwrap(express.application, 'handle')
25
- routerPlugin.unpatch.call(this, { prototype: express.Router })
13
+ this.addSub('apm:express:request:handle', ({ req }) => {
14
+ this.setFramework(req, 'express', this.config)
15
+ })
16
+ }
26
17
  }
27
18
 
28
- module.exports = {
29
- name: 'express',
30
- versions: ['>=4'],
31
- patch,
32
- unpatch
33
- }
19
+ module.exports = ExpressPlugin
@@ -1,6 +1,19 @@
1
1
  'use strict'
2
2
 
3
- module.exports = [].concat(
4
- require('./fastify'),
5
- require('./find-my-way') // TODO make this its own plugin, since restify uses it too
6
- )
3
+ const RouterPlugin = require('../../datadog-plugin-router/src')
4
+
5
+ class FastifyPlugin extends RouterPlugin {
6
+ static get name () {
7
+ return 'fastify'
8
+ }
9
+
10
+ constructor (...args) {
11
+ super(...args)
12
+
13
+ this.addSub('apm:fastify:request:handle', ({ req }) => {
14
+ this.setFramework(req, 'fastify', this.config)
15
+ })
16
+ }
17
+ }
18
+
19
+ module.exports = FastifyPlugin
@@ -0,0 +1,20 @@
1
+ 'use strict'
2
+
3
+ const Plugin = require('../../dd-trace/src/plugins/plugin')
4
+ const web = require('../../dd-trace/src/plugins/util/web')
5
+
6
+ class FindMyWayPlugin extends Plugin {
7
+ static get name () {
8
+ return 'find-my-way'
9
+ }
10
+
11
+ constructor (...args) {
12
+ super(...args)
13
+
14
+ this.addSub('apm:find-my-way:request:route', ({ req, route }) => {
15
+ web.setRoute(req, route)
16
+ })
17
+ }
18
+ }
19
+
20
+ module.exports = FindMyWayPlugin
@@ -60,6 +60,7 @@ function createWrapCreateReadStream (config, tracer) {
60
60
  const tags = makeFSFlagTags('ReadStream', path, options, 'r', config, tracer)
61
61
  return tracer.trace('fs.operation', { tags, orphanable }, (span, done) => {
62
62
  const stream = createReadStream.apply(this, arguments)
63
+ stream.once('close', done)
63
64
  stream.once('end', done)
64
65
  stream.once('error', done)
65
66
  return stream
@@ -74,6 +75,7 @@ function createWrapCreateWriteStream (config, tracer) {
74
75
  const tags = makeFSFlagTags('WriteStream', path, options, 'w', config, tracer)
75
76
  return tracer.trace('fs.operation', { tags, orphanable }, (span, done) => {
76
77
  const stream = createWriteStream.apply(this, arguments)
78
+ stream.once('close', done)
77
79
  stream.once('finish', done)
78
80
  stream.once('error', done)
79
81
  return stream
@@ -1,116 +1,98 @@
1
1
  'use strict'
2
2
 
3
+ const Plugin = require('../../dd-trace/src/plugins/plugin')
4
+ const { storage } = require('../../datadog-core')
3
5
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
4
6
 
5
7
  const messageSpans = new WeakMap()
8
+ class GoogleCloudPubsubPlugin extends Plugin {
9
+ static get name () {
10
+ return 'google-cloud-pubsub'
11
+ }
12
+
13
+ constructor (...args) {
14
+ super(...args)
6
15
 
7
- function createWrapRequest (tracer, config) {
8
- return function wrapRequest (request) {
9
- return function requestWithTrace (cfg = { reqOpts: {} }, cb) {
16
+ this.addSub(`apm:google-cloud-pubsub:request:start`, ({ cfg, projectId, messages }) => {
17
+ const store = storage.getStore()
18
+ const childOf = store ? store.span : store
10
19
  const topic = getTopic(cfg)
11
20
  const tags = {
12
21
  component: '@google-cloud/pubsub',
13
22
  'resource.name': [cfg.method, topic].filter(x => x).join(' '),
14
- 'service.name': config.service || `${tracer._service}-pubsub`,
23
+ 'service.name': this.config.service || `${this.tracer._service}-pubsub`,
15
24
  'span.kind': 'client',
16
25
  'pubsub.method': cfg.method,
17
- 'gcloud.project_id': this.projectId,
26
+ 'gcloud.project_id': projectId,
18
27
  'pubsub.topic': topic
19
28
  }
20
29
  if (cfg.method === 'publish') {
21
30
  tags['span.kind'] = 'producer'
22
31
  }
23
- cb = tracer.scope().bind(cb)
24
- return tracer.trace('pubsub.request', { tags }, (span, done) => {
25
- analyticsSampler.sample(span, config.measured)
26
-
27
- if (cfg.reqOpts && cfg.method === 'publish') {
28
- for (const msg of cfg.reqOpts.messages) {
29
- if (!msg.attributes) {
30
- msg.attributes = {}
31
- }
32
- tracer.inject(span, 'text_map', msg.attributes)
33
- }
34
- }
35
-
36
- arguments[1] = function (err) {
37
- done(err)
38
- return cb.apply(this, arguments)
39
- }
40
-
41
- return request.apply(this, arguments)
32
+ const span = this.tracer.startSpan('pubsub.request', {
33
+ childOf,
34
+ tags
42
35
  })
43
- }
44
- }
45
- }
46
36
 
47
- function createWrapSubscriptionEmit (tracer, config) {
48
- return function wrapSubscriptionEmit (emit) {
49
- return function emitWithTrace (eventName, message) {
50
- if (eventName !== 'message' || !message) return emit.apply(this, arguments)
37
+ analyticsSampler.sample(span, this.config.measured)
38
+ this.enter(span, store)
51
39
 
52
- const span = messageSpans.get(message)
53
-
54
- if (!span) return emit.apply(this, arguments)
55
-
56
- return tracer.scope().activate(span, () => {
57
- try {
58
- return emit.apply(this, arguments)
59
- } catch (e) {
60
- span.setTag('error', e)
61
- throw e
40
+ for (const msg of messages) {
41
+ if (!msg.attributes) {
42
+ msg.attributes = {}
62
43
  }
63
- })
64
- }
65
- }
66
- }
44
+ this.tracer.inject(span, 'text_map', msg.attributes)
45
+ }
46
+ })
67
47
 
68
- function createWrapLeaseDispense (tracer, config) {
69
- return function wrapDispense (dispense) {
70
- return function dispenseWithTrace (message) {
48
+ this.addSub(`apm:google-cloud-pubsub:receive:start`, ({ message }) => {
49
+ const store = storage.getStore()
71
50
  const subscription = message._subscriber._subscription
72
51
  const topic = subscription.metadata && subscription.metadata.topic
52
+ const childOf = this.tracer.extract('text_map', message.attributes)
73
53
  const tags = {
74
54
  component: '@google-cloud/pubsub',
75
55
  'resource.name': topic,
76
- 'service.name': config.service || tracer._service,
56
+ 'service.name': this.config.service || this.tracer._service,
77
57
  'gcloud.project_id': subscription.pubsub.projectId,
78
58
  'pubsub.topic': topic,
79
59
  'span.kind': 'consumer',
80
60
  'span.type': 'worker'
81
61
  }
82
62
 
83
- const childOf = tracer.extract('text_map', message.attributes)
84
- const span = tracer.startSpan('pubsub.receive', { tags, childOf })
63
+ const span = this.tracer.startSpan('pubsub.receive', {
64
+ childOf,
65
+ tags
66
+ })
85
67
 
86
- analyticsSampler.sample(span, config.measured, true)
68
+ analyticsSampler.sample(span, this.config.measured, true)
69
+ this.enter(span, store)
87
70
 
88
71
  messageSpans.set(message, span)
72
+ })
89
73
 
90
- return dispense.apply(this, arguments)
91
- }
92
- }
93
- }
74
+ this.addSub(`apm:google-cloud-pubsub:request:error`, err => {
75
+ const span = storage.getStore().span
76
+ span.setTag('error', err)
77
+ })
94
78
 
95
- function createWrapLeaseRemove (tracer, config) {
96
- return function wrapRemove (remove) {
97
- return function removeWithTrace (message) {
98
- finish(message)
79
+ this.addSub(`apm:google-cloud-pubsub:request:finish`, () => {
80
+ const span = storage.getStore().span
81
+ span.finish()
82
+ })
99
83
 
100
- return remove.apply(this, arguments)
101
- }
102
- }
103
- }
104
-
105
- function createWrapLeaseClear (tracer, config) {
106
- return function wrapClear (clear) {
107
- return function clearWithTrace () {
108
- for (const message of this._messages) {
109
- finish(message)
110
- }
84
+ this.addSub(`apm:google-cloud-pubsub:receive:error`, ({ err, message }) => {
85
+ const span = messageSpans.get(message)
86
+ if (!span) return undefined
87
+ span.setTag('error', err)
88
+ })
111
89
 
112
- return clear.apply(this, arguments)
113
- }
90
+ this.addSub(`apm:google-cloud-pubsub:receive:finish`, ({ message }) => {
91
+ const span = messageSpans.get(message)
92
+ if (!span) return
93
+ span.setTag('pubsub.ack', message._handled ? 1 : 0)
94
+ span.finish()
95
+ })
114
96
  }
115
97
  }
116
98
 
@@ -120,41 +102,4 @@ function getTopic (cfg) {
120
102
  }
121
103
  }
122
104
 
123
- function finish (message) {
124
- const span = messageSpans.get(message)
125
-
126
- if (!span) return
127
-
128
- span.setTag('pubsub.ack', message._handled ? 1 : 0)
129
- span.finish()
130
- }
131
-
132
- module.exports = [
133
- {
134
- name: '@google-cloud/pubsub',
135
- versions: ['>=1.2'],
136
- patch ({ PubSub, Subscription }, tracer, config) {
137
- this.wrap(PubSub.prototype, 'request', createWrapRequest(tracer, config))
138
- this.wrap(Subscription.prototype, 'emit', createWrapSubscriptionEmit(tracer, config))
139
- },
140
- unpatch ({ PubSub, Subscription }) {
141
- this.unwrap(PubSub.prototype, 'request')
142
- this.unwrap(Subscription.prototype, 'emit')
143
- }
144
- },
145
- {
146
- name: '@google-cloud/pubsub',
147
- versions: ['>=1.2'],
148
- file: 'build/src/lease-manager.js',
149
- patch ({ LeaseManager }, tracer, config) {
150
- this.wrap(LeaseManager.prototype, '_dispense', createWrapLeaseDispense(tracer, config))
151
- this.wrap(LeaseManager.prototype, 'remove', createWrapLeaseRemove(tracer, config))
152
- this.wrap(LeaseManager.prototype, 'clear', createWrapLeaseClear(tracer, config))
153
- },
154
- unpatch ({ LeaseManager }) {
155
- this.unwrap(LeaseManager.prototype, '_dispense')
156
- this.unwrap(LeaseManager.prototype, 'remove')
157
- this.unwrap(LeaseManager.prototype, 'clear')
158
- }
159
- }
160
- ]
105
+ module.exports = GoogleCloudPubsubPlugin
@@ -4,9 +4,6 @@ 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 tags = require('../../../ext/tags')
8
- const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
9
- const SERVICE_NAME = tags.SERVICE_NAME
10
7
 
11
8
  class HttpServerPlugin extends Plugin {
12
9
  static get name () {
@@ -20,11 +17,6 @@ class HttpServerPlugin extends Plugin {
20
17
  const store = storage.getStore()
21
18
  const span = web.startSpan(this.tracer, this.config, req, res, 'http.request')
22
19
 
23
- if (this.config.service) {
24
- span.setTag(SERVICE_NAME, this.config.service)
25
- }
26
-
27
- analyticsSampler.sample(span, this.config.measured, true)
28
20
  this.enter(span, store)
29
21
 
30
22
  const context = web.getContext(req)
@@ -52,10 +44,10 @@ class HttpServerPlugin extends Plugin {
52
44
  })
53
45
  })
54
46
 
55
- this.addSub('apm:http:server:request:async-end', ({ req }) => {
47
+ this.addSub('apm:http:server:request:finish', ({ req }) => {
56
48
  const context = web.getContext(req)
57
49
 
58
- if (!context) return // Not created by a http.Server instance.
50
+ if (!context || !context.res) return // Not created by a http.Server instance.
59
51
 
60
52
  web.wrapRes(context, context.req, context.res, context.res.end)()
61
53
  })
@@ -1,4 +1,102 @@
1
- const jestEnvironment = require('./jest-environment')
2
- const jestJasmine2 = require('./jest-jasmine2')
1
+ const Plugin = require('../../dd-trace/src/plugins/plugin')
2
+ const { storage } = require('../../datadog-core')
3
3
 
4
- module.exports = [].concat(jestEnvironment, jestJasmine2)
4
+ const {
5
+ CI_APP_ORIGIN,
6
+ TEST_STATUS,
7
+ JEST_TEST_RUNNER,
8
+ finishAllTraceSpans,
9
+ getTestEnvironmentMetadata,
10
+ getTestParentSpan,
11
+ getTestCommonTags,
12
+ TEST_PARAMETERS,
13
+ getCodeOwnersFileEntries,
14
+ getCodeOwnersForFilename,
15
+ TEST_CODE_OWNERS
16
+ } = require('../../dd-trace/src/plugins/util/test')
17
+
18
+ function getTestSpanMetadata (tracer, test) {
19
+ const childOf = getTestParentSpan(tracer)
20
+
21
+ const { suite, name, runner, testParameters } = test
22
+
23
+ const commonTags = getTestCommonTags(name, suite, tracer._version)
24
+
25
+ return {
26
+ childOf,
27
+ ...commonTags,
28
+ [JEST_TEST_RUNNER]: runner,
29
+ [TEST_PARAMETERS]: testParameters
30
+ }
31
+ }
32
+
33
+ class JestPlugin extends Plugin {
34
+ static get name () {
35
+ return 'jest'
36
+ }
37
+
38
+ constructor (...args) {
39
+ super(...args)
40
+
41
+ this.testEnvironmentMetadata = getTestEnvironmentMetadata('jest', this.config)
42
+ this.codeOwnersEntries = getCodeOwnersFileEntries()
43
+
44
+ this.addSub('ci:jest:test:start', (test) => {
45
+ const store = storage.getStore()
46
+ const span = this.startTestSpan(test)
47
+
48
+ this.enter(span, store)
49
+ })
50
+
51
+ this.addSub('ci:jest:test:end', (status) => {
52
+ const span = storage.getStore().span
53
+ span.setTag(TEST_STATUS, status)
54
+ span.finish()
55
+ finishAllTraceSpans(span)
56
+ this.exit()
57
+ })
58
+
59
+ this.addSub('ci:jest:test-suite:end', () => {
60
+ this.tracer._exporter._writer.flush()
61
+ })
62
+
63
+ this.addSub('ci:jest:test:err', (error) => {
64
+ if (error) {
65
+ const span = storage.getStore().span
66
+ span.setTag(TEST_STATUS, 'fail')
67
+ span.setTag('error', error)
68
+ }
69
+ })
70
+
71
+ this.addSub('ci:jest:test:skip', (test) => {
72
+ const span = this.startTestSpan(test)
73
+ span.setTag(TEST_STATUS, 'skip')
74
+ span.finish()
75
+ })
76
+ }
77
+
78
+ startTestSpan (test) {
79
+ const { childOf, ...testSpanMetadata } = getTestSpanMetadata(this.tracer, test)
80
+
81
+ const codeOwners = getCodeOwnersForFilename(test.suite, this.codeOwnersEntries)
82
+
83
+ if (codeOwners) {
84
+ testSpanMetadata[TEST_CODE_OWNERS] = codeOwners
85
+ }
86
+
87
+ const testSpan = this.tracer
88
+ .startSpan('jest.test', {
89
+ childOf,
90
+ tags: {
91
+ ...this.testEnvironmentMetadata,
92
+ ...testSpanMetadata
93
+ }
94
+ })
95
+
96
+ testSpan.context()._trace.origin = CI_APP_ORIGIN
97
+
98
+ return testSpan
99
+ }
100
+ }
101
+
102
+ module.exports = JestPlugin
@@ -1,8 +1,3 @@
1
- const { SAMPLING_RULE_DECISION } = require('../../dd-trace/src/constants')
2
- const { SAMPLING_PRIORITY, SPAN_TYPE } = require('../../../ext/tags')
3
- const { AUTO_KEEP } = require('../../../ext/priority')
4
- const { TEST_TYPE, TEST_STATUS, getTestParentSpan } = require('../../dd-trace/src/plugins/util/test')
5
-
6
1
  /**
7
2
  * There are two ways to call `test.each` in `jest`:
8
3
  * 1. With an array of arrays: https://jestjs.io/docs/api#1-testeachtablename-fn-timeout
@@ -38,27 +33,4 @@ function getFormattedJestTestParameters (testParameters) {
38
33
  return formattedParameters
39
34
  }
40
35
 
41
- function getTestSpanTags (tracer, testEnvironmentMetadata) {
42
- const childOf = getTestParentSpan(tracer)
43
-
44
- const commonSpanTags = {
45
- [TEST_TYPE]: 'test',
46
- [SAMPLING_RULE_DECISION]: 1,
47
- [SAMPLING_PRIORITY]: AUTO_KEEP,
48
- [SPAN_TYPE]: 'test',
49
- ...testEnvironmentMetadata
50
- }
51
- return {
52
- childOf,
53
- commonSpanTags
54
- }
55
- }
56
-
57
- function setSuppressedErrors (suppressedErrors, testSpan) {
58
- if (suppressedErrors && suppressedErrors.length) {
59
- testSpan.setTag('error', suppressedErrors[0])
60
- testSpan.setTag(TEST_STATUS, 'fail')
61
- }
62
- }
63
-
64
- module.exports = { getFormattedJestTestParameters, getTestSpanTags, setSuppressedErrors }
36
+ module.exports = { getFormattedJestTestParameters }