Skip to content

Commit 2ecad69

Browse files
SylvainJugeCopilotMikeGoldsmith
authored
baggage delegate to IncludeExcludePredicate and allow wildcards in auto-configuration (#2802)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Mike Goldsmith <goldsmith.mike@gmail.com>
1 parent 7c18a2f commit 2ecad69

8 files changed

Lines changed: 107 additions & 66 deletions

File tree

baggage-processor/README.md

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ Do not put sensitive information in Baggage.
2222
If you are using the OpenTelemetry SDK auto-configuration, you can add the span and log baggage
2323
processors through configuration.
2424

25-
| Property | Description |
26-
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
27-
| `otel.java.experimental.span-attributes.copy-from-baggage.include` | Add baggage entries as span attributes, e.g. `key1,key2` or `*` to add all baggage items as keys. |
28-
| `otel.java.experimental.log-attributes.copy-from-baggage.include` | Add baggage entries as log attributes, e.g. `key1,key2` or `*` to add all baggage items as keys. |
25+
| Property | Description |
26+
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |
27+
| `otel.java.experimental.span-attributes.copy-from-baggage.include` | Add baggage entries as span attributes, e.g. `key1,key*`, wildcard pattern mathinc is supported. |
28+
| `otel.java.experimental.log-attributes.copy-from-baggage.include` | Add baggage entries as log attributes, e.g. `key1,key*`, wildcard pattern mathinc is supported. |
29+
30+
[Wildcard pattern matching]([wildcard pattern matching](https://github.com/open-telemetry/opentelemetry-configuration/blob/main/CONTRIBUTING.md#properties-requiring-pattern-matching)) is supported for both properties.
2931

3032
### Usage with declarative configuration
3133

@@ -58,40 +60,40 @@ This will configure the respective processor to include baggage keys listed in `
5860
exclude those in `excluded` as explained in
5961
[Properties requiring pattern matching](https://github.com/open-telemetry/opentelemetry-configuration/blob/main/CONTRIBUTING.md#properties-requiring-pattern-matching).
6062

63+
When both `included` and `excluded` are empty or not set, all the baggage entries will be copied.
64+
When only `included` is set, only the baggage entries matching the patterns in `included` will be copied (opt-in).
65+
When only `excluded` is set, all baggage entries except those matching the patterns in `excluded` will be copied (opt-out).
66+
When a value matches both `included` and `excluded`, then it is excluded.
67+
6168
### Usage through programmatic activation
6269

6370
Add the span and log processor when configuring the tracer and logger providers.
6471

6572
To configure the span and log processors to copy all baggage entries during configuration:
6673

6774
```java
68-
import io.opentelemetry.contrib.baggage.processor;
75+
import io.opentelemetry.contrib.baggage.processor.BaggageSpanProcessor;
76+
import io.opentelemetry.contrib.baggage.processor.BaggageLogProcessor;
77+
6978
// ...
7079
7180
TracerProvider tracerProvider = SdkTracerProvider.builder()
7281
.addSpanProcessor(BaggageSpanProcessor.allowAllBaggageKeys())
7382
.build();
7483
7584
LoggerProvider loggerProvider = SdkLoggerProvider.builder()
76-
.addLogRecordProcessor(BaggageLogRecordProcessor.allowAllBaggageKeys())
85+
.addLogProcessor(BaggageLogRecordProcessor.allowAllBaggageKeys())
7786
.build();
7887
```
7988

80-
Alternatively, you can provide a custom baggage key predicate to select which baggage keys you want to copy.
81-
82-
For example, to only copy baggage entries that start with `my-key`:
83-
84-
```java
85-
new BaggageSpanProcessor(baggageKey -> baggageKey.startsWith("my-key"));
86-
new BaggageLogRecordProcessor(baggageKey -> baggageKey.startsWith("my-key"));
87-
```
89+
Alternatively, you can provide a custom baggage key wildcards to select which baggage keys you want to include/exclude
90+
for copy.
8891

89-
For example, to only copy baggage entries that match the regex `^key.+`:
92+
For example, to only copy baggage entries that start with `my-key` and ignore keys that end with `*-ignored`
9093

9194
```java
92-
Pattern pattern = Pattern.compile("^key.+");
93-
new BaggageSpanProcessor(baggageKey -> pattern.matcher(baggageKey).matches());
94-
new BaggageLogRecordProcessor(baggageKey -> pattern.matcher(baggageKey).matches());
95+
new BaggageSpanProcessor(Collections.singletonList("my-key*"), Collections.singletonList("*-ignored"));
96+
new BaggageLogRecordProcessor(Collections.singletonList("my-key*"), Collections.singletonList("*-ignored"));
9597
```
9698

9799
## Component owners

baggage-processor/src/main/java/io/opentelemetry/contrib/baggage/processor/BaggageLogRecordComponentProvider.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import com.google.auto.service.AutoService;
99
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
1010
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
11-
import io.opentelemetry.sdk.common.internal.IncludeExcludePredicate;
1211
import io.opentelemetry.sdk.logs.LogRecordProcessor;
1312

1413
@AutoService(ComponentProvider.class)
@@ -21,9 +20,8 @@ public String getName() {
2120
@Override
2221
public LogRecordProcessor create(DeclarativeConfigProperties config) {
2322
return new BaggageLogRecordProcessor(
24-
IncludeExcludePredicate.createPatternMatching(
25-
config.getScalarList("included", String.class),
26-
config.getScalarList("excluded", String.class)));
23+
config.getScalarList("included", String.class),
24+
config.getScalarList("excluded", String.class));
2725
}
2826

2927
@Override

baggage-processor/src/main/java/io/opentelemetry/contrib/baggage/processor/BaggageLogRecordProcessor.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
import io.opentelemetry.api.baggage.Baggage;
99
import io.opentelemetry.api.common.AttributeKey;
1010
import io.opentelemetry.context.Context;
11+
import io.opentelemetry.sdk.common.internal.IncludeExcludePredicate;
1112
import io.opentelemetry.sdk.logs.LogRecordProcessor;
1213
import io.opentelemetry.sdk.logs.ReadWriteLogRecord;
14+
import java.util.Collection;
1315
import java.util.function.Predicate;
16+
import javax.annotation.Nullable;
1417

1518
/**
1619
* This log record processor copies attributes stored in {@link Baggage} into each newly created log
@@ -21,19 +24,36 @@ public final class BaggageLogRecordProcessor implements LogRecordProcessor {
2124
private final Predicate<String> baggageKeyPredicate;
2225

2326
/**
24-
* Creates a new {@link BaggageLogRecordProcessor} that copies only baggage entries with keys that
25-
* pass the provided filter into the newly created log record.
27+
* @deprecated Use {@link #BaggageLogRecordProcessor(Collection, Collection)} instead. Most usages
28+
* of this method should be replaceable with glob patterns, but not all thus this method is
29+
* kept to preserve compatibility.
2630
*/
31+
@Deprecated
2732
public BaggageLogRecordProcessor(Predicate<String> baggageKeyPredicate) {
2833
this.baggageKeyPredicate = baggageKeyPredicate;
2934
}
3035

36+
/**
37+
* Creates a new {@link BaggageLogRecordProcessor} that copies baggage entries with keys that pass
38+
* the provided include/exclude filtering into the newly created log record, when both arguments
39+
* are null or empty all baggage are included.
40+
*
41+
* @param included list of included baggage key patterns to include
42+
* @param excluded list of excluded baggage key patterns to exclude
43+
*/
44+
public BaggageLogRecordProcessor(
45+
@Nullable Collection<String> included, @Nullable Collection<String> excluded) {
46+
this.baggageKeyPredicate = IncludeExcludePredicate.createPatternMatching(included, excluded);
47+
}
48+
3149
/**
3250
* Creates a new {@link BaggageLogRecordProcessor} that copies all baggage entries into the newly
3351
* created log record.
52+
*
53+
* @return baggage log processor including all attributes
3454
*/
3555
public static BaggageLogRecordProcessor allowAllBaggageKeys() {
36-
return new BaggageLogRecordProcessor(baggageKey -> true);
56+
return new BaggageLogRecordProcessor(null, null);
3757
}
3858

3959
@Override

baggage-processor/src/main/java/io/opentelemetry/contrib/baggage/processor/BaggageProcessorCustomizer.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,7 @@ private static void addSpanProcessor(
4040
}
4141

4242
// need to add before the batch span processor
43-
sdkTracerProviderBuilder.addSpanProcessorFirst(createBaggageSpanProcessor(keys));
44-
}
45-
46-
static BaggageSpanProcessor createBaggageSpanProcessor(List<String> keys) {
47-
if (keys.size() == 1 && keys.get(0).equals("*")) {
48-
return BaggageSpanProcessor.allowAllBaggageKeys();
49-
}
50-
return new BaggageSpanProcessor(keys::contains);
43+
sdkTracerProviderBuilder.addSpanProcessorFirst(new BaggageSpanProcessor(keys, null));
5144
}
5245

5346
private static void addLogRecordProcessor(
@@ -60,13 +53,6 @@ private static void addLogRecordProcessor(
6053
}
6154

6255
// need to add before the batch log processor
63-
sdkLoggerProviderBuilder.addLogRecordProcessorFirst(createBaggageLogRecordProcessor(keys));
64-
}
65-
66-
static BaggageLogRecordProcessor createBaggageLogRecordProcessor(List<String> keys) {
67-
if (keys.size() == 1 && keys.get(0).equals("*")) {
68-
return BaggageLogRecordProcessor.allowAllBaggageKeys();
69-
}
70-
return new BaggageLogRecordProcessor(keys::contains);
56+
sdkLoggerProviderBuilder.addLogRecordProcessorFirst(new BaggageLogRecordProcessor(keys, null));
7157
}
7258
}

baggage-processor/src/main/java/io/opentelemetry/contrib/baggage/processor/BaggageSpanComponentProvider.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import com.google.auto.service.AutoService;
99
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
1010
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
11-
import io.opentelemetry.sdk.common.internal.IncludeExcludePredicate;
1211
import io.opentelemetry.sdk.trace.SpanProcessor;
1312

1413
@AutoService(ComponentProvider.class)
@@ -21,9 +20,8 @@ public String getName() {
2120
@Override
2221
public SpanProcessor create(DeclarativeConfigProperties config) {
2322
return new BaggageSpanProcessor(
24-
IncludeExcludePredicate.createPatternMatching(
25-
config.getScalarList("included", String.class),
26-
config.getScalarList("excluded", String.class)));
23+
config.getScalarList("included", String.class),
24+
config.getScalarList("excluded", String.class));
2725
}
2826

2927
@Override

baggage-processor/src/main/java/io/opentelemetry/contrib/baggage/processor/BaggageSpanProcessor.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77

88
import io.opentelemetry.api.baggage.Baggage;
99
import io.opentelemetry.context.Context;
10+
import io.opentelemetry.sdk.common.internal.IncludeExcludePredicate;
1011
import io.opentelemetry.sdk.trace.ReadWriteSpan;
1112
import io.opentelemetry.sdk.trace.ReadableSpan;
1213
import io.opentelemetry.sdk.trace.SpanProcessor;
14+
import java.util.Collection;
1315
import java.util.function.Predicate;
16+
import javax.annotation.Nullable;
1417

1518
/**
1619
* This span processor copies attributes stored in {@link Baggage} into each newly created {@link
@@ -20,19 +23,37 @@ public final class BaggageSpanProcessor implements SpanProcessor {
2023
private final Predicate<String> baggageKeyPredicate;
2124

2225
/**
23-
* Creates a new {@link BaggageSpanProcessor} that copies only baggage entries with keys that pass
24-
* the provided filter into the newly created {@link io.opentelemetry.api.trace.Span}.
26+
* @deprecated Use {@link #BaggageSpanProcessor(Collection, Collection)} instead. Most usages of
27+
* this method should be replaceable with glob patterns, but not all thus this method is kept
28+
* to preserve compatibility.
2529
*/
30+
@Deprecated
2631
public BaggageSpanProcessor(Predicate<String> baggageKeyPredicate) {
2732
this.baggageKeyPredicate = baggageKeyPredicate;
2833
}
2934

35+
/**
36+
* Creates a new {@link BaggageSpanProcessor} that copies baggage entries with keys that pass the
37+
* provided include/exclude filtering into the newly created {@link
38+
* io.opentelemetry.api.trace.Span}, when both arguments are null or empty all baggage are
39+
* included.
40+
*
41+
* @param included list of included baggage key patterns to include
42+
* @param excluded list of excluded baggage key patterns to exclude
43+
*/
44+
public BaggageSpanProcessor(
45+
@Nullable Collection<String> included, @Nullable Collection<String> excluded) {
46+
this.baggageKeyPredicate = IncludeExcludePredicate.createPatternMatching(included, excluded);
47+
}
48+
3049
/**
3150
* Creates a new {@link BaggageSpanProcessor} that copies all baggage entries into the newly
32-
* created {@link io.opentelemetry.api.trace.Span}.
51+
* created span.
52+
*
53+
* @return baggage span processor including all attributes
3354
*/
3455
public static BaggageSpanProcessor allowAllBaggageKeys() {
35-
return new BaggageSpanProcessor(baggageKey -> true);
56+
return new BaggageSpanProcessor(null, null);
3657
}
3758

3859
@Override

baggage-processor/src/test/java/io/opentelemetry/contrib/baggage/processor/BaggageProcessorCustomizerTest.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.contrib.baggage.processor;
77

88
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
9+
import static java.util.Collections.singletonList;
910
import static org.awaitility.Awaitility.await;
1011
import static org.mockito.Mockito.verify;
1112

@@ -122,7 +123,7 @@ private static OpenTelemetrySdk getOpenTelemetrySdk(
122123
@Override
123124
public <T> List<T> load(Class<T> spiClass) {
124125
if (spiClass.equals(ConfigurableSpanExporterProvider.class)) {
125-
return Collections.singletonList(
126+
return singletonList(
126127
spiClass.cast(
127128
new ConfigurableSpanExporterProvider() {
128129
@Override
@@ -137,7 +138,7 @@ public String getName() {
137138
}
138139
}));
139140
} else if (spiClass.equals(ConfigurableLogRecordExporterProvider.class)) {
140-
return Collections.singletonList(
141+
return singletonList(
141142
spiClass.cast(
142143
new ConfigurableLogRecordExporterProvider() {
143144
@Override
@@ -160,8 +161,7 @@ public String getName() {
160161

161162
@Test
162163
void test_baggageSpanProcessor_adds_attributes_to_spans(@Mock ReadWriteSpan span) {
163-
try (BaggageSpanProcessor processor =
164-
BaggageProcessorCustomizer.createBaggageSpanProcessor(Collections.singletonList("*"))) {
164+
try (BaggageSpanProcessor processor = BaggageSpanProcessor.allowAllBaggageKeys()) {
165165
try (Scope ignore = Baggage.current().toBuilder().put("key", "value").build().makeCurrent()) {
166166
processor.onStart(Context.current(), span);
167167
verify(span).setAttribute("key", "value");
@@ -172,8 +172,7 @@ void test_baggageSpanProcessor_adds_attributes_to_spans(@Mock ReadWriteSpan span
172172
@Test
173173
void test_baggageSpanProcessor_adds_attributes_to_spans_when_key_filter_matches(
174174
@Mock ReadWriteSpan span) {
175-
try (BaggageSpanProcessor processor =
176-
BaggageProcessorCustomizer.createBaggageSpanProcessor(Collections.singletonList("key"))) {
175+
try (BaggageSpanProcessor processor = new BaggageSpanProcessor(singletonList("key"), null)) {
177176
try (Scope ignore =
178177
Baggage.current().toBuilder()
179178
.put("key", "value")
@@ -191,8 +190,7 @@ void test_baggageSpanProcessor_adds_attributes_to_spans_when_key_filter_matches(
191190
void test_baggageLogRecordProcessor_adds_attributes_to_logRecord(
192191
@Mock ReadWriteLogRecord logRecord) {
193192
try (BaggageLogRecordProcessor processor =
194-
BaggageProcessorCustomizer.createBaggageLogRecordProcessor(
195-
Collections.singletonList("*"))) {
193+
new BaggageLogRecordProcessor(singletonList("*"), null)) {
196194
try (Scope ignore = Baggage.current().toBuilder().put("key", "value").build().makeCurrent()) {
197195
processor.onEmit(Context.current(), logRecord);
198196
verify(logRecord).setAttribute(AttributeKey.stringKey("key"), "value");
@@ -204,8 +202,7 @@ void test_baggageLogRecordProcessor_adds_attributes_to_logRecord(
204202
void test_baggageLogRecordProcessor_adds_attributes_to_spans_when_key_filter_matches(
205203
@Mock ReadWriteLogRecord logRecord) {
206204
try (BaggageLogRecordProcessor processor =
207-
BaggageProcessorCustomizer.createBaggageLogRecordProcessor(
208-
Collections.singletonList("key"))) {
205+
new BaggageLogRecordProcessor(singletonList("k*"), null)) {
209206
try (Scope ignore =
210207
Baggage.current().toBuilder()
211208
.put("key", "value")
@@ -218,4 +215,23 @@ void test_baggageLogRecordProcessor_adds_attributes_to_spans_when_key_filter_mat
218215
}
219216
}
220217
}
218+
219+
@Test
220+
void test_baggageLogRecordProcessor_adds_attributes_to_spans_include_exclude(
221+
@Mock ReadWriteLogRecord logRecord) {
222+
try (BaggageLogRecordProcessor processor =
223+
new BaggageLogRecordProcessor(singletonList("key*"), singletonList("*excluded"))) {
224+
try (Scope ignore =
225+
Baggage.current().toBuilder()
226+
.put("key", "value")
227+
.put("key_is_excluded", "value")
228+
.build()
229+
.makeCurrent()) {
230+
processor.onEmit(Context.current(), logRecord);
231+
verify(logRecord).setAttribute(AttributeKey.stringKey("key"), "value");
232+
verify(logRecord, Mockito.never())
233+
.setAttribute(AttributeKey.stringKey("key_is_excluded"), "value");
234+
}
235+
}
236+
}
221237
}

baggage-processor/src/test/java/io/opentelemetry/contrib/baggage/processor/BaggageSpanProcessorTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55

66
package io.opentelemetry.contrib.baggage.processor;
77

8+
import static java.util.Collections.singletonList;
9+
810
import io.opentelemetry.api.baggage.Baggage;
911
import io.opentelemetry.context.Context;
1012
import io.opentelemetry.context.Scope;
1113
import io.opentelemetry.sdk.trace.ReadWriteSpan;
12-
import java.util.regex.Pattern;
1314
import org.junit.jupiter.api.Test;
1415
import org.junit.jupiter.api.extension.ExtendWith;
1516
import org.mockito.Mock;
@@ -32,7 +33,7 @@ void test_baggageSpanProcessor_adds_attributes_to_spans(@Mock ReadWriteSpan span
3233
@Test
3334
void test_baggageSpanProcessor_adds_attributes_to_spans_when_key_filter_matches(
3435
@Mock ReadWriteSpan span) {
35-
try (BaggageSpanProcessor processor = new BaggageSpanProcessor(key -> key.startsWith("k"))) {
36+
try (BaggageSpanProcessor processor = new BaggageSpanProcessor(singletonList("k*"), null)) {
3637
try (Scope ignore =
3738
Baggage.current().toBuilder()
3839
.put("key", "value")
@@ -47,20 +48,19 @@ void test_baggageSpanProcessor_adds_attributes_to_spans_when_key_filter_matches(
4748
}
4849

4950
@Test
50-
void test_baggageSpanProcessor_adds_attributes_to_spans_when_key_filter_matches_regex(
51+
void test_baggageSpanProcessor_adds_attributes_to_spans_include_exclude(
5152
@Mock ReadWriteSpan span) {
52-
Pattern pattern = Pattern.compile("k.*");
5353
try (BaggageSpanProcessor processor =
54-
new BaggageSpanProcessor(key -> pattern.matcher(key).matches())) {
54+
new BaggageSpanProcessor(singletonList("k*"), singletonList("*ignored"))) {
5555
try (Scope ignore =
5656
Baggage.current().toBuilder()
5757
.put("key", "value")
58-
.put("other", "value")
58+
.put("key_is_ignored", "value")
5959
.build()
6060
.makeCurrent()) {
6161
processor.onStart(Context.current(), span);
6262
Mockito.verify(span).setAttribute("key", "value");
63-
Mockito.verify(span, Mockito.never()).setAttribute("other", "value");
63+
Mockito.verify(span, Mockito.never()).setAttribute("key_is_ignored", "value");
6464
}
6565
}
6666
}

0 commit comments

Comments
 (0)