dd-trace 5.15.0 → 5.16.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/package.json +1 -1
- package/packages/datadog-plugin-graphql/src/resolve.js +4 -0
- package/packages/dd-trace/src/config.js +40 -8
- package/packages/dd-trace/src/constants.js +2 -0
- package/packages/dd-trace/src/opentelemetry/span.js +8 -0
- package/packages/dd-trace/src/priority_sampler.js +8 -4
- package/packages/dd-trace/src/sampling_rule.js +2 -1
package/package.json
CHANGED
|
@@ -80,6 +80,10 @@ class GraphQLResolvePlugin extends TracingPlugin {
|
|
|
80
80
|
// this will disable resolve subscribers if `config.depth` is set to 0
|
|
81
81
|
super.configure(config.depth === 0 ? false : config)
|
|
82
82
|
}
|
|
83
|
+
|
|
84
|
+
finish (finishTime) {
|
|
85
|
+
this.activeSpan.finish(finishTime)
|
|
86
|
+
}
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
// helpers
|
|
@@ -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,16 +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)
|
|
621
624
|
this._setBoolean(env, 'appsec.rasp.enabled', DD_APPSEC_RASP_ENABLED)
|
|
622
625
|
this._setValue(env, 'appsec.rateLimit', maybeInt(DD_APPSEC_TRACE_RATE_LIMIT))
|
|
626
|
+
this._envUnprocessed['appsec.rateLimit'] = DD_APPSEC_TRACE_RATE_LIMIT
|
|
623
627
|
this._setString(env, 'appsec.rules', DD_APPSEC_RULES)
|
|
624
628
|
// DD_APPSEC_SCA_ENABLED is never used locally, but only sent to the backend
|
|
625
629
|
this._setBoolean(env, 'appsec.sca.enabled', DD_APPSEC_SCA_ENABLED)
|
|
626
630
|
this._setValue(env, 'appsec.wafTimeout', maybeInt(DD_APPSEC_WAF_TIMEOUT))
|
|
631
|
+
this._envUnprocessed['appsec.wafTimeout'] = DD_APPSEC_WAF_TIMEOUT
|
|
627
632
|
this._setBoolean(env, 'clientIpEnabled', DD_TRACE_CLIENT_IP_ENABLED)
|
|
628
633
|
this._setString(env, 'clientIpHeader', DD_TRACE_CLIENT_IP_HEADER)
|
|
629
634
|
this._setString(env, 'dbmPropagationMode', DD_DBM_PROPAGATION_MODE)
|
|
@@ -636,13 +641,16 @@ class Config {
|
|
|
636
641
|
this._setBoolean(env, 'experimental.runtimeId', DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED)
|
|
637
642
|
if (AWS_LAMBDA_FUNCTION_NAME) this._setValue(env, 'flushInterval', 0)
|
|
638
643
|
this._setValue(env, 'flushMinSpans', maybeInt(DD_TRACE_PARTIAL_FLUSH_MIN_SPANS))
|
|
644
|
+
this._envUnprocessed.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
|
|
639
645
|
this._setBoolean(env, 'gitMetadataEnabled', DD_TRACE_GIT_METADATA_ENABLED)
|
|
640
646
|
this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
|
|
641
647
|
this._setString(env, 'hostname', coalesce(DD_AGENT_HOST, DD_TRACE_AGENT_HOSTNAME))
|
|
642
648
|
this._setBoolean(env, 'iast.deduplicationEnabled', DD_IAST_DEDUPLICATION_ENABLED)
|
|
643
649
|
this._setBoolean(env, 'iast.enabled', DD_IAST_ENABLED)
|
|
644
650
|
this._setValue(env, 'iast.maxConcurrentRequests', maybeInt(DD_IAST_MAX_CONCURRENT_REQUESTS))
|
|
651
|
+
this._envUnprocessed['iast.maxConcurrentRequests'] = DD_IAST_MAX_CONCURRENT_REQUESTS
|
|
645
652
|
this._setValue(env, 'iast.maxContextOperations', maybeInt(DD_IAST_MAX_CONTEXT_OPERATIONS))
|
|
653
|
+
this._envUnprocessed['iast.maxContextOperations'] = DD_IAST_MAX_CONTEXT_OPERATIONS
|
|
646
654
|
this._setBoolean(env, 'iast.redactionEnabled', DD_IAST_REDACTION_ENABLED && !isFalse(DD_IAST_REDACTION_ENABLED))
|
|
647
655
|
this._setString(env, 'iast.redactionNamePattern', DD_IAST_REDACTION_NAME_PATTERN)
|
|
648
656
|
this._setString(env, 'iast.redactionValuePattern', DD_IAST_REDACTION_VALUE_PATTERN)
|
|
@@ -650,15 +658,18 @@ class Config {
|
|
|
650
658
|
if (iastRequestSampling > -1 && iastRequestSampling < 101) {
|
|
651
659
|
this._setValue(env, 'iast.requestSampling', iastRequestSampling)
|
|
652
660
|
}
|
|
661
|
+
this._envUnprocessed['iast.requestSampling'] = DD_IAST_REQUEST_SAMPLING
|
|
653
662
|
this._setString(env, 'iast.telemetryVerbosity', DD_IAST_TELEMETRY_VERBOSITY)
|
|
654
663
|
this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
|
|
655
664
|
this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
|
|
656
665
|
this._setBoolean(env, 'openAiLogsEnabled', DD_OPENAI_LOGS_ENABLED)
|
|
657
666
|
this._setValue(env, 'openaiSpanCharLimit', maybeInt(DD_OPENAI_SPAN_CHAR_LIMIT))
|
|
667
|
+
this._envUnprocessed.openaiSpanCharLimit = DD_OPENAI_SPAN_CHAR_LIMIT
|
|
658
668
|
if (DD_TRACE_PEER_SERVICE_MAPPING) {
|
|
659
669
|
this._setValue(env, 'peerServiceMapping', fromEntries(
|
|
660
|
-
|
|
670
|
+
DD_TRACE_PEER_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
|
|
661
671
|
))
|
|
672
|
+
this._envUnprocessed.peerServiceMapping = DD_TRACE_PEER_SERVICE_MAPPING
|
|
662
673
|
}
|
|
663
674
|
this._setString(env, 'port', DD_TRACE_AGENT_PORT)
|
|
664
675
|
this._setBoolean(env, 'profiling.enabled', coalesce(DD_EXPERIMENTAL_PROFILING_ENABLED, DD_PROFILING_ENABLED))
|
|
@@ -682,6 +693,7 @@ class Config {
|
|
|
682
693
|
!this._isInServerlessEnvironment()
|
|
683
694
|
))
|
|
684
695
|
this._setValue(env, 'remoteConfig.pollInterval', maybeFloat(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS))
|
|
696
|
+
this._envUnprocessed['remoteConfig.pollInterval'] = DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS
|
|
685
697
|
this._setBoolean(env, 'reportHostname', DD_TRACE_REPORT_HOSTNAME)
|
|
686
698
|
// only used to explicitly set runtimeMetrics to false
|
|
687
699
|
const otelSetRuntimeMetrics = String(OTEL_METRICS_EXPORTER).toLowerCase() === 'none'
|
|
@@ -699,12 +711,14 @@ class Config {
|
|
|
699
711
|
}
|
|
700
712
|
this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE || OTEL_TRACES_SAMPLER_MAPPING[OTEL_TRACES_SAMPLER])
|
|
701
713
|
this._setValue(env, 'sampler.rateLimit', DD_TRACE_RATE_LIMIT)
|
|
702
|
-
this._setSamplingRule(env, 'sampler.rules', safeJsonParse(DD_TRACE_SAMPLING_RULES))
|
|
714
|
+
this._setSamplingRule(env, 'sampler.rules', safeJsonParse(DD_TRACE_SAMPLING_RULES))
|
|
715
|
+
this._envUnprocessed['sampler.rules'] = DD_TRACE_SAMPLING_RULES
|
|
703
716
|
this._setString(env, 'scope', DD_TRACE_SCOPE)
|
|
704
717
|
this._setString(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service || OTEL_SERVICE_NAME)
|
|
705
718
|
this._setString(env, 'site', DD_SITE)
|
|
706
719
|
if (DD_TRACE_SPAN_ATTRIBUTE_SCHEMA) {
|
|
707
720
|
this._setString(env, 'spanAttributeSchema', validateNamingVersion(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA))
|
|
721
|
+
this._envUnprocessed.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
708
722
|
}
|
|
709
723
|
this._setBoolean(env, 'spanRemoveIntegrationFromService', DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)
|
|
710
724
|
this._setBoolean(env, 'startupLogs', DD_TRACE_STARTUP_LOGS)
|
|
@@ -719,6 +733,7 @@ class Config {
|
|
|
719
733
|
this._setBoolean(env, 'telemetry.debug', DD_TELEMETRY_DEBUG)
|
|
720
734
|
this._setBoolean(env, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED)
|
|
721
735
|
this._setValue(env, 'telemetry.heartbeatInterval', maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000)))
|
|
736
|
+
this._envUnprocessed['telemetry.heartbeatInterval'] = DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000
|
|
722
737
|
const hasTelemetryLogsUsingFeatures =
|
|
723
738
|
env['iast.enabled'] || env['profiling.enabled'] || env['profiling.heuristicsEnabled']
|
|
724
739
|
? true
|
|
@@ -735,20 +750,25 @@ class Config {
|
|
|
735
750
|
_applyOptions (options) {
|
|
736
751
|
const opts = this._options = this._options || {}
|
|
737
752
|
const tags = {}
|
|
753
|
+
this._optsUnprocessed = {}
|
|
738
754
|
|
|
739
755
|
options = this.options = Object.assign({ ingestion: {} }, options, opts)
|
|
740
756
|
|
|
741
757
|
tagger.add(tags, options.tags)
|
|
742
758
|
|
|
743
759
|
this._setValue(opts, 'appsec.blockedTemplateHtml', maybeFile(options.appsec.blockedTemplateHtml))
|
|
760
|
+
this._optsUnprocessed['appsec.blockedTemplateHtml'] = options.appsec.blockedTemplateHtml
|
|
744
761
|
this._setValue(opts, 'appsec.blockedTemplateJson', maybeFile(options.appsec.blockedTemplateJson))
|
|
762
|
+
this._optsUnprocessed['appsec.blockedTemplateJson'] = options.appsec.blockedTemplateJson
|
|
745
763
|
this._setBoolean(opts, 'appsec.enabled', options.appsec.enabled)
|
|
746
764
|
this._setString(opts, 'appsec.obfuscatorKeyRegex', options.appsec.obfuscatorKeyRegex)
|
|
747
765
|
this._setString(opts, 'appsec.obfuscatorValueRegex', options.appsec.obfuscatorValueRegex)
|
|
748
766
|
this._setBoolean(opts, 'appsec.rasp.enabled', options.appsec.rasp?.enabled)
|
|
749
767
|
this._setValue(opts, 'appsec.rateLimit', maybeInt(options.appsec.rateLimit))
|
|
768
|
+
this._optsUnprocessed['appsec.rateLimit'] = options.appsec.rateLimit
|
|
750
769
|
this._setString(opts, 'appsec.rules', options.appsec.rules)
|
|
751
770
|
this._setValue(opts, 'appsec.wafTimeout', maybeInt(options.appsec.wafTimeout))
|
|
771
|
+
this._optsUnprocessed['appsec.wafTimeout'] = options.appsec.wafTimeout
|
|
752
772
|
this._setBoolean(opts, 'clientIpEnabled', options.clientIpEnabled)
|
|
753
773
|
this._setString(opts, 'clientIpHeader', options.clientIpHeader)
|
|
754
774
|
this._setString(opts, 'dbmPropagationMode', options.dbmPropagationMode)
|
|
@@ -763,22 +783,26 @@ class Config {
|
|
|
763
783
|
this._setString(opts, 'experimental.exporter', options.experimental && options.experimental.exporter)
|
|
764
784
|
this._setBoolean(opts, 'experimental.runtimeId', options.experimental && options.experimental.runtimeId)
|
|
765
785
|
this._setValue(opts, 'flushInterval', maybeInt(options.flushInterval))
|
|
786
|
+
this._optsUnprocessed.flushInterval = options.flushInterval
|
|
766
787
|
this._setValue(opts, 'flushMinSpans', maybeInt(options.flushMinSpans))
|
|
788
|
+
this._optsUnprocessed.flushMinSpans = options.flushMinSpans
|
|
767
789
|
this._setArray(opts, 'headerTags', options.headerTags)
|
|
768
790
|
this._setString(opts, 'hostname', options.hostname)
|
|
769
791
|
this._setBoolean(opts, 'iast.deduplicationEnabled', options.iastOptions && options.iastOptions.deduplicationEnabled)
|
|
770
792
|
this._setBoolean(opts, 'iast.enabled',
|
|
771
793
|
options.iastOptions && (options.iastOptions === true || options.iastOptions.enabled === true))
|
|
772
|
-
const iastRequestSampling = maybeInt(options.iastOptions?.requestSampling)
|
|
773
794
|
this._setValue(opts, 'iast.maxConcurrentRequests',
|
|
774
795
|
maybeInt(options.iastOptions?.maxConcurrentRequests))
|
|
775
|
-
this.
|
|
776
|
-
|
|
777
|
-
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)
|
|
778
800
|
this._setString(opts, 'iast.redactionNamePattern', options.iastOptions?.redactionNamePattern)
|
|
779
801
|
this._setString(opts, 'iast.redactionValuePattern', options.iastOptions?.redactionValuePattern)
|
|
802
|
+
const iastRequestSampling = maybeInt(options.iastOptions?.requestSampling)
|
|
780
803
|
if (iastRequestSampling > -1 && iastRequestSampling < 101) {
|
|
781
804
|
this._setValue(opts, 'iast.requestSampling', iastRequestSampling)
|
|
805
|
+
this._optsUnprocessed['iast.requestSampling'] = options.iastOptions?.requestSampling
|
|
782
806
|
}
|
|
783
807
|
this._setString(opts, 'iast.telemetryVerbosity', options.iastOptions && options.iastOptions.telemetryVerbosity)
|
|
784
808
|
this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
|
|
@@ -792,6 +816,7 @@ class Config {
|
|
|
792
816
|
this._setString(opts, 'protocolVersion', options.protocolVersion)
|
|
793
817
|
if (options.remoteConfig) {
|
|
794
818
|
this._setValue(opts, 'remoteConfig.pollInterval', maybeFloat(options.remoteConfig.pollInterval))
|
|
819
|
+
this._optsUnprocessed['remoteConfig.pollInterval'] = options.remoteConfig.pollInterval
|
|
795
820
|
}
|
|
796
821
|
this._setBoolean(opts, 'reportHostname', options.reportHostname)
|
|
797
822
|
this._setBoolean(opts, 'runtimeMetrics', options.runtimeMetrics)
|
|
@@ -803,6 +828,7 @@ class Config {
|
|
|
803
828
|
this._setString(opts, 'site', options.site)
|
|
804
829
|
if (options.spanAttributeSchema) {
|
|
805
830
|
this._setString(opts, 'spanAttributeSchema', validateNamingVersion(options.spanAttributeSchema))
|
|
831
|
+
this._optsUnprocessed.spanAttributeSchema = options.spanAttributeSchema
|
|
806
832
|
}
|
|
807
833
|
this._setBoolean(opts, 'spanRemoveIntegrationFromService', options.spanRemoveIntegrationFromService)
|
|
808
834
|
this._setBoolean(opts, 'startupLogs', options.startupLogs)
|
|
@@ -931,6 +957,7 @@ class Config {
|
|
|
931
957
|
|
|
932
958
|
_applyRemote (options) {
|
|
933
959
|
const opts = this._remote = this._remote || {}
|
|
960
|
+
this._remoteUnprocessed = {}
|
|
934
961
|
const tags = {}
|
|
935
962
|
const headerTags = options.tracing_header_tags
|
|
936
963
|
? options.tracing_header_tags.map(tag => {
|
|
@@ -947,7 +974,8 @@ class Config {
|
|
|
947
974
|
this._setTags(opts, 'tags', tags)
|
|
948
975
|
this._setBoolean(opts, 'tracing', options.tracing_enabled)
|
|
949
976
|
// ignore tags for now since rc sampling rule tags format is not supported
|
|
950
|
-
this._setSamplingRule(opts, 'sampler.rules', this._ignoreTags(options.
|
|
977
|
+
this._setSamplingRule(opts, 'sampler.rules', this._ignoreTags(options.tracing_sampling_rules))
|
|
978
|
+
this._remoteUnprocessed['sampler.rules'] = options.tracing_sampling_rules
|
|
951
979
|
}
|
|
952
980
|
|
|
953
981
|
_ignoreTags (samplingRules) {
|
|
@@ -1040,18 +1068,21 @@ class Config {
|
|
|
1040
1068
|
_merge () {
|
|
1041
1069
|
const containers = [this._remote, this._options, this._env, this._calculated, this._defaults]
|
|
1042
1070
|
const origins = ['remote_config', 'code', 'env_var', 'calculated', 'default']
|
|
1071
|
+
const unprocessedValues = [this._remoteUnprocessed, this._optsUnprocessed, this._envUnprocessed, {}, {}]
|
|
1043
1072
|
const changes = []
|
|
1044
1073
|
|
|
1045
1074
|
for (const name in this._defaults) {
|
|
1046
1075
|
for (let i = 0; i < containers.length; i++) {
|
|
1047
1076
|
const container = containers[i]
|
|
1048
1077
|
const origin = origins[i]
|
|
1078
|
+
const unprocessed = unprocessedValues[i]
|
|
1049
1079
|
|
|
1050
1080
|
if ((container[name] !== null && container[name] !== undefined) || container === this._defaults) {
|
|
1051
1081
|
if (get(this, name) === container[name] && has(this, name)) break
|
|
1052
1082
|
|
|
1053
|
-
|
|
1083
|
+
let value = container[name]
|
|
1054
1084
|
set(this, name, value)
|
|
1085
|
+
value = unprocessed[name] || value
|
|
1055
1086
|
|
|
1056
1087
|
changes.push({ name, value, origin })
|
|
1057
1088
|
|
|
@@ -1069,6 +1100,7 @@ function maybeInt (number) {
|
|
|
1069
1100
|
const parsed = parseInt(number)
|
|
1070
1101
|
return isNaN(parsed) ? undefined : parsed
|
|
1071
1102
|
}
|
|
1103
|
+
|
|
1072
1104
|
function maybeFloat (number) {
|
|
1073
1105
|
const parsed = parseFloat(number)
|
|
1074
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',
|
|
@@ -179,11 +179,19 @@ class Span {
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
setAttribute (key, value) {
|
|
182
|
+
if (key === 'http.response.status_code') {
|
|
183
|
+
this._ddSpan.setTag('http.status_code', value.toString())
|
|
184
|
+
}
|
|
185
|
+
|
|
182
186
|
this._ddSpan.setTag(key, value)
|
|
183
187
|
return this
|
|
184
188
|
}
|
|
185
189
|
|
|
186
190
|
setAttributes (attributes) {
|
|
191
|
+
if ('http.response.status_code' in attributes) {
|
|
192
|
+
attributes['http.status_code'] = attributes['http.response.status_code'].toString()
|
|
193
|
+
}
|
|
194
|
+
|
|
187
195
|
this._ddSpan.addTags(attributes)
|
|
188
196
|
return this
|
|
189
197
|
}
|
|
@@ -10,6 +10,8 @@ const {
|
|
|
10
10
|
SAMPLING_MECHANISM_AGENT,
|
|
11
11
|
SAMPLING_MECHANISM_RULE,
|
|
12
12
|
SAMPLING_MECHANISM_MANUAL,
|
|
13
|
+
SAMPLING_MECHANISM_REMOTE_USER,
|
|
14
|
+
SAMPLING_MECHANISM_REMOTE_DYNAMIC,
|
|
13
15
|
SAMPLING_RULE_DECISION,
|
|
14
16
|
SAMPLING_LIMIT_DECISION,
|
|
15
17
|
SAMPLING_AGENT_DECISION,
|
|
@@ -41,9 +43,9 @@ class PrioritySampler {
|
|
|
41
43
|
this.update({})
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
configure (env, { sampleRate, rateLimit = 100, rules = [] } = {}) {
|
|
46
|
+
configure (env, { sampleRate, provenance = undefined, rateLimit = 100, rules = [] } = {}) {
|
|
45
47
|
this._env = env
|
|
46
|
-
this._rules = this._normalizeRules(rules, sampleRate, rateLimit)
|
|
48
|
+
this._rules = this._normalizeRules(rules, sampleRate, rateLimit, provenance)
|
|
47
49
|
this._limiter = new RateLimiter(rateLimit)
|
|
48
50
|
|
|
49
51
|
setSamplingRules(this._rules)
|
|
@@ -137,6 +139,8 @@ class PrioritySampler {
|
|
|
137
139
|
_getPriorityByRule (context, rule) {
|
|
138
140
|
context._trace[SAMPLING_RULE_DECISION] = rule.sampleRate
|
|
139
141
|
context._sampling.mechanism = SAMPLING_MECHANISM_RULE
|
|
142
|
+
if (rule.provenance === 'customer') context._sampling.mechanism = SAMPLING_MECHANISM_REMOTE_USER
|
|
143
|
+
if (rule.provenance === 'dynamic') context._sampling.mechanism = SAMPLING_MECHANISM_REMOTE_DYNAMIC
|
|
140
144
|
|
|
141
145
|
return rule.sample() && this._isSampledByRateLimit(context)
|
|
142
146
|
? USER_KEEP
|
|
@@ -181,11 +185,11 @@ class PrioritySampler {
|
|
|
181
185
|
}
|
|
182
186
|
}
|
|
183
187
|
|
|
184
|
-
_normalizeRules (rules, sampleRate, rateLimit) {
|
|
188
|
+
_normalizeRules (rules, sampleRate, rateLimit, provenance) {
|
|
185
189
|
rules = [].concat(rules || [])
|
|
186
190
|
|
|
187
191
|
return rules
|
|
188
|
-
.concat({ sampleRate, maxPerSecond: rateLimit })
|
|
192
|
+
.concat({ sampleRate, maxPerSecond: rateLimit, provenance })
|
|
189
193
|
.map(rule => ({ ...rule, sampleRate: parseFloat(rule.sampleRate) }))
|
|
190
194
|
.filter(rule => !isNaN(rule.sampleRate))
|
|
191
195
|
.map(SamplingRule.from)
|
|
@@ -64,7 +64,7 @@ function serviceLocator (span) {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
class SamplingRule {
|
|
67
|
-
constructor ({ name, service, resource, tags, sampleRate = 1.0, maxPerSecond } = {}) {
|
|
67
|
+
constructor ({ name, service, resource, tags, sampleRate = 1.0, provenance = undefined, maxPerSecond } = {}) {
|
|
68
68
|
this.matchers = []
|
|
69
69
|
|
|
70
70
|
if (name) {
|
|
@@ -82,6 +82,7 @@ class SamplingRule {
|
|
|
82
82
|
|
|
83
83
|
this._sampler = new Sampler(sampleRate)
|
|
84
84
|
this._limiter = undefined
|
|
85
|
+
this.provenance = provenance
|
|
85
86
|
|
|
86
87
|
if (Number.isFinite(maxPerSecond)) {
|
|
87
88
|
this._limiter = new RateLimiter(maxPerSecond)
|