diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/Span.java b/api/all/src/main/java/io/opentelemetry/api/trace/Span.java index 8f1f1381a71..898e05a4e9d 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/Span.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/Span.java @@ -91,8 +91,7 @@ static Span wrap(SpanContext spanContext) { * Sets an attribute to the {@code Span}. If the {@code Span} previously contained a mapping for * the key, the old value is replaced by the specified value. * - *

If a null or empty String {@code value} is passed in, the behavior is undefined, and hence - * strongly discouraged. + *

Empty String "" and null are valid attribute {@code value}, but not valid keys. * *

Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and * pre-allocate your keys, if possible. diff --git a/api/all/src/test/java/io/opentelemetry/api/common/AttributesTest.java b/api/all/src/test/java/io/opentelemetry/api/common/AttributesTest.java index 8aae9ffcf60..2e97fb1485c 100644 --- a/api/all/src/test/java/io/opentelemetry/api/common/AttributesTest.java +++ b/api/all/src/test/java/io/opentelemetry/api/common/AttributesTest.java @@ -578,4 +578,11 @@ public AttributesBuilder putAll(Attributes attributes) { assertThatCode(() -> myAttributesBuilder.remove(stringKey("foo"))).doesNotThrowAnyException(); assertThatCode(() -> myAttributesBuilder.removeIf(unused -> false)).doesNotThrowAnyException(); } + + @Test + void emptyValueIsValid() { + AttributeKey key = stringKey("anything"); + Attributes attributes = Attributes.of(key, ""); + assertThat(attributes.get(key)).isEqualTo(""); + } }