dd-trace 4.43.0 → 4.44.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 (40) hide show
  1. package/ext/formats.d.ts +1 -0
  2. package/ext/formats.js +2 -1
  3. package/init.js +3 -15
  4. package/package.json +3 -2
  5. package/packages/datadog-instrumentations/src/helpers/register.js +13 -11
  6. package/packages/datadog-instrumentations/src/http/client.js +7 -1
  7. package/packages/datadog-instrumentations/src/http/server.js +50 -13
  8. package/packages/datadog-instrumentations/src/mocha/main.js +21 -8
  9. package/packages/datadog-instrumentations/src/process.js +29 -0
  10. package/packages/datadog-instrumentations/src/vitest.js +47 -23
  11. package/packages/datadog-plugin-aws-sdk/src/base.js +15 -1
  12. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
  13. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -1
  14. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +3 -3
  15. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +37 -8
  16. package/packages/datadog-plugin-vitest/src/index.js +2 -1
  17. package/packages/dd-trace/src/appsec/blocking.js +10 -1
  18. package/packages/dd-trace/src/appsec/channels.js +4 -1
  19. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
  20. package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +16 -0
  21. package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +2 -0
  22. package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +2 -1
  23. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +11 -0
  24. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/code-injection-sensitive-analyzer.js +25 -0
  25. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
  26. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +2 -2
  27. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
  28. package/packages/dd-trace/src/appsec/index.js +12 -7
  29. package/packages/dd-trace/src/appsec/rasp.js +121 -7
  30. package/packages/dd-trace/src/appsec/recommended.json +220 -2
  31. package/packages/dd-trace/src/config.js +41 -42
  32. package/packages/dd-trace/src/data_streams.js +44 -0
  33. package/packages/dd-trace/src/datastreams/pathway.js +4 -2
  34. package/packages/dd-trace/src/log/index.js +32 -0
  35. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +43 -0
  36. package/packages/dd-trace/src/opentracing/tracer.js +10 -6
  37. package/packages/dd-trace/src/plugins/ci_plugin.js +9 -2
  38. package/packages/dd-trace/src/plugins/plugin.js +12 -1
  39. package/packages/dd-trace/src/proxy.js +1 -0
  40. package/packages/dd-trace/src/tracer.js +2 -0
@@ -29,14 +29,14 @@ const telemetryCounters = {
29
29
  function getCounter (event, ddVar, otelVar) {
30
30
  const counters = telemetryCounters[event]
31
31
  const tags = []
32
- const ddVarPrefix = 'config.datadog:'
33
- const otelVarPrefix = 'config.opentelemetry:'
32
+ const ddVarPrefix = 'config_datadog:'
33
+ const otelVarPrefix = 'config_opentelemetry:'
34
34
  if (ddVar) {
35
- ddVar = ddVarPrefix + ddVar
35
+ ddVar = ddVarPrefix + ddVar.toLowerCase()
36
36
  tags.push(ddVar)
37
37
  }
38
38
  if (otelVar) {
39
- otelVar = otelVarPrefix + otelVar
39
+ otelVar = otelVarPrefix + otelVar.toLowerCase()
40
40
  tags.push(otelVar)
41
41
  }
42
42
 
@@ -211,33 +211,23 @@ function propagationStyle (key, option, defaultValue) {
211
211
  }
212
212
 
213
213
  class Config {
214
- constructor (options) {
215
- options = options || {}
216
- options = this.options = {
214
+ constructor (options = {}) {
215
+ options = {
217
216
  ...options,
218
217
  appsec: options.appsec != null ? options.appsec : options.experimental?.appsec,
219
218
  iast: options.iast != null ? options.iast : options.experimental?.iast
220
219
  }
221
220
 
222
- checkIfBothOtelAndDdEnvVarSet()
223
-
224
221
  // Configure the logger first so it can be used to warn about other configs
225
- this.debug = isTrue(coalesce(
226
- process.env.DD_TRACE_DEBUG,
227
- process.env.OTEL_LOG_LEVEL && process.env.OTEL_LOG_LEVEL === 'debug',
228
- false
229
- ))
230
- this.logger = options.logger
231
-
232
- this.logLevel = coalesce(
233
- options.logLevel,
234
- process.env.DD_TRACE_LOG_LEVEL,
235
- process.env.OTEL_LOG_LEVEL,
236
- 'debug'
237
- )
222
+ const logConfig = log.getConfig()
223
+ this.debug = logConfig.enabled
224
+ this.logger = coalesce(options.logger, logConfig.logger)
225
+ this.logLevel = coalesce(options.logLevel, logConfig.logLevel)
238
226
 
239
227
  log.use(this.logger)
240
- log.toggle(this.debug, this.logLevel, this)
228
+ log.toggle(this.debug, this.logLevel)
229
+
230
+ checkIfBothOtelAndDdEnvVarSet()
241
231
 
242
232
  const DD_TRACE_MEMCACHED_COMMAND_ENABLED = coalesce(
243
233
  process.env.DD_TRACE_MEMCACHED_COMMAND_ENABLED,
@@ -486,14 +476,14 @@ class Config {
486
476
  pkg.name ||
487
477
  'node'
488
478
 
489
- const defaults = this._defaults = {}
479
+ const defaults = setHiddenProperty(this, '_defaults', {})
490
480
 
491
481
  this._setValue(defaults, 'appsec.blockedTemplateHtml', undefined)
492
482
  this._setValue(defaults, 'appsec.blockedTemplateJson', undefined)
493
483
  this._setValue(defaults, 'appsec.enabled', undefined)
494
484
  this._setValue(defaults, 'appsec.obfuscatorKeyRegex', defaultWafObfuscatorKeyRegex)
495
485
  this._setValue(defaults, 'appsec.obfuscatorValueRegex', defaultWafObfuscatorValueRegex)
496
- this._setValue(defaults, 'appsec.rasp.enabled', false)
486
+ this._setValue(defaults, 'appsec.rasp.enabled', true)
497
487
  this._setValue(defaults, 'appsec.rateLimit', 100)
498
488
  this._setValue(defaults, 'appsec.rules', undefined)
499
489
  this._setValue(defaults, 'appsec.sca.enabled', null)
@@ -671,8 +661,8 @@ class Config {
671
661
  } = process.env
672
662
 
673
663
  const tags = {}
674
- const env = this._env = {}
675
- this._envUnprocessed = {}
664
+ const env = setHiddenProperty(this, '_env', {})
665
+ setHiddenProperty(this, '_envUnprocessed', {})
676
666
 
677
667
  tagger.add(tags, OTEL_RESOURCE_ATTRIBUTES, true)
678
668
  tagger.add(tags, DD_TAGS)
@@ -812,11 +802,11 @@ class Config {
812
802
  }
813
803
 
814
804
  _applyOptions (options) {
815
- const opts = this._options = this._options || {}
805
+ const opts = setHiddenProperty(this, '_options', this._options || {})
816
806
  const tags = {}
817
- this._optsUnprocessed = {}
807
+ setHiddenProperty(this, '_optsUnprocessed', {})
818
808
 
819
- options = this.options = Object.assign({ ingestion: {} }, options, opts)
809
+ options = setHiddenProperty(this, '_optionsArg', Object.assign({ ingestion: {} }, options, opts))
820
810
 
821
811
  tagger.add(tags, options.tags)
822
812
 
@@ -914,7 +904,7 @@ class Config {
914
904
 
915
905
  _isCiVisibility () {
916
906
  return coalesce(
917
- this.options.isCiVisibility,
907
+ this._optionsArg.isCiVisibility,
918
908
  this._defaults.isCiVisibility
919
909
  )
920
910
  }
@@ -930,9 +920,9 @@ class Config {
930
920
  const DD_CIVISIBILITY_AGENTLESS_URL = process.env.DD_CIVISIBILITY_AGENTLESS_URL
931
921
  const url = DD_CIVISIBILITY_AGENTLESS_URL
932
922
  ? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
933
- : getAgentUrl(this._getTraceAgentUrl(), this.options)
923
+ : getAgentUrl(this._getTraceAgentUrl(), this._optionsArg)
934
924
  const DD_AGENT_HOST = coalesce(
935
- this.options.hostname,
925
+ this._optionsArg.hostname,
936
926
  process.env.DD_AGENT_HOST,
937
927
  process.env.DD_TRACE_AGENT_HOSTNAME,
938
928
  '127.0.0.1'
@@ -943,17 +933,17 @@ class Config {
943
933
  _getSpanComputePeerService () {
944
934
  const DD_TRACE_SPAN_ATTRIBUTE_SCHEMA = validateNamingVersion(
945
935
  coalesce(
946
- this.options.spanAttributeSchema,
936
+ this._optionsArg.spanAttributeSchema,
947
937
  process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
948
938
  )
949
939
  )
950
940
 
951
941
  const peerServiceSet = (
952
- this.options.hasOwnProperty('spanComputePeerService') ||
942
+ this._optionsArg.hasOwnProperty('spanComputePeerService') ||
953
943
  process.env.hasOwnProperty('DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED')
954
944
  )
955
945
  const peerServiceValue = coalesce(
956
- this.options.spanComputePeerService,
946
+ this._optionsArg.spanComputePeerService,
957
947
  process.env.DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED
958
948
  )
959
949
 
@@ -984,7 +974,7 @@ class Config {
984
974
 
985
975
  _isTraceStatsComputationEnabled () {
986
976
  return coalesce(
987
- this.options.stats,
977
+ this._optionsArg.stats,
988
978
  process.env.DD_TRACE_STATS_COMPUTATION_ENABLED,
989
979
  getIsGCPFunction() || getIsAzureFunction()
990
980
  )
@@ -992,7 +982,7 @@ class Config {
992
982
 
993
983
  _getTraceAgentUrl () {
994
984
  return coalesce(
995
- this.options.url,
985
+ this._optionsArg.url,
996
986
  process.env.DD_TRACE_AGENT_URL,
997
987
  process.env.DD_TRACE_URL,
998
988
  null
@@ -1001,7 +991,7 @@ class Config {
1001
991
 
1002
992
  // handles values calculated from a mixture of options and env vars
1003
993
  _applyCalculated () {
1004
- const calc = this._calculated = {}
994
+ const calc = setHiddenProperty(this, '_calculated', {})
1005
995
 
1006
996
  const {
1007
997
  DD_CIVISIBILITY_AGENTLESS_URL
@@ -1010,7 +1000,7 @@ class Config {
1010
1000
  if (DD_CIVISIBILITY_AGENTLESS_URL) {
1011
1001
  this._setValue(calc, 'url', new URL(DD_CIVISIBILITY_AGENTLESS_URL))
1012
1002
  } else {
1013
- this._setValue(calc, 'url', getAgentUrl(this._getTraceAgentUrl(), this.options))
1003
+ this._setValue(calc, 'url', getAgentUrl(this._getTraceAgentUrl(), this._optionsArg))
1014
1004
  }
1015
1005
  if (this._isCiVisibility()) {
1016
1006
  this._setBoolean(calc, 'isEarlyFlakeDetectionEnabled',
@@ -1026,8 +1016,8 @@ class Config {
1026
1016
  }
1027
1017
 
1028
1018
  _applyRemote (options) {
1029
- const opts = this._remote = this._remote || {}
1030
- this._remoteUnprocessed = {}
1019
+ const opts = setHiddenProperty(this, '_remote', this._remote || {})
1020
+ setHiddenProperty(this, '_remoteUnprocessed', {})
1031
1021
  const tags = {}
1032
1022
  const headerTags = options.tracing_header_tags
1033
1023
  ? options.tracing_header_tags.map(tag => {
@@ -1196,4 +1186,13 @@ function getAgentUrl (url, options) {
1196
1186
  }
1197
1187
  }
1198
1188
 
1189
+ function setHiddenProperty (obj, name, value) {
1190
+ Object.defineProperty(obj, name, {
1191
+ value,
1192
+ enumerable: false,
1193
+ writable: true
1194
+ })
1195
+ return obj[name]
1196
+ }
1197
+
1199
1198
  module.exports = Config
@@ -0,0 +1,44 @@
1
+ const DataStreamsContext = require('./data_streams_context')
2
+
3
+ class DataStreamsCheckpointer {
4
+ constructor (tracer) {
5
+ this.tracer = tracer
6
+ this.config = tracer._config
7
+ this.dsmProcessor = tracer._dataStreamsProcessor
8
+ }
9
+
10
+ setProduceCheckpoint (type, target, carrier) {
11
+ if (!this.config.dsmEnabled) return
12
+
13
+ const ctx = this.dsmProcessor.setCheckpoint(
14
+ ['type:' + type, 'topic:' + target, 'direction:out', 'manual_checkpoint:true'],
15
+ null,
16
+ DataStreamsContext.getDataStreamsContext(),
17
+ null
18
+ )
19
+ DataStreamsContext.setDataStreamsContext(ctx)
20
+
21
+ this.tracer.inject(ctx, 'text_map_dsm', carrier)
22
+ }
23
+
24
+ setConsumeCheckpoint (type, source, carrier) {
25
+ if (!this.config.dsmEnabled) return
26
+
27
+ const parentCtx = this.tracer.extract('text_map_dsm', carrier)
28
+ DataStreamsContext.setDataStreamsContext(parentCtx)
29
+
30
+ const ctx = this.dsmProcessor.setCheckpoint(
31
+ ['type:' + type, 'topic:' + source, 'direction:in', 'manual_checkpoint:true'],
32
+ null,
33
+ parentCtx,
34
+ null
35
+ )
36
+ DataStreamsContext.setDataStreamsContext(ctx)
37
+
38
+ return ctx
39
+ }
40
+ }
41
+
42
+ module.exports = {
43
+ DataStreamsCheckpointer
44
+ }
@@ -17,11 +17,13 @@ function shaHash (checkpointString) {
17
17
  }
18
18
 
19
19
  function computeHash (service, env, edgeTags, parentHash) {
20
- const key = `${service}${env}` + edgeTags.join('') + parentHash.toString()
20
+ const hashableEdgeTags = edgeTags.filter(item => item !== 'manual_checkpoint:true')
21
+
22
+ const key = `${service}${env}` + hashableEdgeTags.join('') + parentHash.toString()
21
23
  if (cache.get(key)) {
22
24
  return cache.get(key)
23
25
  }
24
- const currentHash = shaHash(`${service}${env}` + edgeTags.join(''))
26
+ const currentHash = shaHash(`${service}${env}` + hashableEdgeTags.join(''))
25
27
  const buf = Buffer.concat([currentHash, parentHash], 16)
26
28
  const val = shaHash(buf.toString())
27
29
  cache.set(key, val)
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
 
3
+ const coalesce = require('koalas')
4
+ const { isTrue } = require('../util')
3
5
  const { debugChannel, infoChannel, warnChannel, errorChannel } = require('./channels')
4
6
  const logWriter = require('./writer')
5
7
 
@@ -20,13 +22,29 @@ function processMsg (msg) {
20
22
  return typeof msg === 'function' ? msg() : msg
21
23
  }
22
24
 
25
+ const config = {
26
+ enabled: false,
27
+ logger: undefined,
28
+ logLevel: 'debug'
29
+ }
30
+
23
31
  const log = {
32
+ /**
33
+ * @returns Read-only version of logging config. To modify config, call `log.use` and `log.toggle`
34
+ */
35
+ getConfig () {
36
+ return { ...config }
37
+ },
38
+
24
39
  use (logger) {
40
+ config.logger = logger
25
41
  logWriter.use(logger)
26
42
  return this
27
43
  },
28
44
 
29
45
  toggle (enabled, logLevel) {
46
+ config.enabled = enabled
47
+ config.logLevel = logLevel
30
48
  logWriter.toggle(enabled, logLevel)
31
49
  return this
32
50
  },
@@ -76,4 +94,18 @@ const log = {
76
94
 
77
95
  log.reset()
78
96
 
97
+ const enabled = isTrue(coalesce(
98
+ process.env.DD_TRACE_DEBUG,
99
+ process.env.OTEL_LOG_LEVEL === 'debug',
100
+ config.enabled
101
+ ))
102
+
103
+ const logLevel = coalesce(
104
+ process.env.DD_TRACE_LOG_LEVEL,
105
+ process.env.OTEL_LOG_LEVEL,
106
+ config.logLevel
107
+ )
108
+
109
+ log.toggle(enabled, logLevel)
110
+
79
111
  module.exports = log
@@ -0,0 +1,43 @@
1
+ const pick = require('../../../../datadog-core/src/utils/src/pick')
2
+ const log = require('../../log')
3
+
4
+ const { DsmPathwayCodec } = require('../../datastreams/pathway')
5
+
6
+ const base64Key = 'dd-pathway-ctx-base64'
7
+ const logKeys = [base64Key]
8
+
9
+ class DSMTextMapPropagator {
10
+ constructor (config) {
11
+ this.config = config
12
+ }
13
+
14
+ inject (ctx, carrier) {
15
+ if (!this.config.dsmEnabled) return
16
+
17
+ this._injectDatadogDSMContext(ctx, carrier)
18
+
19
+ log.debug(() => `Inject into carrier (DSM): ${JSON.stringify(pick(carrier, logKeys))}.`)
20
+ }
21
+
22
+ extract (carrier) {
23
+ if (!this.config.dsmEnabled) return
24
+
25
+ const dsmContext = this._extractDatadogDSMContext(carrier)
26
+
27
+ if (!dsmContext) return dsmContext
28
+
29
+ log.debug(() => `Extract from carrier (DSM): ${JSON.stringify(pick(carrier, logKeys))}.`)
30
+ return dsmContext
31
+ }
32
+
33
+ _injectDatadogDSMContext (ctx, carrier) {
34
+ DsmPathwayCodec.encode(ctx, carrier)
35
+ }
36
+
37
+ _extractDatadogDSMContext (carrier) {
38
+ const ctx = DsmPathwayCodec.decode(carrier)
39
+ return ctx
40
+ }
41
+ }
42
+
43
+ module.exports = DSMTextMapPropagator
@@ -5,6 +5,7 @@ const Span = require('./span')
5
5
  const SpanProcessor = require('../span_processor')
6
6
  const PrioritySampler = require('../priority_sampler')
7
7
  const TextMapPropagator = require('./propagation/text_map')
8
+ const DSMTextMapPropagator = require('./propagation/text_map_dsm')
8
9
  const HttpPropagator = require('./propagation/http')
9
10
  const BinaryPropagator = require('./propagation/binary')
10
11
  const LogPropagator = require('./propagation/log')
@@ -38,7 +39,8 @@ class DatadogTracer {
38
39
  [formats.TEXT_MAP]: new TextMapPropagator(config),
39
40
  [formats.HTTP_HEADERS]: new HttpPropagator(config),
40
41
  [formats.BINARY]: new BinaryPropagator(config),
41
- [formats.LOG]: new LogPropagator(config)
42
+ [formats.LOG]: new LogPropagator(config),
43
+ [formats.TEXT_MAP_DSM]: new DSMTextMapPropagator(config)
42
44
  }
43
45
  if (config.reportHostname) {
44
46
  this._hostname = os.hostname()
@@ -71,14 +73,16 @@ class DatadogTracer {
71
73
  return span
72
74
  }
73
75
 
74
- inject (spanContext, format, carrier) {
75
- if (spanContext instanceof Span) {
76
- spanContext = spanContext.context()
76
+ inject (context, format, carrier) {
77
+ if (context instanceof Span) {
78
+ context = context.context()
77
79
  }
78
80
 
79
81
  try {
80
- this._prioritySampler.sample(spanContext)
81
- this._propagators[format].inject(spanContext, carrier)
82
+ if (format !== 'text_map_dsm') {
83
+ this._prioritySampler.sample(context)
84
+ }
85
+ this._propagators[format].inject(context, carrier)
82
86
  } catch (e) {
83
87
  log.error(e)
84
88
  runtimeMetrics.increment('datadog.tracer.node.inject.errors', true)
@@ -16,7 +16,8 @@ const {
16
16
  getTestSuiteCommonTags,
17
17
  TEST_STATUS,
18
18
  TEST_SKIPPED_BY_ITR,
19
- ITR_CORRELATION_ID
19
+ ITR_CORRELATION_ID,
20
+ TEST_SOURCE_FILE
20
21
  } = require('./util/test')
21
22
  const Plugin = require('./plugin')
22
23
  const { COMPONENT } = require('../constants')
@@ -207,7 +208,13 @@ module.exports = class CiPlugin extends Plugin {
207
208
  ...extraTags
208
209
  }
209
210
 
210
- const codeOwners = getCodeOwnersForFilename(testSuite, this.codeOwnersEntries)
211
+ const { [TEST_SOURCE_FILE]: testSourceFile } = extraTags
212
+ // We'll try with the test source file if available (it could be different from the test suite)
213
+ let codeOwners = getCodeOwnersForFilename(testSourceFile, this.codeOwnersEntries)
214
+ if (!codeOwners) {
215
+ codeOwners = getCodeOwnersForFilename(testSuite, this.codeOwnersEntries)
216
+ }
217
+
211
218
  if (codeOwners) {
212
219
  testTags[TEST_CODE_OWNERS] = codeOwners
213
220
  }
@@ -3,6 +3,7 @@
3
3
  // TODO: move anything related to tracing to TracingPlugin instead
4
4
 
5
5
  const dc = require('dc-polyfill')
6
+ const logger = require('../log')
6
7
  const { storage } = require('../../../datadog-core')
7
8
 
8
9
  class Subscription {
@@ -72,7 +73,17 @@ module.exports = class Plugin {
72
73
  }
73
74
 
74
75
  addSub (channelName, handler) {
75
- this._subscriptions.push(new Subscription(channelName, handler))
76
+ const plugin = this
77
+ const wrappedHandler = function () {
78
+ try {
79
+ return handler.apply(this, arguments)
80
+ } catch (e) {
81
+ logger.error('Error in plugin handler:', e)
82
+ logger.info('Disabling plugin:', plugin.id)
83
+ plugin.configure(false)
84
+ }
85
+ }
86
+ this._subscriptions.push(new Subscription(channelName, wrappedHandler))
76
87
  }
77
88
 
78
89
  addBind (channelName, transform) {
@@ -181,6 +181,7 @@ class Tracer extends NoopProxy {
181
181
  if (!this._tracingInitialized) {
182
182
  const prioritySampler = appsecStandalone.configure(config)
183
183
  this._tracer = new DatadogTracer(config, prioritySampler)
184
+ this.dataStreamsCheckpointer = this._tracer.dataStreamsCheckpointer
184
185
  this.appsec = new AppsecSdk(this._tracer, config)
185
186
  this._tracingInitialized = true
186
187
  }
@@ -11,6 +11,7 @@ const { DataStreamsProcessor } = require('./datastreams/processor')
11
11
  const { DsmPathwayCodec } = require('./datastreams/pathway')
12
12
  const { DD_MAJOR } = require('../../../version')
13
13
  const DataStreamsContext = require('./data_streams_context')
14
+ const { DataStreamsCheckpointer } = require('./data_streams')
14
15
  const { flushStartupLogs } = require('../../datadog-instrumentations/src/check_require_cache')
15
16
  const log = require('./log/writer')
16
17
 
@@ -23,6 +24,7 @@ class DatadogTracer extends Tracer {
23
24
  constructor (config, prioritySampler) {
24
25
  super(config, prioritySampler)
25
26
  this._dataStreamsProcessor = new DataStreamsProcessor(config)
27
+ this.dataStreamsCheckpointer = new DataStreamsCheckpointer(this)
26
28
  this._scope = new Scope()
27
29
  setStartupLogConfig(config)
28
30
  flushStartupLogs(log)