dd-trace 4.38.1 → 4.40.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 -3
- package/README.md +8 -18
- package/ci/init.js +7 -0
- package/ext/exporters.d.ts +1 -0
- package/ext/exporters.js +2 -1
- package/ext/tags.d.ts +1 -0
- package/ext/tags.js +1 -0
- package/index.d.ts +18 -3
- package/initialize.mjs +52 -0
- package/package.json +9 -12
- package/packages/datadog-instrumentations/src/amqplib.js +5 -2
- package/packages/datadog-instrumentations/src/apollo-server-core.js +0 -1
- package/packages/datadog-instrumentations/src/apollo-server.js +0 -1
- package/packages/datadog-instrumentations/src/body-parser.js +0 -1
- package/packages/datadog-instrumentations/src/check_require_cache.js +67 -5
- package/packages/datadog-instrumentations/src/cookie-parser.js +0 -1
- package/packages/datadog-instrumentations/src/express.js +0 -1
- package/packages/datadog-instrumentations/src/graphql.js +0 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +5 -2
- package/packages/datadog-instrumentations/src/http/server.js +0 -1
- package/packages/datadog-instrumentations/src/jest.js +6 -3
- package/packages/datadog-instrumentations/src/mocha/common.js +48 -0
- package/packages/datadog-instrumentations/src/mocha/main.js +487 -0
- package/packages/datadog-instrumentations/src/mocha/utils.js +306 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +51 -0
- package/packages/datadog-instrumentations/src/mocha.js +4 -673
- package/packages/datadog-instrumentations/src/openai.js +188 -17
- package/packages/datadog-instrumentations/src/playwright.js +4 -3
- package/packages/datadog-instrumentations/src/router.js +1 -1
- package/packages/datadog-instrumentations/src/selenium.js +13 -6
- package/packages/datadog-plugin-graphql/src/resolve.js +4 -0
- package/packages/datadog-plugin-mocha/src/index.js +82 -8
- package/packages/datadog-plugin-next/src/index.js +1 -2
- package/packages/datadog-plugin-openai/src/index.js +219 -73
- package/packages/dd-trace/src/appsec/addresses.js +4 -2
- package/packages/dd-trace/src/appsec/blocking.js +19 -25
- package/packages/dd-trace/src/appsec/channels.js +2 -1
- package/packages/dd-trace/src/appsec/graphql.js +10 -3
- package/packages/dd-trace/src/appsec/index.js +11 -4
- package/packages/dd-trace/src/appsec/rasp.js +35 -0
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +1 -0
- package/packages/dd-trace/src/appsec/rule_manager.js +15 -25
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -5
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +3 -1
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -1
- package/packages/dd-trace/src/config.js +97 -22
- package/packages/dd-trace/src/constants.js +2 -0
- package/packages/dd-trace/src/encode/0.4.js +47 -8
- package/packages/dd-trace/src/exporter.js +1 -0
- package/packages/dd-trace/src/flare/file.js +44 -0
- package/packages/dd-trace/src/flare/index.js +98 -0
- package/packages/dd-trace/src/log/channels.js +54 -29
- package/packages/dd-trace/src/log/writer.js +7 -49
- package/packages/dd-trace/src/opentelemetry/span.js +8 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +57 -12
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +6 -0
- package/packages/dd-trace/src/priority_sampler.js +8 -4
- package/packages/dd-trace/src/profiler.js +2 -1
- package/packages/dd-trace/src/profiling/config.js +1 -0
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/{ssi-telemetry.js → ssi-heuristics.js} +64 -36
- package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +4 -9
- package/packages/dd-trace/src/proxy.js +49 -15
- package/packages/dd-trace/src/ritm.js +13 -1
- package/packages/dd-trace/src/sampling_rule.js +2 -1
- package/packages/dd-trace/src/startup-log.js +19 -15
- package/packages/dd-trace/src/telemetry/index.js +6 -2
- package/packages/dd-trace/src/tracer.js +3 -0
- package/packages/dd-trace/src/plugins/util/ip_blocklist.js +0 -51
|
@@ -15,6 +15,7 @@ function enable (config, appsec) {
|
|
|
15
15
|
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_LOGS_INJECTION, true)
|
|
16
16
|
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RATE, true)
|
|
17
17
|
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_ENABLED, true)
|
|
18
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RULES, true)
|
|
18
19
|
|
|
19
20
|
const activation = Activation.fromConfig(config)
|
|
20
21
|
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const waf = require('./waf')
|
|
5
5
|
const { ACKNOWLEDGED, ERROR } = require('./remote_config/apply_states')
|
|
6
|
-
const blocking = require('./blocking')
|
|
7
6
|
|
|
8
7
|
let defaultRules
|
|
9
8
|
|
|
@@ -20,10 +19,6 @@ function loadRules (config) {
|
|
|
20
19
|
: require('./recommended.json')
|
|
21
20
|
|
|
22
21
|
waf.init(defaultRules, config)
|
|
23
|
-
|
|
24
|
-
if (defaultRules.actions) {
|
|
25
|
-
blocking.updateBlockingConfiguration(defaultRules.actions.find(action => action.id === 'block'))
|
|
26
|
-
}
|
|
27
22
|
}
|
|
28
23
|
|
|
29
24
|
function updateWafFromRC ({ toUnapply, toApply, toModify }) {
|
|
@@ -68,7 +63,7 @@ function updateWafFromRC ({ toUnapply, toApply, toModify }) {
|
|
|
68
63
|
item.apply_state = ERROR
|
|
69
64
|
item.apply_error = 'Multiple ruleset received in ASM_DD'
|
|
70
65
|
} else {
|
|
71
|
-
if (file
|
|
66
|
+
if (file?.rules?.length) {
|
|
72
67
|
const { version, metadata, rules, processors, scanners } = file
|
|
73
68
|
|
|
74
69
|
newRuleset = { version, metadata, rules, processors, scanners }
|
|
@@ -78,30 +73,23 @@ function updateWafFromRC ({ toUnapply, toApply, toModify }) {
|
|
|
78
73
|
batch.add(item)
|
|
79
74
|
}
|
|
80
75
|
} else if (product === 'ASM') {
|
|
81
|
-
|
|
82
|
-
if (file && file.rules_override && file.rules_override.length) {
|
|
83
|
-
batchConfiguration = true
|
|
76
|
+
if (file?.rules_override?.length) {
|
|
84
77
|
newRulesOverride.set(id, file.rules_override)
|
|
85
78
|
}
|
|
86
79
|
|
|
87
|
-
if (file
|
|
88
|
-
batchConfiguration = true
|
|
80
|
+
if (file?.exclusions?.length) {
|
|
89
81
|
newExclusions.set(id, file.exclusions)
|
|
90
82
|
}
|
|
91
83
|
|
|
92
|
-
if (file
|
|
93
|
-
batchConfiguration = true
|
|
84
|
+
if (file?.custom_rules?.length) {
|
|
94
85
|
newCustomRules.set(id, file.custom_rules)
|
|
95
86
|
}
|
|
96
87
|
|
|
97
|
-
if (file
|
|
88
|
+
if (file?.actions?.length) {
|
|
98
89
|
newActions.set(id, file.actions)
|
|
99
90
|
}
|
|
100
91
|
|
|
101
|
-
|
|
102
|
-
if (batchConfiguration) {
|
|
103
|
-
batch.add(item)
|
|
104
|
-
}
|
|
92
|
+
batch.add(item)
|
|
105
93
|
}
|
|
106
94
|
}
|
|
107
95
|
|
|
@@ -112,7 +100,9 @@ function updateWafFromRC ({ toUnapply, toApply, toModify }) {
|
|
|
112
100
|
newRuleset ||
|
|
113
101
|
newRulesOverride.modified ||
|
|
114
102
|
newExclusions.modified ||
|
|
115
|
-
newCustomRules.modified
|
|
103
|
+
newCustomRules.modified ||
|
|
104
|
+
newActions.modified
|
|
105
|
+
) {
|
|
116
106
|
const payload = newRuleset || {}
|
|
117
107
|
|
|
118
108
|
if (newRulesData.modified) {
|
|
@@ -127,6 +117,9 @@ function updateWafFromRC ({ toUnapply, toApply, toModify }) {
|
|
|
127
117
|
if (newCustomRules.modified) {
|
|
128
118
|
payload.custom_rules = concatArrays(newCustomRules)
|
|
129
119
|
}
|
|
120
|
+
if (newActions.modified) {
|
|
121
|
+
payload.actions = concatArrays(newActions)
|
|
122
|
+
}
|
|
130
123
|
|
|
131
124
|
try {
|
|
132
125
|
waf.update(payload)
|
|
@@ -146,6 +139,9 @@ function updateWafFromRC ({ toUnapply, toApply, toModify }) {
|
|
|
146
139
|
if (newCustomRules.modified) {
|
|
147
140
|
appliedCustomRules = newCustomRules
|
|
148
141
|
}
|
|
142
|
+
if (newActions.modified) {
|
|
143
|
+
appliedActions = newActions
|
|
144
|
+
}
|
|
149
145
|
} catch (err) {
|
|
150
146
|
newApplyState = ERROR
|
|
151
147
|
newApplyError = err.toString()
|
|
@@ -156,11 +152,6 @@ function updateWafFromRC ({ toUnapply, toApply, toModify }) {
|
|
|
156
152
|
config.apply_state = newApplyState
|
|
157
153
|
if (newApplyError) config.apply_error = newApplyError
|
|
158
154
|
}
|
|
159
|
-
|
|
160
|
-
if (newActions.modified) {
|
|
161
|
-
blocking.updateBlockingConfiguration(concatArrays(newActions).find(action => action.id === 'block'))
|
|
162
|
-
appliedActions = newActions
|
|
163
|
-
}
|
|
164
155
|
}
|
|
165
156
|
|
|
166
157
|
// A Map with a new prop `modified`, a bool that indicates if the Map was modified
|
|
@@ -242,7 +233,6 @@ function copyRulesData (rulesData) {
|
|
|
242
233
|
|
|
243
234
|
function clearAllRules () {
|
|
244
235
|
waf.destroy()
|
|
245
|
-
blocking.updateBlockingConfiguration(undefined)
|
|
246
236
|
|
|
247
237
|
defaultRules = undefined
|
|
248
238
|
|
|
@@ -3,17 +3,14 @@
|
|
|
3
3
|
const { USER_ID } = require('../addresses')
|
|
4
4
|
const waf = require('../waf')
|
|
5
5
|
const { getRootSpan } = require('./utils')
|
|
6
|
-
const { block } = require('../blocking')
|
|
6
|
+
const { block, getBlockingAction } = require('../blocking')
|
|
7
7
|
const { storage } = require('../../../../datadog-core')
|
|
8
8
|
const { setUserTags } = require('./set_user')
|
|
9
9
|
const log = require('../../log')
|
|
10
10
|
|
|
11
11
|
function isUserBlocked (user) {
|
|
12
12
|
const actions = waf.run({ persistent: { [USER_ID]: user.id } })
|
|
13
|
-
|
|
14
|
-
if (!actions) return false
|
|
15
|
-
|
|
16
|
-
return actions.includes('block')
|
|
13
|
+
return !!getBlockingAction(actions)
|
|
17
14
|
}
|
|
18
15
|
|
|
19
16
|
function checkUserAndSetUser (tracer, user) {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const log = require('../../log')
|
|
4
4
|
const Reporter = require('../reporter')
|
|
5
5
|
const addresses = require('../addresses')
|
|
6
|
+
const { getBlockingAction } = require('../blocking')
|
|
6
7
|
|
|
7
8
|
// TODO: remove once ephemeral addresses are implemented
|
|
8
9
|
const preventDuplicateAddresses = new Set([
|
|
@@ -60,7 +61,8 @@ class WAFContextWrapper {
|
|
|
60
61
|
this.addressesToSkip = newAddressesToSkip
|
|
61
62
|
|
|
62
63
|
const ruleTriggered = !!result.events?.length
|
|
63
|
-
|
|
64
|
+
|
|
65
|
+
const blockTriggered = !!getBlockingAction(result.actions)
|
|
64
66
|
|
|
65
67
|
Reporter.reportMetrics({
|
|
66
68
|
duration: result.totalRuntime / 1e3,
|
|
@@ -4,7 +4,8 @@ const Writer = require('./writer')
|
|
|
4
4
|
const {
|
|
5
5
|
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
|
|
6
6
|
JEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
7
|
-
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE
|
|
7
|
+
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
|
|
8
|
+
MOCHA_WORKER_TRACE_PAYLOAD_CODE
|
|
8
9
|
} = require('../../../plugins/util/test')
|
|
9
10
|
|
|
10
11
|
function getInterprocessTraceCode () {
|
|
@@ -14,6 +15,9 @@ function getInterprocessTraceCode () {
|
|
|
14
15
|
if (process.env.CUCUMBER_WORKER_ID) {
|
|
15
16
|
return CUCUMBER_WORKER_TRACE_PAYLOAD_CODE
|
|
16
17
|
}
|
|
18
|
+
if (process.env.MOCHA_WORKER_ID) {
|
|
19
|
+
return MOCHA_WORKER_TRACE_PAYLOAD_CODE
|
|
20
|
+
}
|
|
17
21
|
return null
|
|
18
22
|
}
|
|
19
23
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const os = require('os')
|
|
5
|
-
const uuid = require('crypto-randomuuid')
|
|
5
|
+
const uuid = require('crypto-randomuuid') // we need to keep the old uuid dep because of cypress
|
|
6
6
|
const URL = require('url').URL
|
|
7
7
|
const log = require('./log')
|
|
8
8
|
const pkg = require('./pkg')
|
|
@@ -170,6 +170,7 @@ class Config {
|
|
|
170
170
|
// Configure the logger first so it can be used to warn about other configs
|
|
171
171
|
this.debug = isTrue(coalesce(
|
|
172
172
|
process.env.DD_TRACE_DEBUG,
|
|
173
|
+
process.env.OTEL_LOG_LEVEL && process.env.OTEL_LOG_LEVEL === 'debug',
|
|
173
174
|
false
|
|
174
175
|
))
|
|
175
176
|
this.logger = options.logger
|
|
@@ -288,15 +289,6 @@ class Config {
|
|
|
288
289
|
)
|
|
289
290
|
|
|
290
291
|
const sampler = {
|
|
291
|
-
rules: coalesce(
|
|
292
|
-
options.samplingRules,
|
|
293
|
-
safeJsonParse(process.env.DD_TRACE_SAMPLING_RULES),
|
|
294
|
-
[]
|
|
295
|
-
).map(rule => {
|
|
296
|
-
return remapify(rule, {
|
|
297
|
-
sample_rate: 'sampleRate'
|
|
298
|
-
})
|
|
299
|
-
}),
|
|
300
292
|
spanSamplingRules: coalesce(
|
|
301
293
|
options.spanSamplingRules,
|
|
302
294
|
safeJsonParse(maybeFile(process.env.DD_SPAN_SAMPLING_RULES_FILE)),
|
|
@@ -444,6 +436,7 @@ class Config {
|
|
|
444
436
|
this._setValue(defaults, 'appsec.enabled', undefined)
|
|
445
437
|
this._setValue(defaults, 'appsec.obfuscatorKeyRegex', defaultWafObfuscatorKeyRegex)
|
|
446
438
|
this._setValue(defaults, 'appsec.obfuscatorValueRegex', defaultWafObfuscatorValueRegex)
|
|
439
|
+
this._setValue(defaults, 'appsec.rasp.enabled', false)
|
|
447
440
|
this._setValue(defaults, 'appsec.rateLimit', 100)
|
|
448
441
|
this._setValue(defaults, 'appsec.rules', undefined)
|
|
449
442
|
this._setValue(defaults, 'appsec.sca.enabled', null)
|
|
@@ -485,9 +478,12 @@ class Config {
|
|
|
485
478
|
this._setValue(defaults, 'peerServiceMapping', {})
|
|
486
479
|
this._setValue(defaults, 'plugins', true)
|
|
487
480
|
this._setValue(defaults, 'port', '8126')
|
|
488
|
-
this._setValue(defaults, 'profiling.enabled',
|
|
481
|
+
this._setValue(defaults, 'profiling.enabled', undefined)
|
|
489
482
|
this._setValue(defaults, 'profiling.exporters', 'agent')
|
|
490
483
|
this._setValue(defaults, 'profiling.sourceMap', true)
|
|
484
|
+
this._setValue(defaults, 'profiling.ssi', false)
|
|
485
|
+
this._setValue(defaults, 'profiling.heuristicsEnabled', false)
|
|
486
|
+
this._setValue(defaults, 'profiling.longLivedThreshold', undefined)
|
|
491
487
|
this._setValue(defaults, 'protocolVersion', '0.4')
|
|
492
488
|
this._setValue(defaults, 'queryStringObfuscation', qsRegex)
|
|
493
489
|
this._setValue(defaults, 'remoteConfig.enabled', true)
|
|
@@ -496,6 +492,7 @@ class Config {
|
|
|
496
492
|
this._setValue(defaults, 'runtimeMetrics', false)
|
|
497
493
|
this._setValue(defaults, 'sampleRate', undefined)
|
|
498
494
|
this._setValue(defaults, 'sampler.rateLimit', undefined)
|
|
495
|
+
this._setValue(defaults, 'sampler.rules', [])
|
|
499
496
|
this._setValue(defaults, 'scope', undefined)
|
|
500
497
|
this._setValue(defaults, 'service', service)
|
|
501
498
|
this._setValue(defaults, 'site', 'datadoghq.com')
|
|
@@ -531,6 +528,7 @@ class Config {
|
|
|
531
528
|
DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP,
|
|
532
529
|
DD_APPSEC_RULES,
|
|
533
530
|
DD_APPSEC_SCA_ENABLED,
|
|
531
|
+
DD_APPSEC_RASP_ENABLED,
|
|
534
532
|
DD_APPSEC_TRACE_RATE_LIMIT,
|
|
535
533
|
DD_APPSEC_WAF_TIMEOUT,
|
|
536
534
|
DD_DATA_STREAMS_ENABLED,
|
|
@@ -558,6 +556,7 @@ class Config {
|
|
|
558
556
|
DD_PROFILING_ENABLED,
|
|
559
557
|
DD_PROFILING_EXPORTERS,
|
|
560
558
|
DD_PROFILING_SOURCE_MAP,
|
|
559
|
+
DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD,
|
|
561
560
|
DD_REMOTE_CONFIGURATION_ENABLED,
|
|
562
561
|
DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS,
|
|
563
562
|
DD_RUNTIME_METRICS_ENABLED,
|
|
@@ -590,6 +589,7 @@ class Config {
|
|
|
590
589
|
DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED,
|
|
591
590
|
DD_TRACE_REPORT_HOSTNAME,
|
|
592
591
|
DD_TRACE_SAMPLE_RATE,
|
|
592
|
+
DD_TRACE_SAMPLING_RULES,
|
|
593
593
|
DD_TRACE_SCOPE,
|
|
594
594
|
DD_TRACE_SPAN_ATTRIBUTE_SCHEMA,
|
|
595
595
|
DD_TRACE_STARTUP_LOGS,
|
|
@@ -607,6 +607,7 @@ class Config {
|
|
|
607
607
|
|
|
608
608
|
const tags = {}
|
|
609
609
|
const env = this._env = {}
|
|
610
|
+
this._envUnprocessed = {}
|
|
610
611
|
|
|
611
612
|
tagger.add(tags, OTEL_RESOURCE_ATTRIBUTES, true)
|
|
612
613
|
tagger.add(tags, DD_TAGS)
|
|
@@ -614,15 +615,20 @@ class Config {
|
|
|
614
615
|
tagger.add(tags, DD_TRACE_GLOBAL_TAGS)
|
|
615
616
|
|
|
616
617
|
this._setValue(env, 'appsec.blockedTemplateHtml', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML))
|
|
618
|
+
this._envUnprocessed['appsec.blockedTemplateHtml'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML
|
|
617
619
|
this._setValue(env, 'appsec.blockedTemplateJson', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON))
|
|
620
|
+
this._envUnprocessed['appsec.blockedTemplateJson'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON
|
|
618
621
|
this._setBoolean(env, 'appsec.enabled', DD_APPSEC_ENABLED)
|
|
619
622
|
this._setString(env, 'appsec.obfuscatorKeyRegex', DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP)
|
|
620
623
|
this._setString(env, 'appsec.obfuscatorValueRegex', DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP)
|
|
624
|
+
this._setBoolean(env, 'appsec.rasp.enabled', DD_APPSEC_RASP_ENABLED)
|
|
621
625
|
this._setValue(env, 'appsec.rateLimit', maybeInt(DD_APPSEC_TRACE_RATE_LIMIT))
|
|
626
|
+
this._envUnprocessed['appsec.rateLimit'] = DD_APPSEC_TRACE_RATE_LIMIT
|
|
622
627
|
this._setString(env, 'appsec.rules', DD_APPSEC_RULES)
|
|
623
628
|
// DD_APPSEC_SCA_ENABLED is never used locally, but only sent to the backend
|
|
624
629
|
this._setBoolean(env, 'appsec.sca.enabled', DD_APPSEC_SCA_ENABLED)
|
|
625
630
|
this._setValue(env, 'appsec.wafTimeout', maybeInt(DD_APPSEC_WAF_TIMEOUT))
|
|
631
|
+
this._envUnprocessed['appsec.wafTimeout'] = DD_APPSEC_WAF_TIMEOUT
|
|
626
632
|
this._setBoolean(env, 'clientIpEnabled', DD_TRACE_CLIENT_IP_ENABLED)
|
|
627
633
|
this._setString(env, 'clientIpHeader', DD_TRACE_CLIENT_IP_HEADER)
|
|
628
634
|
this._setString(env, 'dbmPropagationMode', DD_DBM_PROPAGATION_MODE)
|
|
@@ -635,13 +641,16 @@ class Config {
|
|
|
635
641
|
this._setBoolean(env, 'experimental.runtimeId', DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED)
|
|
636
642
|
if (AWS_LAMBDA_FUNCTION_NAME) this._setValue(env, 'flushInterval', 0)
|
|
637
643
|
this._setValue(env, 'flushMinSpans', maybeInt(DD_TRACE_PARTIAL_FLUSH_MIN_SPANS))
|
|
644
|
+
this._envUnprocessed.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
|
|
638
645
|
this._setBoolean(env, 'gitMetadataEnabled', DD_TRACE_GIT_METADATA_ENABLED)
|
|
639
646
|
this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
|
|
640
647
|
this._setString(env, 'hostname', coalesce(DD_AGENT_HOST, DD_TRACE_AGENT_HOSTNAME))
|
|
641
648
|
this._setBoolean(env, 'iast.deduplicationEnabled', DD_IAST_DEDUPLICATION_ENABLED)
|
|
642
649
|
this._setBoolean(env, 'iast.enabled', DD_IAST_ENABLED)
|
|
643
650
|
this._setValue(env, 'iast.maxConcurrentRequests', maybeInt(DD_IAST_MAX_CONCURRENT_REQUESTS))
|
|
651
|
+
this._envUnprocessed['iast.maxConcurrentRequests'] = DD_IAST_MAX_CONCURRENT_REQUESTS
|
|
644
652
|
this._setValue(env, 'iast.maxContextOperations', maybeInt(DD_IAST_MAX_CONTEXT_OPERATIONS))
|
|
653
|
+
this._envUnprocessed['iast.maxContextOperations'] = DD_IAST_MAX_CONTEXT_OPERATIONS
|
|
645
654
|
this._setBoolean(env, 'iast.redactionEnabled', DD_IAST_REDACTION_ENABLED && !isFalse(DD_IAST_REDACTION_ENABLED))
|
|
646
655
|
this._setString(env, 'iast.redactionNamePattern', DD_IAST_REDACTION_NAME_PATTERN)
|
|
647
656
|
this._setString(env, 'iast.redactionValuePattern', DD_IAST_REDACTION_VALUE_PATTERN)
|
|
@@ -649,20 +658,34 @@ class Config {
|
|
|
649
658
|
if (iastRequestSampling > -1 && iastRequestSampling < 101) {
|
|
650
659
|
this._setValue(env, 'iast.requestSampling', iastRequestSampling)
|
|
651
660
|
}
|
|
661
|
+
this._envUnprocessed['iast.requestSampling'] = DD_IAST_REQUEST_SAMPLING
|
|
652
662
|
this._setString(env, 'iast.telemetryVerbosity', DD_IAST_TELEMETRY_VERBOSITY)
|
|
653
663
|
this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
|
|
654
664
|
this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
|
|
655
665
|
this._setBoolean(env, 'openAiLogsEnabled', DD_OPENAI_LOGS_ENABLED)
|
|
656
666
|
this._setValue(env, 'openaiSpanCharLimit', maybeInt(DD_OPENAI_SPAN_CHAR_LIMIT))
|
|
667
|
+
this._envUnprocessed.openaiSpanCharLimit = DD_OPENAI_SPAN_CHAR_LIMIT
|
|
657
668
|
if (DD_TRACE_PEER_SERVICE_MAPPING) {
|
|
658
669
|
this._setValue(env, 'peerServiceMapping', fromEntries(
|
|
659
|
-
|
|
670
|
+
DD_TRACE_PEER_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
|
|
660
671
|
))
|
|
672
|
+
this._envUnprocessed.peerServiceMapping = DD_TRACE_PEER_SERVICE_MAPPING
|
|
661
673
|
}
|
|
662
674
|
this._setString(env, 'port', DD_TRACE_AGENT_PORT)
|
|
663
675
|
this._setBoolean(env, 'profiling.enabled', coalesce(DD_EXPERIMENTAL_PROFILING_ENABLED, DD_PROFILING_ENABLED))
|
|
664
676
|
this._setString(env, 'profiling.exporters', DD_PROFILING_EXPORTERS)
|
|
665
677
|
this._setBoolean(env, 'profiling.sourceMap', DD_PROFILING_SOURCE_MAP && !isFalse(DD_PROFILING_SOURCE_MAP))
|
|
678
|
+
if (DD_PROFILING_ENABLED === 'auto' || DD_INJECTION_ENABLED) {
|
|
679
|
+
this._setBoolean(env, 'profiling.ssi', true)
|
|
680
|
+
if (DD_PROFILING_ENABLED === 'auto' || DD_INJECTION_ENABLED.split(',').includes('profiler')) {
|
|
681
|
+
this._setBoolean(env, 'profiling.heuristicsEnabled', true)
|
|
682
|
+
}
|
|
683
|
+
if (DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD) {
|
|
684
|
+
// This is only used in testing to not have to wait 30s
|
|
685
|
+
this._setValue(env, 'profiling.longLivedThreshold', Number(DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD))
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
666
689
|
this._setString(env, 'protocolVersion', DD_TRACE_AGENT_PROTOCOL_VERSION)
|
|
667
690
|
this._setString(env, 'queryStringObfuscation', DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP)
|
|
668
691
|
this._setBoolean(env, 'remoteConfig.enabled', coalesce(
|
|
@@ -670,6 +693,7 @@ class Config {
|
|
|
670
693
|
!this._isInServerlessEnvironment()
|
|
671
694
|
))
|
|
672
695
|
this._setValue(env, 'remoteConfig.pollInterval', maybeFloat(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS))
|
|
696
|
+
this._envUnprocessed['remoteConfig.pollInterval'] = DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS
|
|
673
697
|
this._setBoolean(env, 'reportHostname', DD_TRACE_REPORT_HOSTNAME)
|
|
674
698
|
// only used to explicitly set runtimeMetrics to false
|
|
675
699
|
const otelSetRuntimeMetrics = String(OTEL_METRICS_EXPORTER).toLowerCase() === 'none'
|
|
@@ -687,11 +711,14 @@ class Config {
|
|
|
687
711
|
}
|
|
688
712
|
this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE || OTEL_TRACES_SAMPLER_MAPPING[OTEL_TRACES_SAMPLER])
|
|
689
713
|
this._setValue(env, 'sampler.rateLimit', DD_TRACE_RATE_LIMIT)
|
|
714
|
+
this._setSamplingRule(env, 'sampler.rules', safeJsonParse(DD_TRACE_SAMPLING_RULES))
|
|
715
|
+
this._envUnprocessed['sampler.rules'] = DD_TRACE_SAMPLING_RULES
|
|
690
716
|
this._setString(env, 'scope', DD_TRACE_SCOPE)
|
|
691
717
|
this._setString(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service || OTEL_SERVICE_NAME)
|
|
692
718
|
this._setString(env, 'site', DD_SITE)
|
|
693
719
|
if (DD_TRACE_SPAN_ATTRIBUTE_SCHEMA) {
|
|
694
720
|
this._setString(env, 'spanAttributeSchema', validateNamingVersion(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA))
|
|
721
|
+
this._envUnprocessed.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
695
722
|
}
|
|
696
723
|
this._setBoolean(env, 'spanRemoveIntegrationFromService', DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)
|
|
697
724
|
this._setBoolean(env, 'startupLogs', DD_TRACE_STARTUP_LOGS)
|
|
@@ -706,10 +733,9 @@ class Config {
|
|
|
706
733
|
this._setBoolean(env, 'telemetry.debug', DD_TELEMETRY_DEBUG)
|
|
707
734
|
this._setBoolean(env, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED)
|
|
708
735
|
this._setValue(env, 'telemetry.heartbeatInterval', maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000)))
|
|
736
|
+
this._envUnprocessed['telemetry.heartbeatInterval'] = DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000
|
|
709
737
|
const hasTelemetryLogsUsingFeatures =
|
|
710
|
-
|
|
711
|
-
isTrue(DD_PROFILING_ENABLED) ||
|
|
712
|
-
(typeof DD_INJECTION_ENABLED === 'string' && DD_INJECTION_ENABLED.split(',').includes('profiling'))
|
|
738
|
+
env['iast.enabled'] || env['profiling.enabled'] || env['profiling.heuristicsEnabled']
|
|
713
739
|
? true
|
|
714
740
|
: undefined
|
|
715
741
|
this._setBoolean(env, 'telemetry.logCollection', coalesce(DD_TELEMETRY_LOG_COLLECTION_ENABLED,
|
|
@@ -724,19 +750,25 @@ class Config {
|
|
|
724
750
|
_applyOptions (options) {
|
|
725
751
|
const opts = this._options = this._options || {}
|
|
726
752
|
const tags = {}
|
|
753
|
+
this._optsUnprocessed = {}
|
|
727
754
|
|
|
728
755
|
options = this.options = Object.assign({ ingestion: {} }, options, opts)
|
|
729
756
|
|
|
730
757
|
tagger.add(tags, options.tags)
|
|
731
758
|
|
|
732
759
|
this._setValue(opts, 'appsec.blockedTemplateHtml', maybeFile(options.appsec.blockedTemplateHtml))
|
|
760
|
+
this._optsUnprocessed['appsec.blockedTemplateHtml'] = options.appsec.blockedTemplateHtml
|
|
733
761
|
this._setValue(opts, 'appsec.blockedTemplateJson', maybeFile(options.appsec.blockedTemplateJson))
|
|
762
|
+
this._optsUnprocessed['appsec.blockedTemplateJson'] = options.appsec.blockedTemplateJson
|
|
734
763
|
this._setBoolean(opts, 'appsec.enabled', options.appsec.enabled)
|
|
735
764
|
this._setString(opts, 'appsec.obfuscatorKeyRegex', options.appsec.obfuscatorKeyRegex)
|
|
736
765
|
this._setString(opts, 'appsec.obfuscatorValueRegex', options.appsec.obfuscatorValueRegex)
|
|
766
|
+
this._setBoolean(opts, 'appsec.rasp.enabled', options.appsec.rasp?.enabled)
|
|
737
767
|
this._setValue(opts, 'appsec.rateLimit', maybeInt(options.appsec.rateLimit))
|
|
768
|
+
this._optsUnprocessed['appsec.rateLimit'] = options.appsec.rateLimit
|
|
738
769
|
this._setString(opts, 'appsec.rules', options.appsec.rules)
|
|
739
770
|
this._setValue(opts, 'appsec.wafTimeout', maybeInt(options.appsec.wafTimeout))
|
|
771
|
+
this._optsUnprocessed['appsec.wafTimeout'] = options.appsec.wafTimeout
|
|
740
772
|
this._setBoolean(opts, 'clientIpEnabled', options.clientIpEnabled)
|
|
741
773
|
this._setString(opts, 'clientIpHeader', options.clientIpHeader)
|
|
742
774
|
this._setString(opts, 'dbmPropagationMode', options.dbmPropagationMode)
|
|
@@ -751,22 +783,26 @@ class Config {
|
|
|
751
783
|
this._setString(opts, 'experimental.exporter', options.experimental && options.experimental.exporter)
|
|
752
784
|
this._setBoolean(opts, 'experimental.runtimeId', options.experimental && options.experimental.runtimeId)
|
|
753
785
|
this._setValue(opts, 'flushInterval', maybeInt(options.flushInterval))
|
|
786
|
+
this._optsUnprocessed.flushInterval = options.flushInterval
|
|
754
787
|
this._setValue(opts, 'flushMinSpans', maybeInt(options.flushMinSpans))
|
|
788
|
+
this._optsUnprocessed.flushMinSpans = options.flushMinSpans
|
|
755
789
|
this._setArray(opts, 'headerTags', options.headerTags)
|
|
756
790
|
this._setString(opts, 'hostname', options.hostname)
|
|
757
791
|
this._setBoolean(opts, 'iast.deduplicationEnabled', options.iastOptions && options.iastOptions.deduplicationEnabled)
|
|
758
792
|
this._setBoolean(opts, 'iast.enabled',
|
|
759
793
|
options.iastOptions && (options.iastOptions === true || options.iastOptions.enabled === true))
|
|
760
|
-
const iastRequestSampling = maybeInt(options.iastOptions?.requestSampling)
|
|
761
794
|
this._setValue(opts, 'iast.maxConcurrentRequests',
|
|
762
795
|
maybeInt(options.iastOptions?.maxConcurrentRequests))
|
|
763
|
-
this.
|
|
764
|
-
|
|
765
|
-
this.
|
|
796
|
+
this._optsUnprocessed['iast.maxConcurrentRequests'] = options.iastOptions?.maxConcurrentRequests
|
|
797
|
+
this._setValue(opts, 'iast.maxContextOperations', maybeInt(options.iastOptions?.maxContextOperations))
|
|
798
|
+
this._optsUnprocessed['iast.maxContextOperations'] = options.iastOptions?.maxContextOperations
|
|
799
|
+
this._setBoolean(opts, 'iast.redactionEnabled', options.iastOptions?.redactionEnabled)
|
|
766
800
|
this._setString(opts, 'iast.redactionNamePattern', options.iastOptions?.redactionNamePattern)
|
|
767
801
|
this._setString(opts, 'iast.redactionValuePattern', options.iastOptions?.redactionValuePattern)
|
|
802
|
+
const iastRequestSampling = maybeInt(options.iastOptions?.requestSampling)
|
|
768
803
|
if (iastRequestSampling > -1 && iastRequestSampling < 101) {
|
|
769
804
|
this._setValue(opts, 'iast.requestSampling', iastRequestSampling)
|
|
805
|
+
this._optsUnprocessed['iast.requestSampling'] = options.iastOptions?.requestSampling
|
|
770
806
|
}
|
|
771
807
|
this._setString(opts, 'iast.telemetryVerbosity', options.iastOptions && options.iastOptions.telemetryVerbosity)
|
|
772
808
|
this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
|
|
@@ -780,16 +816,19 @@ class Config {
|
|
|
780
816
|
this._setString(opts, 'protocolVersion', options.protocolVersion)
|
|
781
817
|
if (options.remoteConfig) {
|
|
782
818
|
this._setValue(opts, 'remoteConfig.pollInterval', maybeFloat(options.remoteConfig.pollInterval))
|
|
819
|
+
this._optsUnprocessed['remoteConfig.pollInterval'] = options.remoteConfig.pollInterval
|
|
783
820
|
}
|
|
784
821
|
this._setBoolean(opts, 'reportHostname', options.reportHostname)
|
|
785
822
|
this._setBoolean(opts, 'runtimeMetrics', options.runtimeMetrics)
|
|
786
823
|
this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))
|
|
787
824
|
const ingestion = options.ingestion || {}
|
|
788
825
|
this._setValue(opts, 'sampler.rateLimit', coalesce(options.rateLimit, ingestion.rateLimit))
|
|
826
|
+
this._setSamplingRule(opts, 'sampler.rules', options.samplingRules)
|
|
789
827
|
this._setString(opts, 'service', options.service || tags.service)
|
|
790
828
|
this._setString(opts, 'site', options.site)
|
|
791
829
|
if (options.spanAttributeSchema) {
|
|
792
830
|
this._setString(opts, 'spanAttributeSchema', validateNamingVersion(options.spanAttributeSchema))
|
|
831
|
+
this._optsUnprocessed.spanAttributeSchema = options.spanAttributeSchema
|
|
793
832
|
}
|
|
794
833
|
this._setBoolean(opts, 'spanRemoveIntegrationFromService', options.spanRemoveIntegrationFromService)
|
|
795
834
|
this._setBoolean(opts, 'startupLogs', options.startupLogs)
|
|
@@ -918,6 +957,7 @@ class Config {
|
|
|
918
957
|
|
|
919
958
|
_applyRemote (options) {
|
|
920
959
|
const opts = this._remote = this._remote || {}
|
|
960
|
+
this._remoteUnprocessed = {}
|
|
921
961
|
const tags = {}
|
|
922
962
|
const headerTags = options.tracing_header_tags
|
|
923
963
|
? options.tracing_header_tags.map(tag => {
|
|
@@ -933,6 +973,18 @@ class Config {
|
|
|
933
973
|
this._setArray(opts, 'headerTags', headerTags)
|
|
934
974
|
this._setTags(opts, 'tags', tags)
|
|
935
975
|
this._setBoolean(opts, 'tracing', options.tracing_enabled)
|
|
976
|
+
// ignore tags for now since rc sampling rule tags format is not supported
|
|
977
|
+
this._setSamplingRule(opts, 'sampler.rules', this._ignoreTags(options.tracing_sampling_rules))
|
|
978
|
+
this._remoteUnprocessed['sampler.rules'] = options.tracing_sampling_rules
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
_ignoreTags (samplingRules) {
|
|
982
|
+
if (samplingRules) {
|
|
983
|
+
for (const rule of samplingRules) {
|
|
984
|
+
delete rule.tags
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
return samplingRules
|
|
936
988
|
}
|
|
937
989
|
|
|
938
990
|
_setBoolean (obj, name, value) {
|
|
@@ -959,12 +1011,12 @@ class Config {
|
|
|
959
1011
|
}
|
|
960
1012
|
|
|
961
1013
|
_setArray (obj, name, value) {
|
|
962
|
-
if (value
|
|
1014
|
+
if (value == null) {
|
|
963
1015
|
return this._setValue(obj, name, null)
|
|
964
1016
|
}
|
|
965
1017
|
|
|
966
1018
|
if (typeof value === 'string') {
|
|
967
|
-
value = value
|
|
1019
|
+
value = value.split(',')
|
|
968
1020
|
}
|
|
969
1021
|
|
|
970
1022
|
if (Array.isArray(value)) {
|
|
@@ -972,6 +1024,25 @@ class Config {
|
|
|
972
1024
|
}
|
|
973
1025
|
}
|
|
974
1026
|
|
|
1027
|
+
_setSamplingRule (obj, name, value) {
|
|
1028
|
+
if (value == null) {
|
|
1029
|
+
return this._setValue(obj, name, null)
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
if (typeof value === 'string') {
|
|
1033
|
+
value = value.split(',')
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
if (Array.isArray(value)) {
|
|
1037
|
+
value = value.map(rule => {
|
|
1038
|
+
return remapify(rule, {
|
|
1039
|
+
sample_rate: 'sampleRate'
|
|
1040
|
+
})
|
|
1041
|
+
})
|
|
1042
|
+
this._setValue(obj, name, value)
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
975
1046
|
_setString (obj, name, value) {
|
|
976
1047
|
obj[name] = value ? String(value) : undefined // unset for empty strings
|
|
977
1048
|
}
|
|
@@ -997,18 +1068,21 @@ class Config {
|
|
|
997
1068
|
_merge () {
|
|
998
1069
|
const containers = [this._remote, this._options, this._env, this._calculated, this._defaults]
|
|
999
1070
|
const origins = ['remote_config', 'code', 'env_var', 'calculated', 'default']
|
|
1071
|
+
const unprocessedValues = [this._remoteUnprocessed, this._optsUnprocessed, this._envUnprocessed, {}, {}]
|
|
1000
1072
|
const changes = []
|
|
1001
1073
|
|
|
1002
1074
|
for (const name in this._defaults) {
|
|
1003
1075
|
for (let i = 0; i < containers.length; i++) {
|
|
1004
1076
|
const container = containers[i]
|
|
1005
1077
|
const origin = origins[i]
|
|
1078
|
+
const unprocessed = unprocessedValues[i]
|
|
1006
1079
|
|
|
1007
1080
|
if ((container[name] !== null && container[name] !== undefined) || container === this._defaults) {
|
|
1008
1081
|
if (get(this, name) === container[name] && has(this, name)) break
|
|
1009
1082
|
|
|
1010
|
-
|
|
1083
|
+
let value = container[name]
|
|
1011
1084
|
set(this, name, value)
|
|
1085
|
+
value = unprocessed[name] || value
|
|
1012
1086
|
|
|
1013
1087
|
changes.push({ name, value, origin })
|
|
1014
1088
|
|
|
@@ -1026,6 +1100,7 @@ function maybeInt (number) {
|
|
|
1026
1100
|
const parsed = parseInt(number)
|
|
1027
1101
|
return isNaN(parsed) ? undefined : parsed
|
|
1028
1102
|
}
|
|
1103
|
+
|
|
1029
1104
|
function maybeFloat (number) {
|
|
1030
1105
|
const parsed = parseFloat(number)
|
|
1031
1106
|
return isNaN(parsed) ? undefined : parsed
|
|
@@ -15,6 +15,8 @@ module.exports = {
|
|
|
15
15
|
SAMPLING_MECHANISM_MANUAL: 4,
|
|
16
16
|
SAMPLING_MECHANISM_APPSEC: 5,
|
|
17
17
|
SAMPLING_MECHANISM_SPAN: 8,
|
|
18
|
+
SAMPLING_MECHANISM_REMOTE_USER: 11,
|
|
19
|
+
SAMPLING_MECHANISM_REMOTE_DYNAMIC: 12,
|
|
18
20
|
SPAN_SAMPLING_MECHANISM: '_dd.span_sampling.mechanism',
|
|
19
21
|
SPAN_SAMPLING_RULE_RATE: '_dd.span_sampling.rule_rate',
|
|
20
22
|
SPAN_SAMPLING_MAX_PER_SECOND: '_dd.span_sampling.max_per_second',
|
|
@@ -120,7 +120,7 @@ class AgentEncoder {
|
|
|
120
120
|
this._encodeMap(bytes, span.metrics)
|
|
121
121
|
if (span.meta_struct) {
|
|
122
122
|
this._encodeString(bytes, 'meta_struct')
|
|
123
|
-
this.
|
|
123
|
+
this._encodeMetaStruct(bytes, span.meta_struct)
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -271,12 +271,48 @@ class AgentEncoder {
|
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
+
_encodeMetaStruct (bytes, value) {
|
|
275
|
+
const keys = Array.isArray(value) ? [] : Object.keys(value)
|
|
276
|
+
const validKeys = keys.filter(key => {
|
|
277
|
+
const v = value[key]
|
|
278
|
+
return typeof v === 'string' ||
|
|
279
|
+
typeof v === 'number' ||
|
|
280
|
+
(v !== null && typeof v === 'object')
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
this._encodeMapPrefix(bytes, validKeys.length)
|
|
284
|
+
|
|
285
|
+
for (const key of validKeys) {
|
|
286
|
+
const v = value[key]
|
|
287
|
+
this._encodeString(bytes, key)
|
|
288
|
+
this._encodeObjectAsByteArray(bytes, v)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
_encodeObjectAsByteArray (bytes, value) {
|
|
293
|
+
const prefixLength = 5
|
|
294
|
+
const offset = bytes.length
|
|
295
|
+
|
|
296
|
+
bytes.reserve(prefixLength)
|
|
297
|
+
bytes.length += prefixLength
|
|
298
|
+
|
|
299
|
+
this._encodeObject(bytes, value)
|
|
300
|
+
|
|
301
|
+
// we should do it after encoding the object to know the real length
|
|
302
|
+
const length = bytes.length - offset - prefixLength
|
|
303
|
+
bytes.buffer[offset] = 0xc6
|
|
304
|
+
bytes.buffer[offset + 1] = length >> 24
|
|
305
|
+
bytes.buffer[offset + 2] = length >> 16
|
|
306
|
+
bytes.buffer[offset + 3] = length >> 8
|
|
307
|
+
bytes.buffer[offset + 4] = length
|
|
308
|
+
}
|
|
309
|
+
|
|
274
310
|
_encodeObject (bytes, value, circularReferencesDetector = new Set()) {
|
|
275
311
|
circularReferencesDetector.add(value)
|
|
276
312
|
if (Array.isArray(value)) {
|
|
277
|
-
|
|
313
|
+
this._encodeObjectAsArray(bytes, value, circularReferencesDetector)
|
|
278
314
|
} else if (value !== null && typeof value === 'object') {
|
|
279
|
-
|
|
315
|
+
this._encodeObjectAsMap(bytes, value, circularReferencesDetector)
|
|
280
316
|
} else if (typeof value === 'string' || typeof value === 'number') {
|
|
281
317
|
this._encodeValue(bytes, value)
|
|
282
318
|
}
|
|
@@ -284,16 +320,19 @@ class AgentEncoder {
|
|
|
284
320
|
|
|
285
321
|
_encodeObjectAsMap (bytes, value, circularReferencesDetector) {
|
|
286
322
|
const keys = Object.keys(value)
|
|
287
|
-
const validKeys = keys.filter(key =>
|
|
288
|
-
|
|
289
|
-
typeof
|
|
290
|
-
|
|
323
|
+
const validKeys = keys.filter(key => {
|
|
324
|
+
const v = value[key]
|
|
325
|
+
return typeof v === 'string' ||
|
|
326
|
+
typeof v === 'number' ||
|
|
327
|
+
(v !== null && typeof v === 'object' && !circularReferencesDetector.has(v))
|
|
328
|
+
})
|
|
291
329
|
|
|
292
330
|
this._encodeMapPrefix(bytes, validKeys.length)
|
|
293
331
|
|
|
294
332
|
for (const key of validKeys) {
|
|
333
|
+
const v = value[key]
|
|
295
334
|
this._encodeString(bytes, key)
|
|
296
|
-
this._encodeObject(bytes,
|
|
335
|
+
this._encodeObject(bytes, v, circularReferencesDetector)
|
|
297
336
|
}
|
|
298
337
|
}
|
|
299
338
|
|
|
@@ -19,6 +19,7 @@ module.exports = name => {
|
|
|
19
19
|
return require('./ci-visibility/exporters/agent-proxy')
|
|
20
20
|
case exporters.JEST_WORKER:
|
|
21
21
|
case exporters.CUCUMBER_WORKER:
|
|
22
|
+
case exporters.MOCHA_WORKER:
|
|
22
23
|
return require('./ci-visibility/exporters/test-worker')
|
|
23
24
|
default:
|
|
24
25
|
return inAWSLambda && !usingLambdaExtension ? require('./exporters/log') : require('./exporters/agent')
|