Skip to content

Commit a80ddb8

Browse files
committed
2 parents ca91bec + 8f081ba commit a80ddb8

63 files changed

Lines changed: 1045 additions & 550 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## Version 1.8.0 (unreleased):
44

5+
### API
6+
7+
- New `AttributesBuilder#remove(String)` and `AttributeBuilder#removeIf(Predicate<AttributeKey<?>>)`
8+
methods improve ergonomics of modifying attributes.
9+
510
### SDK
611

712
#### Logging (alpha)

CONTRIBUTING.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ It does not support all required rules, so you still have to run `spotlessApply`
143143

144144
## Specific tasks
145145

146+
### Updating the Snapshot build number
147+
148+
The overall version number for opentelemetry-java is determined from git tags, and not fixed in any file.
149+
150+
This means it will not update, even if you `git pull` from the repo tip. It will still produce a set of libraries with the old version number.
151+
152+
To update it, you must fetch the tags, via `git fetch --all --tags` - which should work, even if you have forked the repo, as long as the trunk repo is set as an upstream remote.
153+
146154
### Updating OTLP proto dependency version
147155

148156
The OTLP proto dependency version is defined [here](proto/build.gradle). To bump the version,

api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,17 @@ private static OpenTelemetry maybeAutoConfigure() {
161161
final Class<?> openTelemetrySdkAutoConfiguration;
162162
try {
163163
openTelemetrySdkAutoConfiguration =
164-
Class.forName("io.opentelemetry.sdk.autoconfigure.OpenTelemetrySdkAutoConfiguration");
164+
Class.forName("io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk");
165165
} catch (ClassNotFoundException e) {
166166
return null;
167167
}
168168

169169
try {
170170
Method initialize = openTelemetrySdkAutoConfiguration.getMethod("initialize");
171-
return (OpenTelemetry) initialize.invoke(null);
171+
Object autoConfiguredSdk = initialize.invoke(null);
172+
Method getOpenTelemetrySdk =
173+
openTelemetrySdkAutoConfiguration.getMethod("getOpenTelemetrySdk");
174+
return (OpenTelemetry) getOpenTelemetrySdk.invoke(autoConfiguredSdk);
172175
} catch (NoSuchMethodException | IllegalAccessException e) {
173176
throw new IllegalStateException(
174177
"OpenTelemetrySdkAutoConfiguration detected on classpath "

api/all/src/main/java/io/opentelemetry/api/common/ArrayBackedAttributesBuilder.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.ArrayList;
99
import java.util.Arrays;
1010
import java.util.List;
11+
import java.util.function.Predicate;
1112

1213
class ArrayBackedAttributesBuilder implements AttributesBuilder {
1314
private final List<Object> data;
@@ -22,7 +23,9 @@ class ArrayBackedAttributesBuilder implements AttributesBuilder {
2223

2324
@Override
2425
public Attributes build() {
25-
if (data.size() == 2) {
26+
// If only one key-value pair AND the entry hasn't been set to null (by #remove(AttributeKey<T>)
27+
// or #removeIf(Predicate<AttributeKey<?>>)), then we can bypass sorting and filtering
28+
if (data.size() == 2 && data.get(0) != null) {
2629
return new ArrayBackedAttributes(data.toArray());
2730
}
2831
return ArrayBackedAttributes.sortAndFilterToAttributes(data.toArray());
@@ -55,6 +58,32 @@ public AttributesBuilder putAll(Attributes attributes) {
5558
return this;
5659
}
5760

61+
@Override
62+
public <T> AttributesBuilder remove(AttributeKey<T> key) {
63+
if (key == null || key.getKey().isEmpty()) {
64+
return this;
65+
}
66+
return removeIf(
67+
entryKey ->
68+
key.getKey().equals(entryKey.getKey()) && key.getType().equals(entryKey.getType()));
69+
}
70+
71+
@Override
72+
public AttributesBuilder removeIf(Predicate<AttributeKey<?>> predicate) {
73+
if (predicate == null) {
74+
return this;
75+
}
76+
for (int i = 0; i < data.size() - 1; i += 2) {
77+
Object entry = data.get(i);
78+
if (entry instanceof AttributeKey && predicate.test((AttributeKey<?>) entry)) {
79+
// null items are filtered out in ArrayBackedAttributes
80+
data.set(i, null);
81+
data.set(i + 1, null);
82+
}
83+
}
84+
return this;
85+
}
86+
5887
static List<Double> toList(double... values) {
5988
Double[] boxed = new Double[values.length];
6089
for (int i = 0; i < values.length; i++) {

api/all/src/main/java/io/opentelemetry/api/common/AttributesBuilder.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import static io.opentelemetry.api.common.AttributeKey.stringKey;
1717

1818
import java.util.Arrays;
19+
import java.util.function.Predicate;
1920

2021
/** A builder of {@link Attributes} supporting an arbitrary number of key-value pairs. */
2122
public interface AttributesBuilder {
@@ -150,4 +151,26 @@ default AttributesBuilder put(String key, boolean... value) {
150151
* @return this Builder
151152
*/
152153
AttributesBuilder putAll(Attributes attributes);
154+
155+
/**
156+
* Remove all attributes where {@link AttributeKey#getKey()} and {@link AttributeKey#getType()}
157+
* match the {@code key}.
158+
*
159+
* @return this Builder
160+
*/
161+
default <T> AttributesBuilder remove(AttributeKey<T> key) {
162+
// default implementation is no-op
163+
return this;
164+
}
165+
166+
/**
167+
* Remove all attributes that satisfy the given predicate. Errors or runtime exceptions thrown by
168+
* the predicate are relayed to the caller.
169+
*
170+
* @return this Builder
171+
*/
172+
default AttributesBuilder removeIf(Predicate<AttributeKey<?>> filter) {
173+
// default implementation is no-op
174+
return this;
175+
}
153176
}

api/all/src/test/java/io/opentelemetry/api/common/AttributesTest.java

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import static io.opentelemetry.api.common.AttributeKey.stringKey;
1616
import static java.util.Collections.singletonList;
1717
import static org.assertj.core.api.Assertions.assertThat;
18+
import static org.assertj.core.api.Assertions.assertThatCode;
1819
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1920
import static org.assertj.core.api.Assertions.entry;
2021

@@ -420,4 +421,115 @@ void onlySameTypeCanRetrieveValue() {
420421
assertThat(attributes.get(stringKey("animal"))).isEqualTo("cat");
421422
assertThat(attributes.get(longKey("animal"))).isNull();
422423
}
424+
425+
@Test
426+
void remove() {
427+
AttributesBuilder builder = Attributes.builder();
428+
assertThat(builder.remove(stringKey(""))).isEqualTo(builder);
429+
430+
Attributes attributes = Attributes.builder().remove(stringKey("key1")).build();
431+
assertThat(attributes).isEqualTo(Attributes.builder().build());
432+
433+
attributes =
434+
Attributes.builder().put("key1", "value1").build().toBuilder()
435+
.remove(stringKey("key1"))
436+
.remove(stringKey("key1"))
437+
.build();
438+
assertThat(attributes).isEqualTo(Attributes.builder().build());
439+
440+
attributes =
441+
Attributes.builder()
442+
.put("key1", "value1")
443+
.put("key1", "value2")
444+
.put("key2", "value2")
445+
.put("key3", "value3")
446+
.remove(stringKey("key1"))
447+
.build();
448+
assertThat(attributes)
449+
.isEqualTo(Attributes.builder().put("key2", "value2").put("key3", "value3").build());
450+
451+
attributes =
452+
Attributes.builder()
453+
.put("key1", "value1")
454+
.put("key1", true)
455+
.remove(stringKey("key1"))
456+
.remove(stringKey("key1"))
457+
.build();
458+
assertThat(attributes).isEqualTo(Attributes.builder().put("key1", true).build());
459+
}
460+
461+
@Test
462+
void removeIf() {
463+
AttributesBuilder builder = Attributes.builder();
464+
assertThat(builder.removeIf(unused -> true)).isEqualTo(builder);
465+
466+
Attributes attributes =
467+
Attributes.builder().removeIf(key -> key.getKey().equals("key1")).build();
468+
assertThat(attributes).isEqualTo(Attributes.builder().build());
469+
470+
attributes =
471+
Attributes.builder().put("key1", "value1").build().toBuilder()
472+
.removeIf(key -> key.getKey().equals("key1"))
473+
.removeIf(key -> key.getKey().equals("key1"))
474+
.build();
475+
assertThat(attributes).isEqualTo(Attributes.builder().build());
476+
477+
attributes =
478+
Attributes.builder()
479+
.put("key1", "value1")
480+
.put("key1", "value2")
481+
.put("key2", "value2")
482+
.put("key3", "value3")
483+
.removeIf(key -> key.getKey().equals("key1"))
484+
.build();
485+
assertThat(attributes)
486+
.isEqualTo(Attributes.builder().put("key2", "value2").put("key3", "value3").build());
487+
488+
attributes =
489+
Attributes.builder()
490+
.put("key1", "value1A")
491+
.put("key1", true)
492+
.removeIf(
493+
key -> key.getKey().equals("key1") && key.getType().equals(AttributeType.STRING))
494+
.build();
495+
assertThat(attributes).isEqualTo(Attributes.builder().put("key1", true).build());
496+
497+
attributes =
498+
Attributes.builder()
499+
.put("key1", "value1")
500+
.put("key2", "value2")
501+
.put("foo", "bar")
502+
.removeIf(key -> key.getKey().matches("key.*"))
503+
.build();
504+
assertThat(attributes).isEqualTo(Attributes.builder().put("foo", "bar").build());
505+
}
506+
507+
@Test
508+
void remove_defaultImplementationDoesNotThrow() {
509+
AttributesBuilder myAttributesBuilder =
510+
new AttributesBuilder() {
511+
@Override
512+
public Attributes build() {
513+
return null;
514+
}
515+
516+
@Override
517+
public <T> AttributesBuilder put(AttributeKey<Long> key, int value) {
518+
return null;
519+
}
520+
521+
@Override
522+
public <T> AttributesBuilder put(AttributeKey<T> key, T value) {
523+
return null;
524+
}
525+
526+
@Override
527+
public AttributesBuilder putAll(Attributes attributes) {
528+
return null;
529+
}
530+
};
531+
532+
assertThatCode(() -> myAttributesBuilder.remove(stringKey("foo"))).doesNotThrowAnyException();
533+
assertThatCode(() -> myAttributesBuilder.removeIf(unused -> false)).doesNotThrowAnyException();
534+
}
423535
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
Comparing source compatibility of against
2-
No changes.
2+
***! MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.common.AttributesBuilder (not serializable)
3+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
4+
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.AttributesBuilder remove(io.opentelemetry.api.common.AttributeKey)
5+
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.AttributesBuilder removeIf(java.util.function.Predicate)
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
11
Comparing source compatibility of against
2-
No changes.
2+
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable)
3+
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
4+
+++ NEW SUPERCLASS: java.lang.Object
5+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addPropagatorCustomizer(java.util.function.BiFunction)
6+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addPropertiesSupplier(java.util.function.Supplier)
7+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addResourceCustomizer(java.util.function.BiFunction)
8+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addSamplerCustomizer(java.util.function.BiFunction)
9+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addSpanExporterCustomizer(java.util.function.BiFunction)
10+
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider (not serializable)
11+
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
12+
+++ NEW SUPERCLASS: java.lang.Object
13+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void customize(io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer)

exporters/jaeger/build.gradle.kts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,20 @@ dependencies {
2121
implementation(project(":exporters:otlp:common"))
2222
implementation(project(":semconv"))
2323

24-
implementation("io.grpc:grpc-stub")
24+
compileOnly("io.grpc:grpc-stub")
25+
2526
implementation("com.fasterxml.jackson.jr:jackson-jr-objects")
2627

2728
testImplementation(project(":exporters:jaeger-proto"))
2829

2930
testImplementation("com.fasterxml.jackson.jr:jackson-jr-stree")
3031
testImplementation("com.google.protobuf:protobuf-java-util")
32+
testImplementation("com.linecorp.armeria:armeria-junit5")
33+
testImplementation("com.linecorp.armeria:armeria-grpc-protocol")
3134
testImplementation("com.squareup.okhttp3:okhttp")
32-
testImplementation("io.grpc:grpc-protobuf")
33-
testImplementation("io.grpc:grpc-testing")
3435
testImplementation("org.testcontainers:junit-jupiter")
3536

3637
testImplementation(project(":sdk:testing"))
37-
38-
testRuntimeOnly("io.grpc:grpc-netty-shaded")
3938
}
4039

4140
wire {

0 commit comments

Comments
 (0)