dd-trace 4.29.0 → 4.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 (80) hide show
  1. package/README.md +7 -0
  2. package/ci/cypress/after-spec.js +1 -0
  3. package/index.d.ts +1502 -1485
  4. package/package.json +4 -4
  5. package/packages/datadog-core/src/utils/src/get.js +11 -0
  6. package/packages/datadog-core/src/utils/src/has.js +14 -0
  7. package/packages/datadog-core/src/utils/src/set.js +16 -0
  8. package/packages/datadog-instrumentations/src/amqplib.js +1 -1
  9. package/packages/datadog-instrumentations/src/cucumber.js +2 -1
  10. package/packages/datadog-instrumentations/src/grpc/server.js +3 -1
  11. package/packages/datadog-instrumentations/src/jest.js +11 -5
  12. package/packages/datadog-instrumentations/src/mocha.js +4 -1
  13. package/packages/datadog-instrumentations/src/mongodb-core.js +34 -3
  14. package/packages/datadog-instrumentations/src/playwright.js +78 -16
  15. package/packages/datadog-plugin-amqplib/src/consumer.js +5 -4
  16. package/packages/datadog-plugin-amqplib/src/producer.js +3 -4
  17. package/packages/datadog-plugin-aws-sdk/src/base.js +3 -2
  18. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -11
  19. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +3 -6
  20. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +5 -7
  21. package/packages/datadog-plugin-cucumber/src/index.js +2 -2
  22. package/packages/datadog-plugin-cypress/src/after-spec.js +3 -0
  23. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +123 -58
  24. package/packages/datadog-plugin-cypress/src/support.js +50 -3
  25. package/packages/datadog-plugin-graphql/src/index.js +1 -1
  26. package/packages/datadog-plugin-graphql/src/resolve.js +10 -8
  27. package/packages/datadog-plugin-grpc/src/util.js +1 -1
  28. package/packages/datadog-plugin-jest/src/index.js +13 -4
  29. package/packages/datadog-plugin-kafkajs/src/consumer.js +4 -3
  30. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -5
  31. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  32. package/packages/datadog-plugin-playwright/src/index.js +34 -3
  33. package/packages/datadog-plugin-rhea/src/consumer.js +5 -3
  34. package/packages/datadog-plugin-rhea/src/producer.js +3 -4
  35. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +23 -12
  36. package/packages/dd-trace/src/appsec/iast/index.js +10 -0
  37. package/packages/dd-trace/src/appsec/iast/path-line.js +9 -6
  38. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +1 -1
  39. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +6 -2
  40. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +1 -1
  41. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +14 -2
  42. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -1
  43. package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +34 -27
  44. package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +39 -11
  45. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +7 -6
  46. package/packages/dd-trace/src/appsec/recommended.json +67 -27
  47. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -1
  48. package/packages/dd-trace/src/appsec/reporter.js +24 -11
  49. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -3
  50. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +6 -1
  51. package/packages/dd-trace/src/config.js +451 -460
  52. package/packages/dd-trace/src/data_streams_context.js +1 -1
  53. package/packages/dd-trace/src/datastreams/pathway.js +58 -1
  54. package/packages/dd-trace/src/datastreams/processor.js +3 -5
  55. package/packages/dd-trace/src/format.js +0 -1
  56. package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
  57. package/packages/dd-trace/src/opentracing/propagation/text_map.js +22 -3
  58. package/packages/dd-trace/src/opentracing/span.js +2 -0
  59. package/packages/dd-trace/src/opentracing/span_context.js +1 -0
  60. package/packages/dd-trace/src/plugins/util/test.js +4 -2
  61. package/packages/dd-trace/src/plugins/util/web.js +1 -1
  62. package/packages/dd-trace/src/priority_sampler.js +11 -6
  63. package/packages/dd-trace/src/profiling/exporters/agent.js +38 -2
  64. package/packages/dd-trace/src/telemetry/index.js +32 -33
  65. package/packages/dd-trace/src/tracer.js +3 -3
  66. package/register.js +4 -0
  67. package/CONTRIBUTING.md +0 -171
  68. package/MIGRATING.md +0 -224
  69. package/packages/dd-trace/src/external-logger/test/index.spec.js +0 -147
  70. package/scripts/check-proposal-labels.js +0 -71
  71. package/scripts/check_licenses.js +0 -69
  72. package/scripts/helpers/color.js +0 -8
  73. package/scripts/helpers/exec.js +0 -22
  74. package/scripts/helpers/title.js +0 -15
  75. package/scripts/install_plugin_modules.js +0 -248
  76. package/scripts/publish_docs.js +0 -21
  77. package/scripts/st.js +0 -105
  78. /package/packages/{utils → datadog-core/src/utils}/src/kebabcase.js +0 -0
  79. /package/packages/{utils → datadog-core/src/utils}/src/pick.js +0 -0
  80. /package/packages/{utils → datadog-core/src/utils}/src/uniq.js +0 -0
@@ -5,7 +5,8 @@ const { channel } = require('dc-polyfill')
5
5
  const iastLog = require('./iast-log')
6
6
  const Plugin = require('../../plugins/plugin')
7
7
  const iastTelemetry = require('./telemetry')
8
- const { getInstrumentedMetric, getExecutedMetric, TagKey, EXECUTED_SOURCE } = require('./telemetry/iast-metric')
8
+ const { getInstrumentedMetric, getExecutedMetric, TagKey, EXECUTED_SOURCE, formatTags } =
9
+ require('./telemetry/iast-metric')
9
10
  const { storage } = require('../../../../datadog-core')
10
11
  const { getIastContext } = require('./iast-context')
11
12
  const instrumentations = require('../../../../datadog-instrumentations/src/helpers/instrumentations')
@@ -20,25 +21,29 @@ const instrumentations = require('../../../../datadog-instrumentations/src/helpe
20
21
  * - tagKey can be only SOURCE_TYPE (Source) or VULNERABILITY_TYPE (Sink)
21
22
  */
22
23
  class IastPluginSubscription {
23
- constructor (moduleName, channelName, tag, tagKey = TagKey.VULNERABILITY_TYPE) {
24
+ constructor (moduleName, channelName, tagValues, tagKey = TagKey.VULNERABILITY_TYPE) {
24
25
  this.moduleName = moduleName
25
26
  this.channelName = channelName
26
- this.tag = tag
27
- this.tagKey = tagKey
28
- this.executedMetric = getExecutedMetric(this.tagKey)
29
- this.instrumentedMetric = getInstrumentedMetric(this.tagKey)
27
+
28
+ tagValues = Array.isArray(tagValues) ? tagValues : [tagValues]
29
+ this.tags = formatTags(tagValues, tagKey)
30
+
31
+ this.executedMetric = getExecutedMetric(tagKey)
32
+ this.instrumentedMetric = getInstrumentedMetric(tagKey)
33
+
30
34
  this.moduleInstrumented = false
31
35
  }
32
36
 
33
37
  increaseInstrumented () {
34
- if (this.moduleInstrumented) return
38
+ if (!this.moduleInstrumented) {
39
+ this.moduleInstrumented = true
35
40
 
36
- this.moduleInstrumented = true
37
- this.instrumentedMetric.inc(this.tag)
41
+ this.tags.forEach(tag => this.instrumentedMetric.inc(undefined, tag))
42
+ }
38
43
  }
39
44
 
40
45
  increaseExecuted (iastContext) {
41
- this.executedMetric.inc(this.tag, iastContext)
46
+ this.tags.forEach(tag => this.executedMetric.inc(iastContext, tag))
42
47
  }
43
48
 
44
49
  matchesModuleInstrumented (name) {
@@ -76,10 +81,16 @@ class IastPlugin extends Plugin {
76
81
  }
77
82
  }
78
83
 
79
- _execHandlerAndIncMetric ({ handler, metric, tag, iastContext = getIastContext(storage.getStore()) }) {
84
+ _execHandlerAndIncMetric ({ handler, metric, tags, iastContext = getIastContext(storage.getStore()) }) {
80
85
  try {
81
86
  const result = handler()
82
- iastTelemetry.isEnabled() && metric.inc(tag, iastContext)
87
+ if (iastTelemetry.isEnabled()) {
88
+ if (Array.isArray(tags)) {
89
+ tags.forEach(tag => metric.inc(iastContext, tag))
90
+ } else {
91
+ metric.inc(iastContext, tags)
92
+ }
93
+ }
83
94
  return result
84
95
  } catch (e) {
85
96
  iastLog.errorAndPublish(e)
@@ -21,7 +21,11 @@ const requestStart = dc.channel('dd-trace:incomingHttpRequestStart')
21
21
  const requestClose = dc.channel('dd-trace:incomingHttpRequestEnd')
22
22
  const iastResponseEnd = dc.channel('datadog:iast:response-end')
23
23
 
24
+ let isEnabled = false
25
+
24
26
  function enable (config, _tracer) {
27
+ if (isEnabled) return
28
+
25
29
  iastTelemetry.configure(config, config.iast?.telemetryVerbosity)
26
30
  enableAllAnalyzers(config)
27
31
  enableTaintTracking(config.iast, iastTelemetry.verbosity)
@@ -30,9 +34,15 @@ function enable (config, _tracer) {
30
34
  overheadController.configure(config.iast)
31
35
  overheadController.startGlobalContext()
32
36
  vulnerabilityReporter.start(config, _tracer)
37
+
38
+ isEnabled = true
33
39
  }
34
40
 
35
41
  function disable () {
42
+ if (!isEnabled) return
43
+
44
+ isEnabled = false
45
+
36
46
  iastTelemetry.stop()
37
47
  disableAllAnalyzers()
38
48
  disableTaintTracking()
@@ -29,13 +29,16 @@ function getCallSiteInfo () {
29
29
  const previousStackTraceLimit = Error.stackTraceLimit
30
30
  let callsiteList
31
31
  Error.stackTraceLimit = 100
32
- Error.prepareStackTrace = function (_, callsites) {
33
- callsiteList = callsites
32
+ try {
33
+ Error.prepareStackTrace = function (_, callsites) {
34
+ callsiteList = callsites
35
+ }
36
+ const e = new Error()
37
+ e.stack
38
+ } finally {
39
+ Error.prepareStackTrace = previousPrepareStackTrace
40
+ Error.stackTraceLimit = previousStackTraceLimit
34
41
  }
35
- const e = new Error()
36
- e.stack
37
- Error.prepareStackTrace = previousPrepareStackTrace
38
- Error.stackTraceLimit = previousStackTraceLimit
39
42
  return callsiteList
40
43
  }
41
44
 
@@ -19,7 +19,7 @@ let onRemoveTransaction = (transactionId, iastContext) => {}
19
19
  function onRemoveTransactionInformationTelemetry (transactionId, iastContext) {
20
20
  const metrics = TaintedUtils.getMetrics(transactionId, iastTelemetry.verbosity)
21
21
  if (metrics?.requestCount) {
22
- REQUEST_TAINTED.add(metrics.requestCount, null, iastContext)
22
+ REQUEST_TAINTED.inc(iastContext, metrics.requestCount)
23
23
  }
24
24
  }
25
25
 
@@ -14,6 +14,10 @@ const {
14
14
  HTTP_REQUEST_PATH_PARAM,
15
15
  HTTP_REQUEST_URI
16
16
  } = require('./source-types')
17
+ const { EXECUTED_SOURCE } = require('../telemetry/iast-metric')
18
+
19
+ const REQ_HEADER_TAGS = EXECUTED_SOURCE.formatTags(HTTP_REQUEST_HEADER_VALUE, HTTP_REQUEST_HEADER_NAME)
20
+ const REQ_URI_TAGS = EXECUTED_SOURCE.formatTags(HTTP_REQUEST_URI)
17
21
 
18
22
  class TaintTrackingPlugin extends SourceIastPlugin {
19
23
  constructor () {
@@ -97,7 +101,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
97
101
  taintHeaders (headers, iastContext) {
98
102
  this.execSource({
99
103
  handler: () => taintObject(iastContext, headers, HTTP_REQUEST_HEADER_VALUE, true, HTTP_REQUEST_HEADER_NAME),
100
- tag: [HTTP_REQUEST_HEADER_VALUE, HTTP_REQUEST_HEADER_NAME],
104
+ tags: REQ_HEADER_TAGS,
101
105
  iastContext
102
106
  })
103
107
  }
@@ -107,7 +111,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
107
111
  handler: function () {
108
112
  req.url = newTaintedString(iastContext, req.url, HTTP_REQUEST_URI, HTTP_REQUEST_URI)
109
113
  },
110
- tag: [HTTP_REQUEST_URI],
114
+ tags: REQ_URI_TAGS,
111
115
  iastContext
112
116
  })
113
117
  }
@@ -14,7 +14,7 @@ const telemetryRewriter = {
14
14
 
15
15
  const metrics = response.metrics
16
16
  if (metrics && metrics.instrumentedPropagation) {
17
- INSTRUMENTED_PROPAGATION.add(metrics.instrumentedPropagation)
17
+ INSTRUMENTED_PROPAGATION.inc(undefined, metrics.instrumentedPropagation)
18
18
  }
19
19
 
20
20
  return response
@@ -12,6 +12,7 @@ const dc = require('dc-polyfill')
12
12
  const hardcodedSecretCh = dc.channel('datadog:secrets:result')
13
13
  let rewriter
14
14
  let getPrepareStackTrace
15
+ let kSymbolPrepareStackTrace
15
16
 
16
17
  let getRewriterOriginalPathAndLineFromSourceMap = function (path, line, column) {
17
18
  return { path, line, column }
@@ -44,6 +45,7 @@ function getRewriter (telemetryVerbosity) {
44
45
  const iastRewriter = require('@datadog/native-iast-rewriter')
45
46
  const Rewriter = iastRewriter.Rewriter
46
47
  getPrepareStackTrace = iastRewriter.getPrepareStackTrace
48
+ kSymbolPrepareStackTrace = iastRewriter.kSymbolPrepareStackTrace
47
49
 
48
50
  const chainSourceMap = isFlagPresent('--enable-source-maps')
49
51
  const getOriginalPathAndLineFromSourceMap = iastRewriter.getOriginalPathAndLineFromSourceMap
@@ -65,8 +67,9 @@ function getRewriter (telemetryVerbosity) {
65
67
  return rewriter
66
68
  }
67
69
 
68
- let originalPrepareStackTrace = Error.prepareStackTrace
70
+ let originalPrepareStackTrace
69
71
  function getPrepareStackTraceAccessor () {
72
+ originalPrepareStackTrace = Error.prepareStackTrace
70
73
  let actual = getPrepareStackTrace(originalPrepareStackTrace)
71
74
  return {
72
75
  configurable: true,
@@ -121,7 +124,16 @@ function enableRewriter (telemetryVerbosity) {
121
124
 
122
125
  function disableRewriter () {
123
126
  shimmer.unwrap(Module.prototype, '_compile')
124
- Error.prepareStackTrace = originalPrepareStackTrace
127
+
128
+ if (!Error.prepareStackTrace?.[kSymbolPrepareStackTrace]) return
129
+
130
+ try {
131
+ delete Error.prepareStackTrace
132
+
133
+ Error.prepareStackTrace = originalPrepareStackTrace
134
+ } catch (e) {
135
+ iastLog.warn(e)
136
+ }
125
137
  }
126
138
 
127
139
  function getOriginalPathAndLineFromSourceMap ({ path, line, column }) {
@@ -40,7 +40,7 @@ function getContextDefault () {
40
40
 
41
41
  function getContextDebug () {
42
42
  const iastContext = getContextDefault()
43
- EXECUTED_PROPAGATION.inc(null, iastContext)
43
+ EXECUTED_PROPAGATION.inc(iastContext)
44
44
  return iastContext
45
45
  }
46
46
 
@@ -19,6 +19,19 @@ const TagKey = {
19
19
  PROPAGATION_TYPE: 'propagation_type'
20
20
  }
21
21
 
22
+ function formatTags (tags, tagKey) {
23
+ return tags.map(tagValue => tagValue ? [`${tagKey}:${tagValue.toLowerCase()}`] : undefined)
24
+ }
25
+
26
+ function getNamespace (scope, context) {
27
+ let namespace = globalNamespace
28
+
29
+ if (scope === Scope.REQUEST) {
30
+ namespace = getNamespaceFromContext(context) || globalNamespace
31
+ }
32
+ return namespace
33
+ }
34
+
22
35
  class IastMetric {
23
36
  constructor (name, scope, tagKey) {
24
37
  this.name = name
@@ -26,30 +39,26 @@ class IastMetric {
26
39
  this.tagKey = tagKey
27
40
  }
28
41
 
29
- getNamespace (context) {
30
- return getNamespaceFromContext(context) || globalNamespace
42
+ formatTags (...tags) {
43
+ return formatTags(tags, this.tagKey)
31
44
  }
32
45
 
33
- getTag (tagValue) {
34
- return tagValue ? { [this.tagKey]: tagValue } : undefined
46
+ inc (context, tags, value = 1) {
47
+ const namespace = getNamespace(this.scope, context)
48
+ namespace.count(this.name, tags).inc(value)
35
49
  }
50
+ }
36
51
 
37
- addValue (value, tagValue, context) {
38
- this.getNamespace(context)
39
- .count(this.name, this.getTag(tagValue))
40
- .inc(value)
41
- }
52
+ class NoTaggedIastMetric extends IastMetric {
53
+ constructor (name, scope) {
54
+ super(name, scope)
42
55
 
43
- add (value, tagValue, context) {
44
- if (Array.isArray(tagValue)) {
45
- tagValue.forEach(tag => this.addValue(value, tag, context))
46
- } else {
47
- this.addValue(value, tagValue, context)
48
- }
56
+ this.tags = []
49
57
  }
50
58
 
51
- inc (tagValue, context) {
52
- this.add(1, tagValue, context)
59
+ inc (context, value = 1) {
60
+ const namespace = getNamespace(this.scope, context)
61
+ namespace.count(this.name, this.tags).inc(value)
53
62
  }
54
63
  }
55
64
 
@@ -61,21 +70,18 @@ function getInstrumentedMetric (tagKey) {
61
70
  return tagKey === TagKey.VULNERABILITY_TYPE ? INSTRUMENTED_SINK : INSTRUMENTED_SOURCE
62
71
  }
63
72
 
64
- const INSTRUMENTED_PROPAGATION = new IastMetric('instrumented.propagation', Scope.GLOBAL)
73
+ const INSTRUMENTED_PROPAGATION = new NoTaggedIastMetric('instrumented.propagation', Scope.GLOBAL)
65
74
  const INSTRUMENTED_SOURCE = new IastMetric('instrumented.source', Scope.GLOBAL, TagKey.SOURCE_TYPE)
66
75
  const INSTRUMENTED_SINK = new IastMetric('instrumented.sink', Scope.GLOBAL, TagKey.VULNERABILITY_TYPE)
67
76
 
68
77
  const EXECUTED_SOURCE = new IastMetric('executed.source', Scope.REQUEST, TagKey.SOURCE_TYPE)
69
78
  const EXECUTED_SINK = new IastMetric('executed.sink', Scope.REQUEST, TagKey.VULNERABILITY_TYPE)
70
79
 
71
- const REQUEST_TAINTED = new IastMetric('request.tainted', Scope.REQUEST)
80
+ const REQUEST_TAINTED = new NoTaggedIastMetric('request.tainted', Scope.REQUEST)
72
81
 
73
82
  // DEBUG using metrics
74
- const EXECUTED_PROPAGATION = new IastMetric('executed.propagation', Scope.REQUEST)
75
- const EXECUTED_TAINTED = new IastMetric('executed.tainted', Scope.REQUEST)
76
-
77
- // DEBUG using distribution endpoint
78
- const INSTRUMENTATION_TIME = new IastMetric('instrumentation.time', Scope.GLOBAL)
83
+ const EXECUTED_PROPAGATION = new NoTaggedIastMetric('executed.propagation', Scope.REQUEST)
84
+ const EXECUTED_TAINTED = new NoTaggedIastMetric('executed.tainted', Scope.REQUEST)
79
85
 
80
86
  module.exports = {
81
87
  INSTRUMENTED_PROPAGATION,
@@ -89,13 +95,14 @@ module.exports = {
89
95
 
90
96
  REQUEST_TAINTED,
91
97
 
92
- INSTRUMENTATION_TIME,
93
-
94
98
  PropagationType,
95
99
  TagKey,
96
100
 
97
101
  IastMetric,
102
+ NoTaggedIastMetric,
98
103
 
99
104
  getExecutedMetric,
100
- getInstrumentedMetric
105
+ getInstrumentedMetric,
106
+
107
+ formatTags
101
108
  }
@@ -10,13 +10,13 @@ const DD_IAST_METRICS_NAMESPACE = Symbol('_dd.iast.request.metrics.namespace')
10
10
  function initRequestNamespace (context) {
11
11
  if (!context) return
12
12
 
13
- const namespace = new Namespace('iast')
13
+ const namespace = new IastNamespace()
14
14
  context[DD_IAST_METRICS_NAMESPACE] = namespace
15
15
  return namespace
16
16
  }
17
17
 
18
18
  function getNamespaceFromContext (context) {
19
- return context && context[DD_IAST_METRICS_NAMESPACE]
19
+ return context?.[DD_IAST_METRICS_NAMESPACE]
20
20
  }
21
21
 
22
22
  function finalizeRequestNamespace (context, rootSpan) {
@@ -40,11 +40,14 @@ function finalizeRequestNamespace (context, rootSpan) {
40
40
  }
41
41
 
42
42
  function merge (metrics) {
43
- metrics.forEach(metric => metric.points.forEach(point => {
44
- globalNamespace
45
- .count(metric.metric, getTagsObject(metric.tags))
46
- .inc(point[1])
47
- }))
43
+ metrics.forEach(metric => {
44
+ const { metric: metricName, type, tags, points } = metric
45
+
46
+ if (points?.length && type === 'count') {
47
+ const gMetric = globalNamespace.count(metricName, getTagsObject(tags))
48
+ points.forEach(point => gMetric.inc(point[1]))
49
+ }
50
+ })
48
51
  }
49
52
 
50
53
  function getTagsObject (tags) {
@@ -56,11 +59,34 @@ function getTagsObject (tags) {
56
59
  class IastNamespace extends Namespace {
57
60
  constructor () {
58
61
  super('iast')
62
+
63
+ this.iastMetrics = new Map()
59
64
  }
60
65
 
61
- reset () {
62
- this.metrics.clear()
63
- this.distributions.clear()
66
+ getIastMetrics (name) {
67
+ let metrics = this.iastMetrics.get(name)
68
+ if (!metrics) {
69
+ metrics = new Map()
70
+ this.iastMetrics.set(name, metrics)
71
+ }
72
+
73
+ return metrics
74
+ }
75
+
76
+ getMetric (name, tags, type = 'count') {
77
+ const metrics = this.getIastMetrics(name)
78
+
79
+ let metric = metrics.get(tags)
80
+ if (!metric) {
81
+ metric = super[type](name, Array.isArray(tags) ? [...tags] : tags)
82
+ metrics.set(tags, metric)
83
+ }
84
+
85
+ return metric
86
+ }
87
+
88
+ count (name, tags) {
89
+ return this.getMetric(name, tags, 'count')
64
90
  }
65
91
  }
66
92
 
@@ -72,5 +98,7 @@ module.exports = {
72
98
  finalizeRequestNamespace,
73
99
  globalNamespace,
74
100
 
75
- DD_IAST_METRICS_NAMESPACE
101
+ DD_IAST_METRICS_NAMESPACE,
102
+
103
+ IastNamespace
76
104
  }
@@ -1,11 +1,11 @@
1
1
  'use strict'
2
2
 
3
3
  function addMetricsToSpan (rootSpan, metrics, tagPrefix) {
4
- if (!rootSpan || !rootSpan.addTags || !metrics) return
4
+ if (!rootSpan?.addTags || !metrics) return
5
5
 
6
6
  const flattenMap = new Map()
7
7
  metrics
8
- .filter(data => data && data.metric)
8
+ .filter(data => data?.metric)
9
9
  .forEach(data => {
10
10
  const name = taggedMetricName(data)
11
11
  let total = flattenMap.get(name)
@@ -27,19 +27,20 @@ function addMetricsToSpan (rootSpan, metrics, tagPrefix) {
27
27
  }
28
28
 
29
29
  function flatten (metricData) {
30
- return metricData.points && metricData.points.map(point => point[1]).reduce((total, value) => total + value, 0)
30
+ const { points } = metricData
31
+ return points ? points.map(point => point[1]).reduce((total, value) => total + value, 0) : 0
31
32
  }
32
33
 
33
34
  function taggedMetricName (data) {
34
35
  const metric = data.metric
35
- const tags = data.tags && filterTags(data.tags)
36
- return !tags || !tags.length
36
+ const tags = filterTags(data.tags)
37
+ return !tags?.length
37
38
  ? metric
38
39
  : `${metric}.${processTagValue(tags)}`
39
40
  }
40
41
 
41
42
  function filterTags (tags) {
42
- return tags.filter(tag => !tag.startsWith('lib_language') && !tag.startsWith('version'))
43
+ return tags?.filter(tag => !tag.startsWith('lib_language') && !tag.startsWith('version'))
43
44
  }
44
45
 
45
46
  function processTagValue (tags) {