dd-trace 3.15.0 → 3.17.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 (180) hide show
  1. package/LICENSE-3rdparty.csv +2 -2
  2. package/README.md +53 -0
  3. package/ci/init.js +9 -1
  4. package/ext/exporters.d.ts +2 -1
  5. package/ext/exporters.js +2 -1
  6. package/index.d.ts +6 -2
  7. package/package.json +24 -19
  8. package/packages/datadog-esbuild/index.js +104 -0
  9. package/packages/datadog-instrumentations/src/cucumber.js +80 -3
  10. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +100 -27
  11. package/packages/datadog-instrumentations/src/helpers/hook.js +13 -3
  12. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  13. package/packages/datadog-instrumentations/src/helpers/instrument.js +6 -0
  14. package/packages/datadog-instrumentations/src/helpers/register.js +2 -2
  15. package/packages/datadog-instrumentations/src/jest.js +35 -3
  16. package/packages/datadog-instrumentations/src/mariadb.js +130 -11
  17. package/packages/datadog-instrumentations/src/mocha.js +30 -6
  18. package/packages/datadog-instrumentations/src/mongodb-core.js +8 -2
  19. package/packages/datadog-instrumentations/src/mongoose.js +1 -1
  20. package/packages/datadog-instrumentations/src/next.js +32 -4
  21. package/packages/datadog-instrumentations/src/pg.js +16 -11
  22. package/packages/datadog-instrumentations/src/playwright.js +2 -2
  23. package/packages/datadog-plugin-amqp10/src/consumer.js +1 -1
  24. package/packages/datadog-plugin-amqp10/src/index.js +1 -1
  25. package/packages/datadog-plugin-amqp10/src/producer.js +3 -2
  26. package/packages/datadog-plugin-amqplib/src/client.js +3 -2
  27. package/packages/datadog-plugin-amqplib/src/consumer.js +1 -1
  28. package/packages/datadog-plugin-amqplib/src/index.js +1 -1
  29. package/packages/datadog-plugin-amqplib/src/producer.js +3 -2
  30. package/packages/datadog-plugin-aws-sdk/src/base.js +7 -2
  31. package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
  32. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +2 -0
  33. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +2 -0
  34. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -0
  35. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -0
  36. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +2 -0
  37. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +2 -0
  38. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +2 -0
  39. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -0
  40. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -0
  41. package/packages/datadog-plugin-bunyan/src/index.js +1 -1
  42. package/packages/datadog-plugin-cassandra-driver/src/index.js +3 -2
  43. package/packages/datadog-plugin-connect/src/index.js +1 -1
  44. package/packages/datadog-plugin-couchbase/src/index.js +1 -1
  45. package/packages/datadog-plugin-cucumber/src/index.js +33 -6
  46. package/packages/datadog-plugin-cypress/src/index.js +1 -1
  47. package/packages/datadog-plugin-cypress/src/plugin.js +40 -33
  48. package/packages/datadog-plugin-dns/src/index.js +1 -1
  49. package/packages/datadog-plugin-dns/src/lookup.js +1 -1
  50. package/packages/datadog-plugin-dns/src/lookup_service.js +1 -1
  51. package/packages/datadog-plugin-dns/src/resolve.js +1 -1
  52. package/packages/datadog-plugin-dns/src/reverse.js +1 -1
  53. package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
  54. package/packages/datadog-plugin-express/src/index.js +1 -1
  55. package/packages/datadog-plugin-fastify/src/index.js +1 -1
  56. package/packages/datadog-plugin-find-my-way/src/index.js +1 -1
  57. package/packages/datadog-plugin-fs/src/index.js +1 -1
  58. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +5 -5
  59. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -1
  60. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +1 -1
  61. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +7 -6
  62. package/packages/datadog-plugin-graphql/src/execute.js +1 -1
  63. package/packages/datadog-plugin-graphql/src/index.js +1 -1
  64. package/packages/datadog-plugin-graphql/src/parse.js +1 -1
  65. package/packages/datadog-plugin-graphql/src/resolve.js +1 -1
  66. package/packages/datadog-plugin-graphql/src/validate.js +1 -1
  67. package/packages/datadog-plugin-grpc/src/client.js +1 -1
  68. package/packages/datadog-plugin-grpc/src/index.js +1 -1
  69. package/packages/datadog-plugin-grpc/src/server.js +1 -1
  70. package/packages/datadog-plugin-hapi/src/index.js +1 -1
  71. package/packages/datadog-plugin-http/src/client.js +2 -2
  72. package/packages/datadog-plugin-http/src/index.js +1 -1
  73. package/packages/datadog-plugin-http/src/server.js +2 -2
  74. package/packages/datadog-plugin-http2/src/client.js +4 -3
  75. package/packages/datadog-plugin-http2/src/index.js +1 -1
  76. package/packages/datadog-plugin-http2/src/server.js +2 -2
  77. package/packages/datadog-plugin-ioredis/src/index.js +1 -1
  78. package/packages/datadog-plugin-jest/src/index.js +53 -19
  79. package/packages/datadog-plugin-kafkajs/src/consumer.js +1 -1
  80. package/packages/datadog-plugin-kafkajs/src/index.js +1 -1
  81. package/packages/datadog-plugin-kafkajs/src/producer.js +1 -1
  82. package/packages/datadog-plugin-koa/src/index.js +1 -1
  83. package/packages/datadog-plugin-mariadb/src/index.js +18 -1
  84. package/packages/datadog-plugin-memcached/src/index.js +3 -2
  85. package/packages/datadog-plugin-microgateway-core/src/index.js +1 -1
  86. package/packages/datadog-plugin-mocha/src/index.js +13 -9
  87. package/packages/datadog-plugin-moleculer/src/client.js +1 -1
  88. package/packages/datadog-plugin-moleculer/src/index.js +1 -1
  89. package/packages/datadog-plugin-moleculer/src/server.js +1 -1
  90. package/packages/datadog-plugin-mongodb-core/src/index.js +1 -1
  91. package/packages/datadog-plugin-mysql/src/index.js +3 -2
  92. package/packages/datadog-plugin-mysql2/src/index.js +1 -1
  93. package/packages/datadog-plugin-net/src/index.js +9 -75
  94. package/packages/datadog-plugin-net/src/ipc.js +1 -1
  95. package/packages/datadog-plugin-net/src/tcp.js +3 -2
  96. package/packages/datadog-plugin-next/src/index.js +3 -3
  97. package/packages/datadog-plugin-opensearch/src/index.js +1 -1
  98. package/packages/datadog-plugin-oracledb/src/index.js +3 -2
  99. package/packages/datadog-plugin-paperplane/src/index.js +1 -1
  100. package/packages/datadog-plugin-paperplane/src/logger.js +1 -1
  101. package/packages/datadog-plugin-paperplane/src/server.js +1 -1
  102. package/packages/datadog-plugin-pg/src/index.js +3 -2
  103. package/packages/datadog-plugin-pino/src/index.js +1 -1
  104. package/packages/datadog-plugin-playwright/src/index.js +5 -4
  105. package/packages/datadog-plugin-redis/src/index.js +3 -2
  106. package/packages/datadog-plugin-restify/src/index.js +1 -1
  107. package/packages/datadog-plugin-rhea/src/consumer.js +1 -1
  108. package/packages/datadog-plugin-rhea/src/index.js +1 -1
  109. package/packages/datadog-plugin-rhea/src/producer.js +3 -2
  110. package/packages/datadog-plugin-router/src/index.js +8 -8
  111. package/packages/datadog-plugin-sharedb/src/index.js +1 -1
  112. package/packages/datadog-plugin-tedious/src/index.js +3 -2
  113. package/packages/datadog-plugin-web/src/index.js +1 -1
  114. package/packages/datadog-plugin-winston/src/index.js +1 -1
  115. package/packages/dd-trace/src/appsec/{templates/blocked.html → blocked_templates.js} +19 -1
  116. package/packages/dd-trace/src/appsec/blocking.js +9 -24
  117. package/packages/dd-trace/src/appsec/gateway/engine/runner.js +2 -1
  118. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +2 -0
  119. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +12 -0
  120. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
  121. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +11 -5
  122. package/packages/dd-trace/src/appsec/iast/iast-log.js +111 -0
  123. package/packages/dd-trace/src/appsec/iast/index.js +8 -4
  124. package/packages/dd-trace/src/appsec/iast/path-line.js +3 -6
  125. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +11 -2
  126. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +11 -0
  127. package/packages/dd-trace/src/appsec/iast/taint-tracking/origin-types.js +2 -0
  128. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -0
  129. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -3
  130. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +5 -3
  131. package/packages/dd-trace/src/appsec/iast/telemetry/log_collector.js +96 -0
  132. package/packages/dd-trace/src/appsec/iast/telemetry/logs.js +87 -0
  133. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +27 -2
  134. package/packages/dd-trace/src/appsec/index.js +4 -18
  135. package/packages/dd-trace/src/appsec/recommended.json +43 -14
  136. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -1
  137. package/packages/dd-trace/src/appsec/sdk/index.js +2 -2
  138. package/packages/dd-trace/src/ci-visibility/encode/json-encoder.js +27 -0
  139. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +2 -9
  140. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +7 -7
  141. package/packages/dd-trace/src/ci-visibility/exporters/jest-worker/index.js +33 -0
  142. package/packages/dd-trace/src/ci-visibility/exporters/jest-worker/writer.js +37 -0
  143. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +8 -2
  144. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +8 -2
  145. package/packages/dd-trace/src/config.js +44 -22
  146. package/packages/dd-trace/src/constants.js +2 -1
  147. package/packages/dd-trace/src/datastreams/encoding.js +80 -0
  148. package/packages/dd-trace/src/dcitm.js +51 -0
  149. package/packages/dd-trace/src/exporter.js +7 -9
  150. package/packages/dd-trace/src/exporters/common/agents.js +42 -0
  151. package/packages/dd-trace/src/exporters/common/docker.js +4 -1
  152. package/packages/dd-trace/src/exporters/common/request.js +1 -4
  153. package/packages/dd-trace/src/lambda/handler.js +14 -6
  154. package/packages/dd-trace/src/opentracing/propagation/log.js +23 -7
  155. package/packages/dd-trace/src/opentracing/propagation/text_map.js +28 -2
  156. package/packages/dd-trace/src/opentracing/span.js +19 -3
  157. package/packages/dd-trace/src/opentracing/span_context.js +3 -1
  158. package/packages/dd-trace/src/opentracing/tracer.js +3 -1
  159. package/packages/dd-trace/src/plugin_manager.js +7 -7
  160. package/packages/dd-trace/src/plugins/ci_plugin.js +16 -16
  161. package/packages/dd-trace/src/plugins/index.js +1 -0
  162. package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
  163. package/packages/dd-trace/src/plugins/outgoing.js +2 -1
  164. package/packages/dd-trace/src/plugins/tracing.js +1 -1
  165. package/packages/dd-trace/src/plugins/util/ci.js +12 -0
  166. package/packages/dd-trace/src/plugins/util/ip_extractor.js +23 -27
  167. package/packages/dd-trace/src/plugins/util/test.js +26 -7
  168. package/packages/dd-trace/src/profiling/config.js +87 -20
  169. package/packages/dd-trace/src/profiling/constants.js +16 -0
  170. package/packages/dd-trace/src/profiling/exporter_cli.js +62 -0
  171. package/packages/dd-trace/src/profiling/exporters/agent.js +2 -1
  172. package/packages/dd-trace/src/profiling/profiler.js +21 -8
  173. package/packages/dd-trace/src/profiling/profilers/space.js +21 -1
  174. package/packages/dd-trace/src/span_sampler.js +3 -2
  175. package/packages/dd-trace/src/telemetry/index.js +16 -2
  176. package/packages/dd-trace/src/util.js +10 -1
  177. package/scripts/install_plugin_modules.js +5 -1
  178. package/packages/dd-trace/src/appsec/templates/blocked.json +0 -8
  179. package/scripts/junit_report.js +0 -25
  180. package/scripts/tdd.js +0 -34
@@ -132,7 +132,7 @@ class TextMapPropagator {
132
132
  const hasB3multi = this._hasPropagationStyle('inject', 'b3multi')
133
133
  if (!(hasB3 || hasB3multi)) return
134
134
 
135
- carrier[b3TraceKey] = spanContext._traceId.toString(16)
135
+ carrier[b3TraceKey] = this._getB3TraceId(spanContext)
136
136
  carrier[b3SpanKey] = spanContext._spanId.toString(16)
137
137
  carrier[b3SampledKey] = spanContext._sampling.priority >= AUTO_KEEP ? '1' : '0'
138
138
 
@@ -149,7 +149,7 @@ class TextMapPropagator {
149
149
  const hasB3SingleHeader = this._hasPropagationStyle('inject', 'b3 single header')
150
150
  if (!hasB3SingleHeader) return null
151
151
 
152
- const traceId = spanContext._traceId.toString(16)
152
+ const traceId = this._getB3TraceId(spanContext)
153
153
  const spanId = spanContext._spanId.toString(16)
154
154
  const sampled = spanContext._sampling.priority >= AUTO_KEEP ? '1' : '0'
155
155
 
@@ -277,6 +277,8 @@ class TextMapPropagator {
277
277
  spanContext._sampling.priority = priority
278
278
  }
279
279
 
280
+ this._extract128BitTraceId(b3[b3TraceKey], spanContext)
281
+
280
282
  return spanContext
281
283
  }
282
284
 
@@ -321,6 +323,8 @@ class TextMapPropagator {
321
323
  tracestate
322
324
  })
323
325
 
326
+ this._extract128BitTraceId(traceId, spanContext)
327
+
324
328
  tracestate.forVendor('dd', state => {
325
329
  for (const [key, value] of state.entries()) {
326
330
  switch (key) {
@@ -484,6 +488,20 @@ class TextMapPropagator {
484
488
  }
485
489
  }
486
490
 
491
+ _extract128BitTraceId (traceId, spanContext) {
492
+ if (!spanContext) return
493
+
494
+ const buffer = spanContext._traceId.toBuffer()
495
+
496
+ if (buffer.length !== 16) return
497
+
498
+ const tid = traceId.substring(0, 16)
499
+
500
+ if (tid === '0000000000000000') return
501
+
502
+ spanContext._trace.tags['_dd.p.tid'] = tid
503
+ }
504
+
487
505
  _validateTagKey (key) {
488
506
  return tagKeyExpr.test(key)
489
507
  }
@@ -501,6 +519,14 @@ class TextMapPropagator {
501
519
  return AUTO_REJECT
502
520
  }
503
521
  }
522
+
523
+ _getB3TraceId (spanContext) {
524
+ if (spanContext._traceId.toBuffer().length <= 8 && spanContext._trace.tags['_dd.p.tid']) {
525
+ return spanContext._trace.tags['_dd.p.tid'] + spanContext._traceId.toString(16)
526
+ }
527
+
528
+ return spanContext._traceId.toString(16)
529
+ }
504
530
  }
505
531
 
506
532
  module.exports = TextMapPropagator
@@ -32,9 +32,14 @@ class DatadogSpan {
32
32
  this._processor = processor
33
33
  this._prioritySampler = prioritySampler
34
34
  this._store = storage.getStore()
35
+ this._duration = undefined
36
+
37
+ // For internal use only. You probably want `context()._name`.
38
+ // This name property is not updated when the span name changes.
39
+ // This is necessary for span count metrics.
35
40
  this._name = operationName
36
41
 
37
- this._spanContext = this._createContext(parent)
42
+ this._spanContext = this._createContext(parent, fields)
38
43
  this._spanContext._name = operationName
39
44
  this._spanContext._tags = tags
40
45
  this._spanContext._hostname = hostname
@@ -140,7 +145,7 @@ class DatadogSpan {
140
145
  this._processor.process(this)
141
146
  }
142
147
 
143
- _createContext (parent) {
148
+ _createContext (parent, fields) {
144
149
  let spanContext
145
150
 
146
151
  if (parent) {
@@ -153,16 +158,27 @@ class DatadogSpan {
153
158
  trace: parent._trace,
154
159
  tracestate: parent._tracestate
155
160
  })
161
+
162
+ if (!spanContext._trace.startTime) {
163
+ spanContext._trace.startTime = dateNow()
164
+ }
156
165
  } else {
157
166
  const spanId = id()
167
+ const startTime = dateNow()
158
168
  spanContext = new SpanContext({
159
169
  traceId: spanId,
160
170
  spanId
161
171
  })
172
+ spanContext._trace.startTime = startTime
173
+
174
+ if (fields.traceId128BitGenerationEnabled) {
175
+ spanContext._trace.tags['_dd.p.tid'] = Math.floor(startTime / 1000).toString(16)
176
+ .padStart(8, '0')
177
+ .padEnd(16, '0')
178
+ }
162
179
  }
163
180
 
164
181
  spanContext._trace.started.push(this)
165
- spanContext._trace.startTime = spanContext._trace.startTime || dateNow()
166
182
  spanContext._trace.ticks = spanContext._trace.ticks || now()
167
183
 
168
184
  return spanContext
@@ -34,7 +34,9 @@ class DatadogSpanContext {
34
34
 
35
35
  toTraceparent () {
36
36
  const flags = this._sampling.priority >= AUTO_KEEP ? '01' : '00'
37
- const traceId = this._traceId.toString(16).padStart(32, '0')
37
+ const traceId = this._traceId.toBuffer().length <= 8 && this._trace.tags['_dd.p.tid']
38
+ ? this._trace.tags['_dd.p.tid'] + this._traceId.toString(16).padStart(16, '0')
39
+ : this._traceId.toString(16).padStart(32, '0')
38
40
  const spanId = this._spanId.toString(16).padStart(16, '0')
39
41
  const version = (this._traceparent && this._traceparent.version) || '00'
40
42
  return `${version}-${traceId}-${spanId}-${flags}`
@@ -33,6 +33,7 @@ class DatadogTracer {
33
33
  this._processor = new SpanProcessor(this._exporter, this._prioritySampler, config)
34
34
  this._url = this._exporter._url
35
35
  this._enableGetRumData = config.experimental.enableGetRumData
36
+ this._traceId128BitGenerationEnabled = config.traceId128BitGenerationEnabled
36
37
  this._propagators = {
37
38
  [formats.TEXT_MAP]: new TextMapPropagator(config),
38
39
  [formats.HTTP_HEADERS]: new HttpPropagator(config),
@@ -58,7 +59,8 @@ class DatadogTracer {
58
59
  parent,
59
60
  tags,
60
61
  startTime: options.startTime,
61
- hostname: this._hostname
62
+ hostname: this._hostname,
63
+ traceId128BitGenerationEnabled: this._traceId128BitGenerationEnabled
62
64
  }, this._debug)
63
65
 
64
66
  span.addTags(this._tags)
@@ -28,17 +28,17 @@ loadChannel.subscribe(({ name }) => {
28
28
  const Plugin = plugins[name]
29
29
 
30
30
  if (!Plugin || typeof Plugin !== 'function') return
31
- if (!pluginClasses[Plugin.name]) {
32
- const envName = `DD_TRACE_${Plugin.name.toUpperCase()}_ENABLED`
31
+ if (!pluginClasses[Plugin.id]) {
32
+ const envName = `DD_TRACE_${Plugin.id.toUpperCase()}_ENABLED`
33
33
  const enabled = process.env[envName.replace(/[^a-z0-9_]/ig, '_')]
34
34
 
35
35
  // TODO: remove the need to load the plugin class in order to disable the plugin
36
- if (isFalse(enabled) || disabledPlugins.has(Plugin.name)) {
37
- log.debug(`Plugin "${Plugin.name}" was disabled via configuration option.`)
36
+ if (isFalse(enabled) || disabledPlugins.has(Plugin.id)) {
37
+ log.debug(`Plugin "${Plugin.id}" was disabled via configuration option.`)
38
38
 
39
- pluginClasses[Plugin.name] = null
39
+ pluginClasses[Plugin.id] = null
40
40
  } else {
41
- pluginClasses[Plugin.name] = Plugin
41
+ pluginClasses[Plugin.id] = Plugin
42
42
  }
43
43
  }
44
44
  })
@@ -56,7 +56,7 @@ module.exports = class PluginManager {
56
56
 
57
57
  if (!Plugin || typeof Plugin !== 'function') return
58
58
 
59
- this.loadPlugin(Plugin.name)
59
+ this.loadPlugin(Plugin.id)
60
60
  }
61
61
 
62
62
  loadChannel.subscribe(this._loadedSubscriber)
@@ -12,7 +12,7 @@ const {
12
12
  TEST_MODULE_ID,
13
13
  TEST_SESSION_ID,
14
14
  TEST_COMMAND,
15
- TEST_BUNDLE
15
+ TEST_MODULE
16
16
  } = require('./util/test')
17
17
  const Plugin = require('./plugin')
18
18
  const { COMPONENT } = require('../constants')
@@ -22,13 +22,13 @@ module.exports = class CiPlugin extends Plugin {
22
22
  constructor (...args) {
23
23
  super(...args)
24
24
 
25
- this.addSub(`ci:${this.constructor.name}:itr-configuration`, ({ onDone }) => {
25
+ this.addSub(`ci:${this.constructor.id}:itr-configuration`, ({ onDone }) => {
26
26
  if (!this.tracer._exporter || !this.tracer._exporter.getItrConfiguration) {
27
27
  return onDone({ err: new Error('CI Visibility was not initialized correctly') })
28
28
  }
29
29
  this.tracer._exporter.getItrConfiguration(this.testConfiguration, (err, itrConfig) => {
30
30
  if (err) {
31
- log.error(`Error fetching intelligent test runner configuration: ${err.message}`)
31
+ log.error(`Intelligent Test Runner configuration could not be fetched. ${err.message}`)
32
32
  } else {
33
33
  this.itrConfig = itrConfig
34
34
  }
@@ -36,40 +36,40 @@ module.exports = class CiPlugin extends Plugin {
36
36
  })
37
37
  })
38
38
 
39
- this.addSub(`ci:${this.constructor.name}:test-suite:skippable`, ({ onDone }) => {
39
+ this.addSub(`ci:${this.constructor.id}:test-suite:skippable`, ({ onDone }) => {
40
40
  if (!this.tracer._exporter || !this.tracer._exporter.getSkippableSuites) {
41
41
  return onDone({ err: new Error('CI Visibility was not initialized correctly') })
42
42
  }
43
43
  this.tracer._exporter.getSkippableSuites(this.testConfiguration, (err, skippableSuites) => {
44
44
  if (err) {
45
- log.error(`Error fetching skippable suites: ${err.message}`)
45
+ log.error(`Skippable suites could not be fetched. ${err.message}`)
46
46
  }
47
47
  onDone({ err, skippableSuites })
48
48
  })
49
49
  })
50
50
 
51
- this.addSub(`ci:${this.constructor.name}:session:start`, ({ command, frameworkVersion, rootDir }) => {
51
+ this.addSub(`ci:${this.constructor.id}:session:start`, ({ command, frameworkVersion, rootDir }) => {
52
52
  const childOf = getTestParentSpan(this.tracer)
53
- const testSessionSpanMetadata = getTestSessionCommonTags(command, frameworkVersion)
54
- const testModuleSpanMetadata = getTestModuleCommonTags(command, frameworkVersion)
53
+ const testSessionSpanMetadata = getTestSessionCommonTags(command, frameworkVersion, this.constructor.id)
54
+ const testModuleSpanMetadata = getTestModuleCommonTags(command, frameworkVersion, this.constructor.id)
55
55
 
56
56
  this.command = command
57
57
  this.frameworkVersion = frameworkVersion
58
58
  // only for playwright
59
59
  this.rootDir = rootDir
60
60
 
61
- this.testSessionSpan = this.tracer.startSpan(`${this.constructor.name}.test_session`, {
61
+ this.testSessionSpan = this.tracer.startSpan(`${this.constructor.id}.test_session`, {
62
62
  childOf,
63
63
  tags: {
64
- [COMPONENT]: this.constructor.name,
64
+ [COMPONENT]: this.constructor.id,
65
65
  ...this.testEnvironmentMetadata,
66
66
  ...testSessionSpanMetadata
67
67
  }
68
68
  })
69
- this.testModuleSpan = this.tracer.startSpan(`${this.constructor.name}.test_module`, {
69
+ this.testModuleSpan = this.tracer.startSpan(`${this.constructor.id}.test_module`, {
70
70
  childOf: this.testSessionSpan,
71
71
  tags: {
72
- [COMPONENT]: this.constructor.name,
72
+ [COMPONENT]: this.constructor.id,
73
73
  ...this.testEnvironmentMetadata,
74
74
  ...testModuleSpanMetadata
75
75
  }
@@ -79,7 +79,7 @@ module.exports = class CiPlugin extends Plugin {
79
79
 
80
80
  configure (config) {
81
81
  super.configure(config)
82
- this.testEnvironmentMetadata = getTestEnvironmentMetadata(this.constructor.name, this.config)
82
+ this.testEnvironmentMetadata = getTestEnvironmentMetadata(this.constructor.id, this.config)
83
83
  this.codeOwnersEntries = getCodeOwnersFileEntries()
84
84
 
85
85
  const {
@@ -110,7 +110,7 @@ module.exports = class CiPlugin extends Plugin {
110
110
 
111
111
  let testTags = {
112
112
  ...getTestCommonTags(testName, testSuite, this.frameworkVersion),
113
- [COMPONENT]: this.constructor.name,
113
+ [COMPONENT]: this.constructor.id,
114
114
  ...extraTags
115
115
  }
116
116
 
@@ -129,7 +129,7 @@ module.exports = class CiPlugin extends Plugin {
129
129
  [TEST_SUITE_ID]: testSuiteSpan.context().toSpanId(),
130
130
  [TEST_SESSION_ID]: testSuiteSpan.context().toTraceId(),
131
131
  [TEST_COMMAND]: testSuiteSpan.context()._tags[TEST_COMMAND],
132
- [TEST_BUNDLE]: testSuiteSpan.context()._tags[TEST_COMMAND]
132
+ [TEST_MODULE]: this.constructor.id
133
133
  }
134
134
  if (testSuiteSpan.context()._parentId) {
135
135
  suiteTags[TEST_MODULE_ID] = testSuiteSpan.context()._parentId.toString(10)
@@ -142,7 +142,7 @@ module.exports = class CiPlugin extends Plugin {
142
142
  }
143
143
 
144
144
  const testSpan = this.tracer
145
- .startSpan(`${this.constructor.name}.test`, {
145
+ .startSpan(`${this.constructor.id}.test`, {
146
146
  childOf,
147
147
  tags: {
148
148
  ...this.testEnvironmentMetadata,
@@ -39,6 +39,7 @@ module.exports = {
39
39
  get 'jest-environment-node' () { return require('../../../datadog-plugin-jest/src') },
40
40
  get 'jest-environment-jsdom' () { return require('../../../datadog-plugin-jest/src') },
41
41
  get 'jest-jasmine2' () { return require('../../../datadog-plugin-jest/src') },
42
+ get 'jest-worker' () { return require('../../../datadog-plugin-jest/src') },
42
43
  get 'koa' () { return require('../../../datadog-plugin-koa/src') },
43
44
  get 'koa-router' () { return require('../../../datadog-plugin-koa/src') },
44
45
  get 'kafkajs' () { return require('../../../datadog-plugin-kafkajs/src') },
@@ -39,7 +39,7 @@ module.exports = class LogPlugin extends Plugin {
39
39
  constructor (...args) {
40
40
  super(...args)
41
41
 
42
- this.addSub(`apm:${this.constructor.name}:log`, (arg) => {
42
+ this.addSub(`apm:${this.constructor.id}:log`, (arg) => {
43
43
  const store = storage.getStore()
44
44
  const span = store && store.span
45
45
 
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ const { CLIENT_PORT_KEY } = require('../constants')
3
4
  const TracingPlugin = require('./tracing')
4
5
 
5
6
  // TODO: Exit span on finish when AsyncResource instances are removed.
@@ -23,7 +24,7 @@ class OutgoingPlugin extends TracingPlugin {
23
24
 
24
25
  span.addTags({
25
26
  'out.host': hostname,
26
- 'out.port': port
27
+ [CLIENT_PORT_KEY]: port
27
28
  })
28
29
  }
29
30
  }
@@ -9,7 +9,7 @@ class TracingPlugin extends Plugin {
9
9
  constructor (...args) {
10
10
  super(...args)
11
11
 
12
- this.component = this.constructor.component || this.constructor.name
12
+ this.component = this.constructor.component || this.constructor.id
13
13
  this.operation = this.constructor.operation
14
14
 
15
15
  this.addTraceSub('start', message => {
@@ -534,6 +534,18 @@ module.exports = {
534
534
  }
535
535
  }
536
536
 
537
+ if (env.TEAMCITY_VERSION) {
538
+ const { BUILD_URL, TEAMCITY_BUILDCONF_NAME, DATADOG_BUILD_ID } = env
539
+ tags = {
540
+ [CI_PROVIDER_NAME]: 'teamcity',
541
+ [CI_JOB_URL]: BUILD_URL,
542
+ [CI_JOB_NAME]: TEAMCITY_BUILDCONF_NAME,
543
+ [CI_ENV_VARS]: JSON.stringify({
544
+ DATADOG_BUILD_ID
545
+ })
546
+ }
547
+ }
548
+
537
549
  normalizeTag(tags, CI_WORKSPACE_PATH, resolveTilde)
538
550
  normalizeTag(tags, GIT_REPOSITORY_URL, filterSensitiveInfoFromRepository)
539
551
  normalizeTag(tags, GIT_BRANCH, normalizeRef)
@@ -2,18 +2,18 @@
2
2
 
3
3
  const BlockList = require('./ip_blocklist')
4
4
  const net = require('net')
5
- const log = require('../../log')
6
5
 
7
6
  const ipHeaderList = [
8
7
  'x-forwarded-for',
9
8
  'x-real-ip',
10
- 'client-ip',
9
+ 'true-client-ip',
10
+ 'x-client-ip',
11
11
  'x-forwarded',
12
- 'x-cluster-client-ip',
13
12
  'forwarded-for',
14
- 'forwarded',
15
- 'via',
16
- 'true-client-ip'
13
+ 'x-cluster-client-ip',
14
+ 'fastly-client-ip',
15
+ 'cf-connecting-ip',
16
+ 'cf-connecting-ipv6'
17
17
  ]
18
18
 
19
19
  const privateCIDRs = [
@@ -41,36 +41,31 @@ function extractIp (config, req) {
41
41
  const headers = req.headers
42
42
  if (config.clientIpHeader) {
43
43
  if (!headers) return
44
- const header = headers[config.clientIpHeader]
45
- if (!header) return
46
44
 
47
- return findFirstIp(header)
45
+ const ip = findFirstIp(headers[config.clientIpHeader])
46
+ return ip.public || ip.private
48
47
  }
49
48
 
50
- const foundHeaders = []
49
+ let firstPrivateIp
51
50
  if (headers) {
52
51
  for (let i = 0; i < ipHeaderList.length; i++) {
53
- if (headers[ipHeaderList[i]]) {
54
- foundHeaders.push(ipHeaderList[i])
52
+ const firstIp = findFirstIp(headers[ipHeaderList[i]])
53
+
54
+ if (firstIp.public) {
55
+ return firstIp.public
56
+ } else if (!firstPrivateIp && firstIp.private) {
57
+ firstPrivateIp = firstIp.private
55
58
  }
56
59
  }
57
60
  }
58
61
 
59
- if (foundHeaders.length === 1) {
60
- const header = headers[foundHeaders[0]]
61
- const firstIp = findFirstIp(header)
62
-
63
- if (firstIp) return firstIp
64
- } else if (foundHeaders.length > 1) {
65
- log.error(`Cannot find client IP: multiple IP headers detected ${foundHeaders}`)
66
- return
67
- }
68
-
69
- return req.socket && req.socket.remoteAddress
62
+ return firstPrivateIp || (req.socket && req.socket.remoteAddress)
70
63
  }
71
64
 
72
65
  function findFirstIp (str) {
73
- let firstPrivateIp
66
+ const result = {}
67
+ if (!str) return result
68
+
74
69
  const splitted = str.split(',')
75
70
 
76
71
  for (let i = 0; i < splitted.length; i++) {
@@ -83,14 +78,15 @@ function findFirstIp (str) {
83
78
 
84
79
  if (!privateIPMatcher.check(chunk, type === 6 ? 'ipv6' : 'ipv4')) {
85
80
  // it's public, return it immediately
86
- return chunk
81
+ result.public = chunk
82
+ break
87
83
  }
88
84
 
89
85
  // it's private, only save the first one found
90
- if (!firstPrivateIp) firstPrivateIp = chunk
86
+ if (!result.private) result.private = chunk
91
87
  }
92
88
 
93
- return firstPrivateIp
89
+ return result
94
90
  }
95
91
 
96
92
  module.exports = {
@@ -38,10 +38,11 @@ const TEST_CODE_OWNERS = 'test.codeowners'
38
38
  const TEST_SOURCE_FILE = 'test.source.file'
39
39
  const LIBRARY_VERSION = 'library_version'
40
40
  const TEST_COMMAND = 'test.command'
41
- const TEST_BUNDLE = 'test.bundle'
41
+ const TEST_MODULE = 'test.module'
42
42
  const TEST_SESSION_ID = 'test_session_id'
43
43
  const TEST_MODULE_ID = 'test_module_id'
44
44
  const TEST_SUITE_ID = 'test_suite_id'
45
+ const TEST_TOOLCHAIN = 'test.toolchain'
45
46
 
46
47
  const CI_APP_ORIGIN = 'ciapp-test'
47
48
 
@@ -55,6 +56,10 @@ const TEST_MODULE_CODE_COVERAGE_ENABLED = 'test_module.code_coverage.enabled'
55
56
 
56
57
  const TEST_CODE_COVERAGE_LINES_TOTAL = 'test.codecov_lines_total'
57
58
 
59
+ // jest worker variables
60
+ const JEST_WORKER_TRACE_PAYLOAD_CODE = 60
61
+ const JEST_WORKER_COVERAGE_PAYLOAD_CODE = 61
62
+
58
63
  module.exports = {
59
64
  TEST_CODE_OWNERS,
60
65
  TEST_FRAMEWORK,
@@ -70,6 +75,8 @@ module.exports = {
70
75
  TEST_SOURCE_FILE,
71
76
  CI_APP_ORIGIN,
72
77
  LIBRARY_VERSION,
78
+ JEST_WORKER_TRACE_PAYLOAD_CODE,
79
+ JEST_WORKER_COVERAGE_PAYLOAD_CODE,
73
80
  getTestEnvironmentMetadata,
74
81
  getTestParametersString,
75
82
  finishAllTraceSpans,
@@ -82,11 +89,12 @@ module.exports = {
82
89
  getTestModuleCommonTags,
83
90
  getTestSuiteCommonTags,
84
91
  TEST_COMMAND,
92
+ TEST_TOOLCHAIN,
85
93
  TEST_SESSION_ID,
86
94
  TEST_MODULE_ID,
87
95
  TEST_SUITE_ID,
88
96
  TEST_ITR_TESTS_SKIPPED,
89
- TEST_BUNDLE,
97
+ TEST_MODULE,
90
98
  TEST_SESSION_ITR_SKIPPING_ENABLED,
91
99
  TEST_SESSION_CODE_COVERAGE_ENABLED,
92
100
  TEST_MODULE_ITR_SKIPPING_ENABLED,
@@ -99,6 +107,15 @@ module.exports = {
99
107
  fromCoverageMapToCoverage
100
108
  }
101
109
 
110
+ // Returns pkg manager and its version, separated by '-', e.g. npm-8.15.0 or yarn-1.22.19
111
+ function getPkgManager () {
112
+ try {
113
+ return process.env.npm_config_user_agent.split(' ')[0].replace('/', '-')
114
+ } catch (e) {
115
+ return ''
116
+ }
117
+ }
118
+
102
119
  function getTestEnvironmentMetadata (testFramework, config) {
103
120
  // TODO: eventually these will come from the tracer (generally available)
104
121
  const ciMetadata = getCIMetadata()
@@ -261,28 +278,30 @@ function getTestLevelCommonTags (command, testFrameworkVersion) {
261
278
  }
262
279
  }
263
280
 
264
- function getTestSessionCommonTags (command, testFrameworkVersion) {
281
+ function getTestSessionCommonTags (command, testFrameworkVersion, testFramework) {
265
282
  return {
266
283
  [SPAN_TYPE]: 'test_session_end',
267
284
  [RESOURCE_NAME]: `test_session.${command}`,
285
+ [TEST_MODULE]: testFramework,
286
+ [TEST_TOOLCHAIN]: getPkgManager(),
268
287
  ...getTestLevelCommonTags(command, testFrameworkVersion)
269
288
  }
270
289
  }
271
290
 
272
- function getTestModuleCommonTags (command, testFrameworkVersion) {
291
+ function getTestModuleCommonTags (command, testFrameworkVersion, testFramework) {
273
292
  return {
274
293
  [SPAN_TYPE]: 'test_module_end',
275
294
  [RESOURCE_NAME]: `test_module.${command}`,
276
- [TEST_BUNDLE]: command,
295
+ [TEST_MODULE]: testFramework,
277
296
  ...getTestLevelCommonTags(command, testFrameworkVersion)
278
297
  }
279
298
  }
280
299
 
281
- function getTestSuiteCommonTags (command, testFrameworkVersion, testSuite) {
300
+ function getTestSuiteCommonTags (command, testFrameworkVersion, testSuite, testFramework) {
282
301
  return {
283
302
  [SPAN_TYPE]: 'test_suite_end',
284
303
  [RESOURCE_NAME]: `test_suite.${testSuite}`,
285
- [TEST_BUNDLE]: command,
304
+ [TEST_MODULE]: testFramework,
286
305
  [TEST_SUITE]: testSuite,
287
306
  ...getTestLevelCommonTags(command, testFrameworkVersion)
288
307
  }