Skip to content

Commit 7b141be

Browse files
authored
Accept trace sampling rules via remote-config (#6987)
* Report that we can now accept tracing-sample-rules via remote-config * Convert provenance string constants to enum and add LOCAL static config provenance * Rebuild sampler when remote-config trace sampling rules change
1 parent 485ef50 commit 7b141be

12 files changed

Lines changed: 232 additions & 59 deletions

File tree

dd-trace-core/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ excludedClassesCoverage += [
3737
'datadog.trace.core.datastreams.DataStreamContextInjector',
3838
'datadog.trace.common.sampling.TraceSamplingRules.RuleAdapter',
3939
'datadog.trace.common.sampling.SpanSamplingRules.RuleAdapter',
40+
'datadog.trace.core.TracingConfigPoller.SamplingRuleTagEntry',
41+
'datadog.trace.core.TracingConfigPoller.TracingSamplingRule',
42+
'datadog.trace.core.TracingConfigPoller.Updater',
4043
]
4144

4245
addTestSuite('traceAgentTest')

dd-trace-core/src/main/java/datadog/trace/common/sampling/SamplingRule.java renamed to dd-trace-core/src/main/java/datadog/trace/common/sampling/RateSamplingRule.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
import java.util.Map;
99
import java.util.regex.Pattern;
1010

11-
public abstract class SamplingRule {
11+
public abstract class RateSamplingRule {
1212
private final RateSampler sampler;
1313

14-
public SamplingRule(final RateSampler sampler) {
14+
public RateSamplingRule(final RateSampler sampler) {
1515
this.sampler = sampler;
1616
}
1717

@@ -25,7 +25,7 @@ public RateSampler getSampler() {
2525
return sampler;
2626
}
2727

28-
public static class AlwaysMatchesSamplingRule extends SamplingRule {
28+
public static class AlwaysMatchesSamplingRule extends RateSamplingRule {
2929

3030
public AlwaysMatchesSamplingRule(final RateSampler sampler) {
3131
super(sampler);
@@ -37,7 +37,7 @@ public <T extends CoreSpan<T>> boolean matches(final T span) {
3737
}
3838
}
3939

40-
public abstract static class PatternMatchSamplingRule extends SamplingRule {
40+
public abstract static class PatternMatchSamplingRule extends RateSamplingRule {
4141
private final Pattern pattern;
4242

4343
public PatternMatchSamplingRule(final String regex, final RateSampler sampler) {
@@ -76,7 +76,7 @@ protected <T extends CoreSpan<T>> CharSequence getRelevantString(final T span) {
7676
}
7777
}
7878

79-
public static final class TraceSamplingRule extends SamplingRule {
79+
public static final class TraceSamplingRule extends RateSamplingRule {
8080
private final Matcher serviceMatcher;
8181
private final Matcher operationMatcher;
8282
private final Matcher resourceMatcher;
@@ -104,7 +104,7 @@ public <T extends CoreSpan<T>> boolean matches(T span) {
104104
}
105105
}
106106

107-
public static final class SpanSamplingRule extends SamplingRule {
107+
public static final class SpanSamplingRule extends RateSamplingRule {
108108
private final Matcher serviceMatcher;
109109
private final Matcher operationMatcher;
110110
private final SimpleRateLimiter rateLimiter;

dd-trace-core/src/main/java/datadog/trace/common/sampling/RuleBasedTraceSampler.java

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import datadog.trace.api.config.TracerConfig;
44
import datadog.trace.api.sampling.PrioritySampling;
55
import datadog.trace.api.sampling.SamplingMechanism;
6-
import datadog.trace.common.sampling.SamplingRule.AlwaysMatchesSamplingRule;
7-
import datadog.trace.common.sampling.SamplingRule.OperationSamplingRule;
8-
import datadog.trace.common.sampling.SamplingRule.ServiceSamplingRule;
9-
import datadog.trace.common.sampling.SamplingRule.TraceSamplingRule;
6+
import datadog.trace.api.sampling.SamplingRule;
107
import datadog.trace.core.CoreSpan;
118
import datadog.trace.core.util.SimpleRateLimiter;
129
import java.util.ArrayList;
@@ -19,7 +16,7 @@
1916
public class RuleBasedTraceSampler<T extends CoreSpan<T>> implements Sampler, PrioritySampler {
2017

2118
private static final Logger log = LoggerFactory.getLogger(RuleBasedTraceSampler.class);
22-
private final List<SamplingRule> samplingRules;
19+
private final List<RateSamplingRule> samplingRules;
2320
private final PrioritySampler fallbackSampler;
2421
private final SimpleRateLimiter rateLimiter;
2522
private final long rateLimit;
@@ -28,7 +25,7 @@ public class RuleBasedTraceSampler<T extends CoreSpan<T>> implements Sampler, Pr
2825
public static final String SAMPLING_LIMIT_RATE = "_dd.limit_psr";
2926

3027
public RuleBasedTraceSampler(
31-
final List<SamplingRule> samplingRules,
28+
final List<RateSamplingRule> samplingRules,
3229
final int rateLimit,
3330
final PrioritySampler fallbackSampler) {
3431
this.samplingRules = samplingRules;
@@ -39,18 +36,20 @@ public RuleBasedTraceSampler(
3936
}
4037

4138
public static RuleBasedTraceSampler build(
42-
final TraceSamplingRules traceSamplingRules, final Double defaultRate, final int rateLimit) {
39+
final List<? extends SamplingRule.TraceSamplingRule> traceSamplingRules,
40+
final Double defaultRate,
41+
final int rateLimit) {
4342
return build(null, null, traceSamplingRules, defaultRate, rateLimit);
4443
}
4544

4645
public static RuleBasedTraceSampler build(
4746
@Deprecated final Map<String, String> serviceRules,
4847
@Deprecated final Map<String, String> operationRules,
49-
final TraceSamplingRules traceSamplingRules,
48+
final List<? extends SamplingRule.TraceSamplingRule> traceSamplingRules,
5049
final Double defaultRate,
5150
final int rateLimit) {
5251

53-
final List<SamplingRule> samplingRules = new ArrayList<>();
52+
final List<RateSamplingRule> samplingRules = new ArrayList<>();
5453

5554
if (traceSamplingRules != null && !traceSamplingRules.isEmpty()) {
5655
if ((!serviceRules.isEmpty() || !operationRules.isEmpty())) {
@@ -62,9 +61,9 @@ public static RuleBasedTraceSampler build(
6261
TracerConfig.TRACE_SAMPLING_RULES);
6362
}
6463
// Ignore serviceRules & operationRules if traceSamplingRules are defined
65-
for (TraceSamplingRules.Rule rule : traceSamplingRules.getRules()) {
66-
TraceSamplingRule samplingRule =
67-
new TraceSamplingRule(
64+
for (SamplingRule.TraceSamplingRule rule : traceSamplingRules) {
65+
RateSamplingRule.TraceSamplingRule samplingRule =
66+
new RateSamplingRule.TraceSamplingRule(
6867
rule.getService(),
6968
rule.getName(),
7069
rule.getResource(),
@@ -78,8 +77,8 @@ public static RuleBasedTraceSampler build(
7877
for (final Entry<String, String> entry : serviceRules.entrySet()) {
7978
try {
8079
final double rateForEntry = Double.parseDouble(entry.getValue());
81-
final SamplingRule samplingRule =
82-
new ServiceSamplingRule(
80+
final RateSamplingRule samplingRule =
81+
new RateSamplingRule.ServiceSamplingRule(
8382
entry.getKey(), new DeterministicSampler.TraceSampler(rateForEntry));
8483
samplingRules.add(samplingRule);
8584
} catch (final NumberFormatException e) {
@@ -92,8 +91,8 @@ public static RuleBasedTraceSampler build(
9291
for (final Entry<String, String> entry : operationRules.entrySet()) {
9392
try {
9493
final double rateForEntry = Double.parseDouble(entry.getValue());
95-
final SamplingRule samplingRule =
96-
new OperationSamplingRule(
94+
final RateSamplingRule samplingRule =
95+
new RateSamplingRule.OperationSamplingRule(
9796
entry.getKey(), new DeterministicSampler.TraceSampler(rateForEntry));
9897
samplingRules.add(samplingRule);
9998
} catch (final NumberFormatException e) {
@@ -104,8 +103,9 @@ public static RuleBasedTraceSampler build(
104103
}
105104

106105
if (defaultRate != null) {
107-
final SamplingRule samplingRule =
108-
new AlwaysMatchesSamplingRule(new DeterministicSampler.TraceSampler(defaultRate));
106+
final RateSamplingRule samplingRule =
107+
new RateSamplingRule.AlwaysMatchesSamplingRule(
108+
new DeterministicSampler.TraceSampler(defaultRate));
109109
samplingRules.add(samplingRule);
110110
}
111111

@@ -119,9 +119,9 @@ public <T extends CoreSpan<T>> boolean sample(final T span) {
119119

120120
@Override
121121
public <T extends CoreSpan<T>> void setSamplingPriority(final T span) {
122-
SamplingRule matchedRule = null;
122+
RateSamplingRule matchedRule = null;
123123

124-
for (final SamplingRule samplingRule : samplingRules) {
124+
for (final RateSamplingRule samplingRule : samplingRules) {
125125
if (samplingRule.matches(span)) {
126126
matchedRule = samplingRule;
127127
break;

dd-trace-core/src/main/java/datadog/trace/common/sampling/Sampler.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
import datadog.trace.api.config.TracerConfig;
99
import datadog.trace.api.sampling.PrioritySampling;
1010
import datadog.trace.api.sampling.SamplingMechanism;
11+
import datadog.trace.api.sampling.SamplingRule;
1112
import datadog.trace.core.CoreSpan;
13+
import java.util.Collections;
14+
import java.util.List;
1215
import java.util.Map;
1316
import java.util.Properties;
1417
import org.slf4j.Logger;
@@ -33,15 +36,19 @@ public static Sampler forConfig(final Config config, final TraceConfig traceConf
3336
if (config != null) {
3437
final Map<String, String> serviceRules = config.getTraceSamplingServiceRules();
3538
final Map<String, String> operationRules = config.getTraceSamplingOperationRules();
36-
String traceSamplingRulesJson = config.getTraceSamplingRules();
37-
TraceSamplingRules traceSamplingRules = TraceSamplingRules.EMPTY;
38-
if (traceSamplingRulesJson != null) {
39-
traceSamplingRules = TraceSamplingRules.deserialize(traceSamplingRulesJson);
39+
List<? extends SamplingRule.TraceSamplingRule> traceSamplingRules;
40+
if (null != traceConfig) {
41+
traceSamplingRules = traceConfig.getTraceSamplingRules();
42+
} else if (null != config.getTraceSamplingRules()) {
43+
traceSamplingRules =
44+
TraceSamplingRules.deserialize(config.getTraceSamplingRules()).getRules();
45+
} else {
46+
traceSamplingRules = Collections.emptyList();
4047
}
4148
boolean serviceRulesDefined = serviceRules != null && !serviceRules.isEmpty();
4249
boolean operationRulesDefined = operationRules != null && !operationRules.isEmpty();
43-
boolean jsonTraceSamplingRulesDefined = !traceSamplingRules.isEmpty();
44-
if ((serviceRulesDefined || operationRulesDefined) && jsonTraceSamplingRulesDefined) {
50+
boolean traceSamplingRulesDefined = !traceSamplingRules.isEmpty();
51+
if ((serviceRulesDefined || operationRulesDefined) && traceSamplingRulesDefined) {
4552
log.warn(
4653
"Both {} and/or {} as well as {} are defined. Only {} will be used for rule-based sampling",
4754
TracerConfig.TRACE_SAMPLING_SERVICE_RULES,
@@ -53,7 +60,7 @@ public static Sampler forConfig(final Config config, final TraceConfig traceConf
5360
null != traceConfig ? traceConfig.getTraceSampleRate() : config.getTraceSampleRate();
5461
if (serviceRulesDefined
5562
|| operationRulesDefined
56-
|| jsonTraceSamplingRulesDefined
63+
|| traceSamplingRulesDefined
5764
|| traceSampleRate != null) {
5865
try {
5966
sampler =

dd-trace-core/src/main/java/datadog/trace/common/sampling/SingleSpanSampler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ private Builder() {}
5353
}
5454

5555
final class RuleBasedSingleSpanSampler implements SingleSpanSampler {
56-
private final List<SamplingRule.SpanSamplingRule> spanSamplingRules;
56+
private final List<RateSamplingRule.SpanSamplingRule> spanSamplingRules;
5757

5858
public RuleBasedSingleSpanSampler(SpanSamplingRules rules) {
5959
if (rules == null) {
@@ -66,16 +66,16 @@ public RuleBasedSingleSpanSampler(SpanSamplingRules rules) {
6666
rule.getMaxPerSecond() == Integer.MAX_VALUE
6767
? null
6868
: new SimpleRateLimiter(rule.getMaxPerSecond());
69-
SamplingRule.SpanSamplingRule spanSamplingRule =
70-
new SamplingRule.SpanSamplingRule(
69+
RateSamplingRule.SpanSamplingRule spanSamplingRule =
70+
new RateSamplingRule.SpanSamplingRule(
7171
rule.getService(), rule.getName(), sampler, simpleRateLimiter);
7272
spanSamplingRules.add(spanSamplingRule);
7373
}
7474
}
7575

7676
@Override
7777
public <T extends CoreSpan<T>> boolean setSamplingPriority(T span) {
78-
for (SamplingRule.SpanSamplingRule rule : spanSamplingRules) {
78+
for (RateSamplingRule.SpanSamplingRule rule : spanSamplingRules) {
7979
if (rule.matches(span)) {
8080
if (rule.sample(span)) {
8181
double rate = rule.getSampler().getSampleRate();

dd-trace-core/src/main/java/datadog/trace/common/sampling/SpanSamplingRules.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public static final class Rule implements SamplingRule.SpanSamplingRule {
8888
private final Map<String, String> tags;
8989
private final double sampleRate;
9090
private final int maxPerSecond;
91-
private final String provenance;
91+
private final Provenance provenance;
9292

9393
private Rule(
9494
String service,
@@ -97,7 +97,7 @@ private Rule(
9797
Map<String, String> tags,
9898
double sampleRate,
9999
int maxPerSecond,
100-
String provenance) {
100+
Provenance provenance) {
101101
this.service = service;
102102
this.name = name;
103103
this.resource = resource;
@@ -148,7 +148,7 @@ public static Rule create(JsonRule jsonRule) {
148148
return null;
149149
}
150150
}
151-
return new Rule(service, name, resource, tags, sampleRate, maxPerSecond, CUSTOMER);
151+
return new Rule(service, name, resource, tags, sampleRate, maxPerSecond, Provenance.LOCAL);
152152
}
153153

154154
private static void logRuleError(JsonRule rule, String error) {
@@ -186,7 +186,7 @@ public int getMaxPerSecond() {
186186
}
187187

188188
@Override
189-
public String getProvenance() {
189+
public Provenance getProvenance() {
190190
return provenance;
191191
}
192192
}

dd-trace-core/src/main/java/datadog/trace/common/sampling/TraceSamplingRules.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ public static final class Rule implements SamplingRule.TraceSamplingRule {
6969
private final String resource;
7070
private final Map<String, String> tags;
7171
private final double sampleRate;
72-
private final String provenance;
72+
private final Provenance provenance;
7373

7474
private Rule(
7575
String service,
7676
String name,
7777
String resource,
7878
Map<String, String> tags,
7979
double sampleRate,
80-
String provenance) {
80+
Provenance provenance) {
8181
this.service = service;
8282
this.name = name;
8383
this.resource = resource;
@@ -113,7 +113,7 @@ public static Rule create(JsonRule jsonRule) {
113113
return null;
114114
}
115115
}
116-
return new Rule(service, name, resource, tags, sampleRate, CUSTOMER);
116+
return new Rule(service, name, resource, tags, sampleRate, Provenance.LOCAL);
117117
}
118118

119119
private static void logRuleError(JsonRule rule, String error) {
@@ -146,7 +146,7 @@ public double getSampleRate() {
146146
}
147147

148148
@Override
149-
public String getProvenance() {
149+
public Provenance getProvenance() {
150150
return provenance;
151151
}
152152
}

dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1620,7 +1620,8 @@ protected ConfigSnapshot(
16201620

16211621
if (null == oldSnapshot) {
16221622
sampler = CoreTracer.this.initialSampler;
1623-
} else if (Objects.equals(getTraceSampleRate(), oldSnapshot.getTraceSampleRate())) {
1623+
} else if (Objects.equals(getTraceSampleRate(), oldSnapshot.getTraceSampleRate())
1624+
&& Objects.equals(getTraceSamplingRules(), oldSnapshot.getTraceSamplingRules())) {
16241625
sampler = oldSnapshot.sampler;
16251626
} else {
16261627
sampler = Sampler.Builder.forConfig(CoreTracer.this.initialConfig, this);

0 commit comments

Comments
 (0)