dd-trace 4.42.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.
- package/LICENSE-3rdparty.csv +0 -2
- package/ext/formats.d.ts +1 -0
- package/ext/formats.js +2 -1
- package/index.d.ts +61 -39
- package/init.js +3 -15
- package/package.json +9 -12
- package/packages/datadog-instrumentations/src/child_process.js +2 -2
- package/packages/datadog-instrumentations/src/fs.js +1 -1
- package/packages/datadog-instrumentations/src/hapi.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +13 -11
- package/packages/datadog-instrumentations/src/http/client.js +8 -2
- package/packages/datadog-instrumentations/src/http/server.js +50 -13
- package/packages/datadog-instrumentations/src/jest.js +17 -2
- package/packages/datadog-instrumentations/src/kafkajs.js +1 -1
- package/packages/datadog-instrumentations/src/ldapjs.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +21 -8
- package/packages/datadog-instrumentations/src/mquery.js +2 -2
- package/packages/datadog-instrumentations/src/next.js +1 -1
- package/packages/datadog-instrumentations/src/pg.js +2 -2
- package/packages/datadog-instrumentations/src/playwright.js +46 -32
- package/packages/datadog-instrumentations/src/process.js +29 -0
- package/packages/datadog-instrumentations/src/restify.js +1 -1
- package/packages/datadog-instrumentations/src/vitest.js +98 -28
- package/packages/datadog-plugin-aws-sdk/src/base.js +16 -2
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +3 -3
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -4
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +114 -48
- package/packages/datadog-plugin-cypress/src/plugin.js +4 -3
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +7 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +1 -1
- package/packages/datadog-plugin-mongodb-core/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/index.js +5 -5
- package/packages/datadog-plugin-playwright/src/index.js +4 -1
- package/packages/datadog-plugin-sharedb/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +19 -7
- package/packages/dd-trace/src/analytics_sampler.js +1 -1
- package/packages/dd-trace/src/appsec/blocking.js +10 -1
- package/packages/dd-trace/src/appsec/channels.js +4 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +16 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +2 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +11 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/code-injection-sensitive-analyzer.js +25 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +3 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/index.js +15 -10
- package/packages/dd-trace/src/appsec/passport.js +1 -1
- package/packages/dd-trace/src/appsec/rasp.js +121 -7
- package/packages/dd-trace/src/appsec/recommended.json +220 -2
- package/packages/dd-trace/src/appsec/reporter.js +0 -4
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +1 -1
- package/packages/dd-trace/src/config.js +68 -66
- package/packages/dd-trace/src/data_streams.js +44 -0
- package/packages/dd-trace/src/datastreams/pathway.js +4 -2
- package/packages/dd-trace/src/datastreams/processor.js +1 -1
- package/packages/dd-trace/src/log/index.js +32 -0
- package/packages/dd-trace/src/opentelemetry/span.js +1 -1
- package/packages/dd-trace/src/opentelemetry/tracer.js +6 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +43 -0
- package/packages/dd-trace/src/opentracing/tracer.js +10 -6
- package/packages/dd-trace/src/plugins/ci_plugin.js +9 -2
- package/packages/dd-trace/src/plugins/plugin.js +12 -1
- package/packages/dd-trace/src/proxy.js +1 -0
- 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 = '
|
|
33
|
-
const otelVarPrefix = '
|
|
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
|
|
|
@@ -134,7 +134,7 @@ const fromEntries = Object.fromEntries || (entries =>
|
|
|
134
134
|
// eslint-disable-next-line max-len
|
|
135
135
|
const qsRegex = '(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:(?:\\s|%20)*(?:=|%3D)[^&]+|(?:"|%22)(?:\\s|%20)*(?::|%3A)(?:\\s|%20)*(?:"|%22)(?:%2[^2]|%[^2]|[^"%])+(?:"|%22))|bearer(?:\\s|%20)+[a-z0-9\\._\\-]+|token(?::|%3A)[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L](?:[\\w=-]|%3D)+\\.ey[I-L](?:[\\w=-]|%3D)+(?:\\.(?:[\\w.+\\/=-]|%3D|%2F|%2B)+)?|[\\-]{5}BEGIN(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY[\\-]{5}[^\\-]+[\\-]{5}END(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY|ssh-rsa(?:\\s|%20)*(?:[a-z0-9\\/\\.+]|%2F|%5C|%2B){100,}'
|
|
136
136
|
// eslint-disable-next-line max-len
|
|
137
|
-
const defaultWafObfuscatorKeyRegex = '(?i)(?:
|
|
137
|
+
const defaultWafObfuscatorKeyRegex = '(?i)pass|pw(?:or)?d|secret|(?:api|private|public|access)[_-]?key|token|consumer[_-]?(?:id|key|secret)|sign(?:ed|ature)|bearer|authorization|jsessionid|phpsessid|asp\\.net[_-]sessionid|sid|jwt'
|
|
138
138
|
// eslint-disable-next-line max-len
|
|
139
139
|
const defaultWafObfuscatorValueRegex = '(?i)(?:p(?:ass)?w(?:or)?d|pass(?:[_-]?phrase)?|secret(?:[_-]?key)?|(?:(?:api|private|public|access)[_-]?)key(?:[_-]?id)?|(?:(?:auth|access|id|refresh)[_-]?)?token|consumer[_-]?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?|jsessionid|phpsessid|asp\\.net(?:[_-]|-)sessionid|sid|jwt)(?:\\s*=[^;]|"\\s*:\\s*"[^"]+")|bearer\\s+[a-z0-9\\._\\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\\w=-]+\\.ey[I-L][\\w=-]+(?:\\.[\\w.+\\/=-]+)?|[\\-]{5}BEGIN[a-z\\s]+PRIVATE\\sKEY[\\-]{5}[^\\-]+[\\-]{5}END[a-z\\s]+PRIVATE\\sKEY|ssh-rsa\\s*[a-z0-9\\/\\.+]{100,}'
|
|
140
140
|
const runtimeId = uuid()
|
|
@@ -185,7 +185,7 @@ function remapify (input, mappings) {
|
|
|
185
185
|
|
|
186
186
|
function propagationStyle (key, option, defaultValue) {
|
|
187
187
|
// Extract by key if in object-form value
|
|
188
|
-
if (typeof option === 'object' && !Array.isArray(option)) {
|
|
188
|
+
if (option !== null && typeof option === 'object' && !Array.isArray(option)) {
|
|
189
189
|
option = option[key]
|
|
190
190
|
}
|
|
191
191
|
|
|
@@ -193,7 +193,7 @@ function propagationStyle (key, option, defaultValue) {
|
|
|
193
193
|
if (Array.isArray(option)) return option.map(v => v.toLowerCase())
|
|
194
194
|
|
|
195
195
|
// If it's not an array but not undefined there's something wrong with the input
|
|
196
|
-
if (
|
|
196
|
+
if (option !== undefined) {
|
|
197
197
|
log.warn('Unexpected input for config.tracePropagationStyle')
|
|
198
198
|
}
|
|
199
199
|
|
|
@@ -201,7 +201,7 @@ function propagationStyle (key, option, defaultValue) {
|
|
|
201
201
|
const envKey = `DD_TRACE_PROPAGATION_STYLE_${key.toUpperCase()}`
|
|
202
202
|
|
|
203
203
|
const envVar = coalesce(process.env[envKey], process.env.DD_TRACE_PROPAGATION_STYLE, process.env.OTEL_PROPAGATORS)
|
|
204
|
-
if (
|
|
204
|
+
if (envVar !== undefined) {
|
|
205
205
|
return envVar.split(',')
|
|
206
206
|
.filter(v => v !== '')
|
|
207
207
|
.map(v => v.trim().toLowerCase())
|
|
@@ -211,33 +211,23 @@ function propagationStyle (key, option, defaultValue) {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
class Config {
|
|
214
|
-
constructor (options) {
|
|
215
|
-
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
|
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
|
|
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',
|
|
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
|
|
675
|
-
this
|
|
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
|
|
805
|
+
const opts = setHiddenProperty(this, '_options', this._options || {})
|
|
816
806
|
const tags = {}
|
|
817
|
-
this
|
|
807
|
+
setHiddenProperty(this, '_optsUnprocessed', {})
|
|
818
808
|
|
|
819
|
-
options = this
|
|
809
|
+
options = setHiddenProperty(this, '_optionsArg', Object.assign({ ingestion: {} }, options, opts))
|
|
820
810
|
|
|
821
811
|
tagger.add(tags, options.tags)
|
|
822
812
|
|
|
@@ -858,23 +848,23 @@ class Config {
|
|
|
858
848
|
this._optsUnprocessed.flushMinSpans = options.flushMinSpans
|
|
859
849
|
this._setArray(opts, 'headerTags', options.headerTags)
|
|
860
850
|
this._setString(opts, 'hostname', options.hostname)
|
|
861
|
-
this._setBoolean(opts, 'iast.deduplicationEnabled', options.
|
|
851
|
+
this._setBoolean(opts, 'iast.deduplicationEnabled', options.iast && options.iast.deduplicationEnabled)
|
|
862
852
|
this._setBoolean(opts, 'iast.enabled',
|
|
863
|
-
options.
|
|
853
|
+
options.iast && (options.iast === true || options.iast.enabled === true))
|
|
864
854
|
this._setValue(opts, 'iast.maxConcurrentRequests',
|
|
865
|
-
maybeInt(options.
|
|
866
|
-
this._optsUnprocessed['iast.maxConcurrentRequests'] = options.
|
|
867
|
-
this._setValue(opts, 'iast.maxContextOperations', maybeInt(options.
|
|
868
|
-
this._optsUnprocessed['iast.maxContextOperations'] = options.
|
|
869
|
-
this._setBoolean(opts, 'iast.redactionEnabled', options.
|
|
870
|
-
this._setString(opts, 'iast.redactionNamePattern', options.
|
|
871
|
-
this._setString(opts, 'iast.redactionValuePattern', options.
|
|
872
|
-
const iastRequestSampling = maybeInt(options.
|
|
855
|
+
maybeInt(options.iast?.maxConcurrentRequests))
|
|
856
|
+
this._optsUnprocessed['iast.maxConcurrentRequests'] = options.iast?.maxConcurrentRequests
|
|
857
|
+
this._setValue(opts, 'iast.maxContextOperations', maybeInt(options.iast?.maxContextOperations))
|
|
858
|
+
this._optsUnprocessed['iast.maxContextOperations'] = options.iast?.maxContextOperations
|
|
859
|
+
this._setBoolean(opts, 'iast.redactionEnabled', options.iast?.redactionEnabled)
|
|
860
|
+
this._setString(opts, 'iast.redactionNamePattern', options.iast?.redactionNamePattern)
|
|
861
|
+
this._setString(opts, 'iast.redactionValuePattern', options.iast?.redactionValuePattern)
|
|
862
|
+
const iastRequestSampling = maybeInt(options.iast?.requestSampling)
|
|
873
863
|
if (iastRequestSampling > -1 && iastRequestSampling < 101) {
|
|
874
864
|
this._setValue(opts, 'iast.requestSampling', iastRequestSampling)
|
|
875
|
-
this._optsUnprocessed['iast.requestSampling'] = options.
|
|
865
|
+
this._optsUnprocessed['iast.requestSampling'] = options.iast?.requestSampling
|
|
876
866
|
}
|
|
877
|
-
this._setString(opts, 'iast.telemetryVerbosity', options.
|
|
867
|
+
this._setString(opts, 'iast.telemetryVerbosity', options.iast && options.iast.telemetryVerbosity)
|
|
878
868
|
this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
|
|
879
869
|
this._setBoolean(opts, 'logInjection', options.logInjection)
|
|
880
870
|
this._setString(opts, 'lookup', options.lookup)
|
|
@@ -904,7 +894,7 @@ class Config {
|
|
|
904
894
|
this._setBoolean(opts, 'startupLogs', options.startupLogs)
|
|
905
895
|
this._setTags(opts, 'tags', tags)
|
|
906
896
|
const hasTelemetryLogsUsingFeatures =
|
|
907
|
-
(options.
|
|
897
|
+
(options.iast && (options.iast === true || options.iast?.enabled === true)) ||
|
|
908
898
|
(options.profiling && options.profiling === true)
|
|
909
899
|
this._setBoolean(opts, 'telemetry.logCollection', hasTelemetryLogsUsingFeatures)
|
|
910
900
|
this._setBoolean(opts, 'traceId128BitGenerationEnabled', options.traceId128BitGenerationEnabled)
|
|
@@ -914,7 +904,7 @@ class Config {
|
|
|
914
904
|
|
|
915
905
|
_isCiVisibility () {
|
|
916
906
|
return coalesce(
|
|
917
|
-
this.
|
|
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.
|
|
923
|
+
: getAgentUrl(this._getTraceAgentUrl(), this._optionsArg)
|
|
934
924
|
const DD_AGENT_HOST = coalesce(
|
|
935
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
1030
|
-
this
|
|
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 => {
|
|
@@ -1043,15 +1033,18 @@ class Config {
|
|
|
1043
1033
|
this._setArray(opts, 'headerTags', headerTags)
|
|
1044
1034
|
this._setTags(opts, 'tags', tags)
|
|
1045
1035
|
this._setBoolean(opts, 'tracing', options.tracing_enabled)
|
|
1046
|
-
// ignore tags for now since rc sampling rule tags format is not supported
|
|
1047
|
-
this._setSamplingRule(opts, 'sampler.rules', this._ignoreTags(options.tracing_sampling_rules))
|
|
1048
1036
|
this._remoteUnprocessed['sampler.rules'] = options.tracing_sampling_rules
|
|
1037
|
+
this._setSamplingRule(opts, 'sampler.rules', this._reformatTags(options.tracing_sampling_rules))
|
|
1049
1038
|
}
|
|
1050
1039
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1040
|
+
_reformatTags (samplingRules) {
|
|
1041
|
+
for (const rule of (samplingRules || [])) {
|
|
1042
|
+
const reformattedTags = {}
|
|
1043
|
+
if (rule.tags) {
|
|
1044
|
+
for (const tag of (rule.tags || {})) {
|
|
1045
|
+
reformattedTags[tag.key] = tag.value_glob
|
|
1046
|
+
}
|
|
1047
|
+
rule.tags = reformattedTags
|
|
1055
1048
|
}
|
|
1056
1049
|
}
|
|
1057
1050
|
return samplingRules
|
|
@@ -1193,4 +1186,13 @@ function getAgentUrl (url, options) {
|
|
|
1193
1186
|
}
|
|
1194
1187
|
}
|
|
1195
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
|
+
|
|
1196
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
|
|
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}` +
|
|
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
|
|
@@ -15,6 +15,7 @@ class Tracer {
|
|
|
15
15
|
this._tracerProvider = tracerProvider
|
|
16
16
|
// Is there a reason this is public?
|
|
17
17
|
this.instrumentationLibrary = library
|
|
18
|
+
this._spanLimits = {}
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
get resource () {
|
|
@@ -118,6 +119,11 @@ class Tracer {
|
|
|
118
119
|
getActiveSpanProcessor () {
|
|
119
120
|
return this._tracerProvider.getActiveSpanProcessor()
|
|
120
121
|
}
|
|
122
|
+
|
|
123
|
+
// not used in our codebase but needed for compatibility. See issue #1244
|
|
124
|
+
getSpanLimits () {
|
|
125
|
+
return this._spanLimits
|
|
126
|
+
}
|
|
121
127
|
}
|
|
122
128
|
|
|
123
129
|
module.exports = Tracer
|
|
@@ -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 (
|
|
75
|
-
if (
|
|
76
|
-
|
|
76
|
+
inject (context, format, carrier) {
|
|
77
|
+
if (context instanceof Span) {
|
|
78
|
+
context = context.context()
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
try {
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
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
|
-
|
|
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)
|