Skip to content

Commit a835c25

Browse files
ida613tlhunter
andcommitted
Send original config value to telemetry (#4378)
* send original config values to telemetry --------- Co-authored-by: Thomas Hunter II <[email protected]>
1 parent 4fa2520 commit a835c25

File tree

2 files changed

+49
-22
lines changed

2 files changed

+49
-22
lines changed

packages/dd-trace/src/config.js

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -607,23 +607,28 @@ class Config {
607607

608608
const tags = {}
609609
const env = this._env = {}
610+
this._envUnprocessed = {}
610611

611612
tagger.add(tags, OTEL_RESOURCE_ATTRIBUTES, true)
612613
tagger.add(tags, DD_TAGS)
613614
tagger.add(tags, DD_TRACE_TAGS)
614615
tagger.add(tags, DD_TRACE_GLOBAL_TAGS)
615616

616617
this._setValue(env, 'appsec.blockedTemplateHtml', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML))
618+
this._envUnprocessed['appsec.blockedTemplateHtml'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML
617619
this._setValue(env, 'appsec.blockedTemplateJson', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON))
620+
this._envUnprocessed['appsec.blockedTemplateJson'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON
618621
this._setBoolean(env, 'appsec.enabled', DD_APPSEC_ENABLED)
619622
this._setString(env, 'appsec.obfuscatorKeyRegex', DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP)
620623
this._setString(env, 'appsec.obfuscatorValueRegex', DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP)
621624
this._setBoolean(env, 'appsec.rasp.enabled', DD_APPSEC_RASP_ENABLED)
622625
this._setValue(env, 'appsec.rateLimit', maybeInt(DD_APPSEC_TRACE_RATE_LIMIT))
626+
this._envUnprocessed['appsec.rateLimit'] = DD_APPSEC_TRACE_RATE_LIMIT
623627
this._setString(env, 'appsec.rules', DD_APPSEC_RULES)
624628
// DD_APPSEC_SCA_ENABLED is never used locally, but only sent to the backend
625629
this._setBoolean(env, 'appsec.sca.enabled', DD_APPSEC_SCA_ENABLED)
626630
this._setValue(env, 'appsec.wafTimeout', maybeInt(DD_APPSEC_WAF_TIMEOUT))
631+
this._envUnprocessed['appsec.wafTimeout'] = DD_APPSEC_WAF_TIMEOUT
627632
this._setBoolean(env, 'clientIpEnabled', DD_TRACE_CLIENT_IP_ENABLED)
628633
this._setString(env, 'clientIpHeader', DD_TRACE_CLIENT_IP_HEADER)
629634
this._setString(env, 'dbmPropagationMode', DD_DBM_PROPAGATION_MODE)
@@ -636,29 +641,35 @@ class Config {
636641
this._setBoolean(env, 'experimental.runtimeId', DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED)
637642
if (AWS_LAMBDA_FUNCTION_NAME) this._setValue(env, 'flushInterval', 0)
638643
this._setValue(env, 'flushMinSpans', maybeInt(DD_TRACE_PARTIAL_FLUSH_MIN_SPANS))
644+
this._envUnprocessed.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
639645
this._setBoolean(env, 'gitMetadataEnabled', DD_TRACE_GIT_METADATA_ENABLED)
640646
this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
641647
this._setString(env, 'hostname', coalesce(DD_AGENT_HOST, DD_TRACE_AGENT_HOSTNAME))
642648
this._setBoolean(env, 'iast.deduplicationEnabled', DD_IAST_DEDUPLICATION_ENABLED)
643649
this._setBoolean(env, 'iast.enabled', DD_IAST_ENABLED)
644650
this._setValue(env, 'iast.maxConcurrentRequests', maybeInt(DD_IAST_MAX_CONCURRENT_REQUESTS))
651+
this._envUnprocessed['iast.maxConcurrentRequests'] = DD_IAST_MAX_CONCURRENT_REQUESTS
645652
this._setValue(env, 'iast.maxContextOperations', maybeInt(DD_IAST_MAX_CONTEXT_OPERATIONS))
653+
this._envUnprocessed['iast.maxContextOperations'] = DD_IAST_MAX_CONTEXT_OPERATIONS
646654
this._setBoolean(env, 'iast.redactionEnabled', DD_IAST_REDACTION_ENABLED && !isFalse(DD_IAST_REDACTION_ENABLED))
647655
this._setString(env, 'iast.redactionNamePattern', DD_IAST_REDACTION_NAME_PATTERN)
648656
this._setString(env, 'iast.redactionValuePattern', DD_IAST_REDACTION_VALUE_PATTERN)
649657
const iastRequestSampling = maybeInt(DD_IAST_REQUEST_SAMPLING)
650658
if (iastRequestSampling > -1 && iastRequestSampling < 101) {
651659
this._setValue(env, 'iast.requestSampling', iastRequestSampling)
652660
}
661+
this._envUnprocessed['iast.requestSampling'] = DD_IAST_REQUEST_SAMPLING
653662
this._setString(env, 'iast.telemetryVerbosity', DD_IAST_TELEMETRY_VERBOSITY)
654663
this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
655664
this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
656665
this._setBoolean(env, 'openAiLogsEnabled', DD_OPENAI_LOGS_ENABLED)
657666
this._setValue(env, 'openaiSpanCharLimit', maybeInt(DD_OPENAI_SPAN_CHAR_LIMIT))
667+
this._envUnprocessed.openaiSpanCharLimit = DD_OPENAI_SPAN_CHAR_LIMIT
658668
if (DD_TRACE_PEER_SERVICE_MAPPING) {
659669
this._setValue(env, 'peerServiceMapping', fromEntries(
660-
process.env.DD_TRACE_PEER_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
670+
DD_TRACE_PEER_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
661671
))
672+
this._envUnprocessed.peerServiceMapping = DD_TRACE_PEER_SERVICE_MAPPING
662673
}
663674
this._setString(env, 'port', DD_TRACE_AGENT_PORT)
664675
this._setBoolean(env, 'profiling.enabled', coalesce(DD_EXPERIMENTAL_PROFILING_ENABLED, DD_PROFILING_ENABLED))
@@ -682,6 +693,7 @@ class Config {
682693
!this._isInServerlessEnvironment()
683694
))
684695
this._setValue(env, 'remoteConfig.pollInterval', maybeFloat(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS))
696+
this._envUnprocessed['remoteConfig.pollInterval'] = DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS
685697
this._setBoolean(env, 'reportHostname', DD_TRACE_REPORT_HOSTNAME)
686698
// only used to explicitly set runtimeMetrics to false
687699
const otelSetRuntimeMetrics = String(OTEL_METRICS_EXPORTER).toLowerCase() === 'none'
@@ -699,12 +711,14 @@ class Config {
699711
}
700712
this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE || OTEL_TRACES_SAMPLER_MAPPING[OTEL_TRACES_SAMPLER])
701713
this._setValue(env, 'sampler.rateLimit', DD_TRACE_RATE_LIMIT)
702-
this._setSamplingRule(env, 'sampler.rules', safeJsonParse(DD_TRACE_SAMPLING_RULES)) // example
714+
this._setSamplingRule(env, 'sampler.rules', safeJsonParse(DD_TRACE_SAMPLING_RULES))
715+
this._envUnprocessed['sampler.rules'] = DD_TRACE_SAMPLING_RULES
703716
this._setString(env, 'scope', DD_TRACE_SCOPE)
704717
this._setString(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service || OTEL_SERVICE_NAME)
705718
this._setString(env, 'site', DD_SITE)
706719
if (DD_TRACE_SPAN_ATTRIBUTE_SCHEMA) {
707720
this._setString(env, 'spanAttributeSchema', validateNamingVersion(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA))
721+
this._envUnprocessed.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
708722
}
709723
this._setBoolean(env, 'spanRemoveIntegrationFromService', DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)
710724
this._setBoolean(env, 'startupLogs', DD_TRACE_STARTUP_LOGS)
@@ -719,6 +733,7 @@ class Config {
719733
this._setBoolean(env, 'telemetry.debug', DD_TELEMETRY_DEBUG)
720734
this._setBoolean(env, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED)
721735
this._setValue(env, 'telemetry.heartbeatInterval', maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000)))
736+
this._envUnprocessed['telemetry.heartbeatInterval'] = DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000
722737
const hasTelemetryLogsUsingFeatures =
723738
env['iast.enabled'] || env['profiling.enabled'] || env['profiling.heuristicsEnabled']
724739
? true
@@ -735,20 +750,25 @@ class Config {
735750
_applyOptions (options) {
736751
const opts = this._options = this._options || {}
737752
const tags = {}
753+
this._optsUnprocessed = {}
738754

739755
options = this.options = Object.assign({ ingestion: {} }, options, opts)
740756

741757
tagger.add(tags, options.tags)
742758

743759
this._setValue(opts, 'appsec.blockedTemplateHtml', maybeFile(options.appsec.blockedTemplateHtml))
760+
this._optsUnprocessed['appsec.blockedTemplateHtml'] = options.appsec.blockedTemplateHtml
744761
this._setValue(opts, 'appsec.blockedTemplateJson', maybeFile(options.appsec.blockedTemplateJson))
762+
this._optsUnprocessed['appsec.blockedTemplateJson'] = options.appsec.blockedTemplateJson
745763
this._setBoolean(opts, 'appsec.enabled', options.appsec.enabled)
746764
this._setString(opts, 'appsec.obfuscatorKeyRegex', options.appsec.obfuscatorKeyRegex)
747765
this._setString(opts, 'appsec.obfuscatorValueRegex', options.appsec.obfuscatorValueRegex)
748766
this._setBoolean(opts, 'appsec.rasp.enabled', options.appsec.rasp?.enabled)
749767
this._setValue(opts, 'appsec.rateLimit', maybeInt(options.appsec.rateLimit))
768+
this._optsUnprocessed['appsec.rateLimit'] = options.appsec.rateLimit
750769
this._setString(opts, 'appsec.rules', options.appsec.rules)
751770
this._setValue(opts, 'appsec.wafTimeout', maybeInt(options.appsec.wafTimeout))
771+
this._optsUnprocessed['appsec.wafTimeout'] = options.appsec.wafTimeout
752772
this._setBoolean(opts, 'clientIpEnabled', options.clientIpEnabled)
753773
this._setString(opts, 'clientIpHeader', options.clientIpHeader)
754774
this._setString(opts, 'dbmPropagationMode', options.dbmPropagationMode)
@@ -763,22 +783,26 @@ class Config {
763783
this._setString(opts, 'experimental.exporter', options.experimental && options.experimental.exporter)
764784
this._setBoolean(opts, 'experimental.runtimeId', options.experimental && options.experimental.runtimeId)
765785
this._setValue(opts, 'flushInterval', maybeInt(options.flushInterval))
786+
this._optsUnprocessed.flushInterval = options.flushInterval
766787
this._setValue(opts, 'flushMinSpans', maybeInt(options.flushMinSpans))
788+
this._optsUnprocessed.flushMinSpans = options.flushMinSpans
767789
this._setArray(opts, 'headerTags', options.headerTags)
768790
this._setString(opts, 'hostname', options.hostname)
769791
this._setBoolean(opts, 'iast.deduplicationEnabled', options.iastOptions && options.iastOptions.deduplicationEnabled)
770792
this._setBoolean(opts, 'iast.enabled',
771793
options.iastOptions && (options.iastOptions === true || options.iastOptions.enabled === true))
772-
const iastRequestSampling = maybeInt(options.iastOptions?.requestSampling)
773794
this._setValue(opts, 'iast.maxConcurrentRequests',
774795
maybeInt(options.iastOptions?.maxConcurrentRequests))
775-
this._setValue(opts, 'iast.maxContextOperations',
776-
maybeInt(options.iastOptions && options.iastOptions.maxContextOperations))
777-
this._setBoolean(opts, 'iast.redactionEnabled', options.iastOptions && options.iastOptions.redactionEnabled)
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)
778800
this._setString(opts, 'iast.redactionNamePattern', options.iastOptions?.redactionNamePattern)
779801
this._setString(opts, 'iast.redactionValuePattern', options.iastOptions?.redactionValuePattern)
802+
const iastRequestSampling = maybeInt(options.iastOptions?.requestSampling)
780803
if (iastRequestSampling > -1 && iastRequestSampling < 101) {
781804
this._setValue(opts, 'iast.requestSampling', iastRequestSampling)
805+
this._optsUnprocessed['iast.requestSampling'] = options.iastOptions?.requestSampling
782806
}
783807
this._setString(opts, 'iast.telemetryVerbosity', options.iastOptions && options.iastOptions.telemetryVerbosity)
784808
this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
@@ -792,6 +816,7 @@ class Config {
792816
this._setString(opts, 'protocolVersion', options.protocolVersion)
793817
if (options.remoteConfig) {
794818
this._setValue(opts, 'remoteConfig.pollInterval', maybeFloat(options.remoteConfig.pollInterval))
819+
this._optsUnprocessed['remoteConfig.pollInterval'] = options.remoteConfig.pollInterval
795820
}
796821
this._setBoolean(opts, 'reportHostname', options.reportHostname)
797822
this._setBoolean(opts, 'runtimeMetrics', options.runtimeMetrics)
@@ -803,6 +828,7 @@ class Config {
803828
this._setString(opts, 'site', options.site)
804829
if (options.spanAttributeSchema) {
805830
this._setString(opts, 'spanAttributeSchema', validateNamingVersion(options.spanAttributeSchema))
831+
this._optsUnprocessed.spanAttributeSchema = options.spanAttributeSchema
806832
}
807833
this._setBoolean(opts, 'spanRemoveIntegrationFromService', options.spanRemoveIntegrationFromService)
808834
this._setBoolean(opts, 'startupLogs', options.startupLogs)
@@ -931,6 +957,7 @@ class Config {
931957

932958
_applyRemote (options) {
933959
const opts = this._remote = this._remote || {}
960+
this._remoteUnprocessed = {}
934961
const tags = {}
935962
const headerTags = options.tracing_header_tags
936963
? options.tracing_header_tags.map(tag => {
@@ -948,6 +975,7 @@ class Config {
948975
this._setBoolean(opts, 'tracing', options.tracing_enabled)
949976
// ignore tags for now since rc sampling rule tags format is not supported
950977
this._setSamplingRule(opts, 'sampler.rules', this._ignoreTags(options.trace_sample_rules))
978+
this._remoteUnprocessed['sampler.rules'] = options.trace_sample_rules
951979
}
952980

953981
_ignoreTags (samplingRules) {
@@ -1040,18 +1068,21 @@ class Config {
10401068
_merge () {
10411069
const containers = [this._remote, this._options, this._env, this._calculated, this._defaults]
10421070
const origins = ['remote_config', 'code', 'env_var', 'calculated', 'default']
1071+
const unprocessedValues = [this._remoteUnprocessed, this._optsUnprocessed, this._envUnprocessed, {}, {}]
10431072
const changes = []
10441073

10451074
for (const name in this._defaults) {
10461075
for (let i = 0; i < containers.length; i++) {
10471076
const container = containers[i]
10481077
const origin = origins[i]
1078+
const unprocessed = unprocessedValues[i]
10491079

10501080
if ((container[name] !== null && container[name] !== undefined) || container === this._defaults) {
10511081
if (get(this, name) === container[name] && has(this, name)) break
10521082

1053-
const value = container[name]
1083+
let value = container[name]
10541084
set(this, name, value)
1085+
value = unprocessed[name] || value
10551086

10561087
changes.push({ name, value, origin })
10571088

@@ -1069,6 +1100,7 @@ function maybeInt (number) {
10691100
const parsed = parseInt(number)
10701101
return isNaN(parsed) ? undefined : parsed
10711102
}
1103+
10721104
function maybeFloat (number) {
10731105
const parsed = parseFloat(number)
10741106
return isNaN(parsed) ? undefined : parsed

packages/dd-trace/test/config.spec.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -541,16 +541,16 @@ describe('Config', () => {
541541
expect(updateConfig).to.be.calledOnce
542542

543543
expect(updateConfig.getCall(0).args[0]).to.deep.include.members([
544-
{ name: 'appsec.blockedTemplateHtml', value: BLOCKED_TEMPLATE_HTML, origin: 'env_var' },
545-
{ name: 'appsec.blockedTemplateJson', value: BLOCKED_TEMPLATE_JSON, origin: 'env_var' },
544+
{ name: 'appsec.blockedTemplateHtml', value: BLOCKED_TEMPLATE_HTML_PATH, origin: 'env_var' },
545+
{ name: 'appsec.blockedTemplateJson', value: BLOCKED_TEMPLATE_JSON_PATH, origin: 'env_var' },
546546
{ name: 'appsec.enabled', value: true, origin: 'env_var' },
547547
{ name: 'appsec.obfuscatorKeyRegex', value: '.*', origin: 'env_var' },
548548
{ name: 'appsec.obfuscatorValueRegex', value: '.*', origin: 'env_var' },
549+
{ name: 'appsec.rateLimit', value: '42', origin: 'env_var' },
549550
{ name: 'appsec.rasp.enabled', value: true, origin: 'env_var' },
550-
{ name: 'appsec.rateLimit', value: 42, origin: 'env_var' },
551551
{ name: 'appsec.rules', value: RULES_JSON_PATH, origin: 'env_var' },
552552
{ name: 'appsec.sca.enabled', value: true, origin: 'env_var' },
553-
{ name: 'appsec.wafTimeout', value: 42, origin: 'env_var' },
553+
{ name: 'appsec.wafTimeout', value: '42', origin: 'env_var' },
554554
{ name: 'clientIpEnabled', value: true, origin: 'env_var' },
555555
{ name: 'clientIpHeader', value: 'x-true-client-ip', origin: 'env_var' },
556556
{ name: 'dogstatsd.hostname', value: 'dsd-agent', origin: 'env_var' },
@@ -562,36 +562,31 @@ describe('Config', () => {
562562
{ name: 'hostname', value: 'agent', origin: 'env_var' },
563563
{ name: 'iast.deduplicationEnabled', value: false, origin: 'env_var' },
564564
{ name: 'iast.enabled', value: true, origin: 'env_var' },
565-
{ name: 'iast.maxConcurrentRequests', value: 3, origin: 'env_var' },
566-
{ name: 'iast.maxContextOperations', value: 4, origin: 'env_var' },
565+
{ name: 'iast.maxConcurrentRequests', value: '3', origin: 'env_var' },
566+
{ name: 'iast.maxContextOperations', value: '4', origin: 'env_var' },
567567
{ name: 'iast.redactionEnabled', value: false, origin: 'env_var' },
568568
{ name: 'iast.redactionNamePattern', value: 'REDACTION_NAME_PATTERN', origin: 'env_var' },
569569
{ name: 'iast.redactionValuePattern', value: 'REDACTION_VALUE_PATTERN', origin: 'env_var' },
570-
{ name: 'iast.requestSampling', value: 40, origin: 'env_var' },
570+
{ name: 'iast.requestSampling', value: '40', origin: 'env_var' },
571571
{ name: 'iast.telemetryVerbosity', value: 'DEBUG', origin: 'env_var' },
572572
{ name: 'instrumentation_config_id', value: 'abcdef123', origin: 'env_var' },
573573
{ name: 'isGCPFunction', value: false, origin: 'env_var' },
574-
{ name: 'peerServiceMapping', value: { c: 'cc', d: 'dd' }, origin: 'env_var' },
574+
{ name: 'peerServiceMapping', value: process.env.DD_TRACE_PEER_SERVICE_MAPPING, origin: 'env_var' },
575575
{ name: 'port', value: '6218', origin: 'env_var' },
576576
{ name: 'profiling.enabled', value: true, origin: 'env_var' },
577577
{ name: 'profiling.heuristicsEnabled', value: true, origin: 'env_var' },
578578
{ name: 'profiling.ssi', value: true, origin: 'env_var' },
579579
{ name: 'protocolVersion', value: '0.5', origin: 'env_var' },
580580
{ name: 'queryStringObfuscation', value: '.*', origin: 'env_var' },
581581
{ name: 'remoteConfig.enabled', value: false, origin: 'env_var' },
582-
{ name: 'remoteConfig.pollInterval', value: 42, origin: 'env_var' },
582+
{ name: 'remoteConfig.pollInterval', value: '42', origin: 'env_var' },
583583
{ name: 'reportHostname', value: true, origin: 'env_var' },
584584
{ name: 'runtimeMetrics', value: true, origin: 'env_var' },
585585
{ name: 'sampleRate', value: 0.5, origin: 'env_var' },
586586
{ name: 'sampler.rateLimit', value: '-1', origin: 'env_var' },
587587
{
588588
name: 'sampler.rules',
589-
value: [
590-
{ service: 'usersvc', name: 'healthcheck', sampleRate: 0.0 },
591-
{ service: 'usersvc', sampleRate: 0.5 },
592-
{ service: 'authsvc', sampleRate: 1.0 },
593-
{ sampleRate: 0.1 }
594-
],
589+
value: process.env.DD_TRACE_SAMPLING_RULES,
595590
origin: 'env_var'
596591
},
597592
{ name: 'service', value: 'service', origin: 'env_var' },

0 commit comments

Comments
 (0)