diff --git a/api/all/src/main/java/io/opentelemetry/api/common/ArrayBackedAttributesBuilder.java b/api/all/src/main/java/io/opentelemetry/api/common/ArrayBackedAttributesBuilder.java index 30df86d770..af575a61e3 100644 --- a/api/all/src/main/java/io/opentelemetry/api/common/ArrayBackedAttributesBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/ArrayBackedAttributesBuilder.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; +import javax.annotation.Nullable; class ArrayBackedAttributesBuilder implements AttributesBuilder { private final List data; @@ -37,7 +38,7 @@ class ArrayBackedAttributesBuilder implements AttributesBuilder { } @Override - public AttributesBuilder put(AttributeKey key, T value) { + public AttributesBuilder put(AttributeKey key, @Nullable T value) { if (key == null || key.getKey().isEmpty() || value == null) { return this; } diff --git a/api/all/src/main/java/io/opentelemetry/api/common/AttributesBuilder.java b/api/all/src/main/java/io/opentelemetry/api/common/AttributesBuilder.java index a7fe1be0ee..6623d47013 100644 --- a/api/all/src/main/java/io/opentelemetry/api/common/AttributesBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/common/AttributesBuilder.java @@ -18,6 +18,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; +import javax.annotation.Nullable; /** A builder of {@link Attributes} supporting an arbitrary number of key-value pairs. */ public interface AttributesBuilder { @@ -35,18 +36,22 @@ public interface AttributesBuilder { // version. AttributesBuilder put(AttributeKey key, int value); - /** Puts a {@link AttributeKey} with associated value into this. */ - AttributesBuilder put(AttributeKey key, T value); + /** + * Puts an {@link AttributeKey} with an associated value into this if the value is non-null. + * Providing a null value does not remove or unset previously set values. + */ + AttributesBuilder put(AttributeKey key, @Nullable T value); /** - * Puts a String attribute into this. + * Puts a String attribute into this if the value is non-null. Providing a null value does not + * remove or unset previously set values. * *

Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate * your keys, if possible. * * @return this Builder */ - default AttributesBuilder put(String key, String value) { + default AttributesBuilder put(String key, @Nullable String value) { return put(stringKey(key), value); } diff --git a/api/all/src/main/java/io/opentelemetry/api/logs/DefaultLogger.java b/api/all/src/main/java/io/opentelemetry/api/logs/DefaultLogger.java index 56284b43cb..228ba1ec6e 100644 --- a/api/all/src/main/java/io/opentelemetry/api/logs/DefaultLogger.java +++ b/api/all/src/main/java/io/opentelemetry/api/logs/DefaultLogger.java @@ -10,6 +10,7 @@ import io.opentelemetry.api.common.Value; import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; class DefaultLogger implements Logger { @@ -77,7 +78,7 @@ class DefaultLogger implements Logger { } @Override - public LogRecordBuilder setAttribute(AttributeKey key, T value) { + public LogRecordBuilder setAttribute(AttributeKey key, @Nullable T value) { return this; } diff --git a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java index 9e071baed1..0cc3dcdf31 100644 --- a/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java +++ b/api/all/src/main/java/io/opentelemetry/api/logs/LogRecordBuilder.java @@ -16,6 +16,7 @@ import io.opentelemetry.api.common.Value; import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; /** * Used to construct and emit log records from a {@link Logger}. @@ -107,16 +108,20 @@ public interface LogRecordBuilder { * Sets an attribute on the {@code LogRecord}. If the {@code LogRecord} previously contained a * mapping for the key, the old value is replaced by the specified value. * + *

Note: Providing a null value is a no-op and will not remove previously set values. + * * @param key the key for this attribute. * @param value the value for this attribute. * @return this. */ - LogRecordBuilder setAttribute(AttributeKey key, T value); + LogRecordBuilder setAttribute(AttributeKey key, @Nullable T value); /** * Sets a String attribute on the {@code LogRecord}. If the {@code LogRecord} previously contained * a mapping for the key, the old value is replaced by the specified value. * + *

Note: Providing a null value is a no-op and will not remove previously set values. + * *

Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and * pre-allocate your keys, if possible. * @@ -125,7 +130,7 @@ public interface LogRecordBuilder { * @return this. * @since 1.48.0 */ - default LogRecordBuilder setAttribute(String key, String value) { + default LogRecordBuilder setAttribute(String key, @Nullable String value) { return setAttribute(stringKey(key), value); } diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/PropagatedSpan.java b/api/all/src/main/java/io/opentelemetry/api/trace/PropagatedSpan.java index 24c145b05b..8839628004 100644 --- a/api/all/src/main/java/io/opentelemetry/api/trace/PropagatedSpan.java +++ b/api/all/src/main/java/io/opentelemetry/api/trace/PropagatedSpan.java @@ -8,6 +8,7 @@ package io.opentelemetry.api.trace; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; /** @@ -42,7 +43,7 @@ final class PropagatedSpan implements Span { } @Override - public Span setAttribute(String key, String value) { + public Span setAttribute(String key, @Nullable String value) { return this; } @@ -62,7 +63,7 @@ final class PropagatedSpan implements Span { } @Override - public Span setAttribute(AttributeKey key, T value) { + public Span setAttribute(AttributeKey key, @Nullable T value) { return this; } 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 8d50285990..708bb1de07 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 @@ -88,7 +88,9 @@ public interface Span extends ImplicitContextKeyed { * 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. * - *

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

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

Note: Providing a null value is a no-op and will not remove previously set values. * *

Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and * pre-allocate your keys, if possible. @@ -97,7 +99,7 @@ public interface Span extends ImplicitContextKeyed { * @param value the value for this attribute. * @return this. */ - default Span setAttribute(String key, String value) { + default Span setAttribute(String key, @Nullable String value) { return setAttribute(AttributeKey.stringKey(key), value); } @@ -150,13 +152,13 @@ public interface Span extends ImplicitContextKeyed { * 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. * - *

Note: the behavior of null values is undefined, and hence strongly discouraged. + *

Note: Providing a null value is a no-op. * * @param key the key for this attribute. * @param value the value for this attribute. * @return this. */ - Span setAttribute(AttributeKey key, T value); + Span setAttribute(AttributeKey key, @Nullable T value); /** * Sets an attribute to the {@code Span}. If the {@code Span} previously contained a mapping for 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 2e97fb1485..1200dac1b1 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 @@ -26,6 +26,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.NoSuchElementException; import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.Nullable; import org.junit.jupiter.api.Test; /** Unit tests for {@link Attributes}s. */ @@ -565,7 +566,7 @@ class AttributesTest { } @Override - public AttributesBuilder put(AttributeKey key, T value) { + public AttributesBuilder put(AttributeKey key, @Nullable T value) { return null; } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java index f0f167bac0..239f42d7aa 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java @@ -13,6 +13,7 @@ import io.opentelemetry.api.logs.Severity; import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; class ExtendedDefaultLogger implements ExtendedLogger { @@ -51,7 +52,7 @@ class ExtendedDefaultLogger implements ExtendedLogger { } @Override - public ExtendedLogRecordBuilder setAttribute(AttributeKey key, T value) { + public ExtendedLogRecordBuilder setAttribute(AttributeKey key, @Nullable T value) { return this; } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java index 9ca95f0b0c..6395768f36 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedLogRecordBuilder.java @@ -15,6 +15,7 @@ import io.opentelemetry.api.logs.Severity; import io.opentelemetry.context.Context; import java.time.Instant; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; /** Extended {@link LogRecordBuilder} with experimental APIs. */ public interface ExtendedLogRecordBuilder extends LogRecordBuilder { @@ -110,7 +111,7 @@ public interface ExtendedLogRecordBuilder extends LogRecordBuilder { * attribute APIs. */ @Override - ExtendedLogRecordBuilder setAttribute(AttributeKey key, T value); + ExtendedLogRecordBuilder setAttribute(AttributeKey key, @Nullable T value); /** * Set an attribute. diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/DelegatingSpan.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/DelegatingSpan.java index f32e8b204d..ad1f624795 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/DelegatingSpan.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/DelegatingSpan.java @@ -15,6 +15,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; import java.time.Instant; import java.util.concurrent.TimeUnit; +import javax.annotation.Nullable; /** * Delegates all {@link Span} methods to some underlying Span via {@link @@ -52,12 +53,12 @@ interface DelegatingSpan extends Span { } @Override - default Span setAttribute(AttributeKey key, T value) { + default Span setAttribute(AttributeKey key, @Nullable T value) { return getDelegate().setAttribute(key, value); } @Override - default Span setAttribute(String key, String value) { + default Span setAttribute(String key, @Nullable String value) { return getDelegate().setAttribute(key, value); } diff --git a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryNoRecordEventsSpanImpl.java b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryNoRecordEventsSpanImpl.java index 1e18beb8ce..a1e48f5eb4 100644 --- a/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryNoRecordEventsSpanImpl.java +++ b/opencensus-shim/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryNoRecordEventsSpanImpl.java @@ -37,7 +37,7 @@ import io.opentelemetry.api.trace.StatusCode; import java.util.EnumSet; import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; +import javax.annotation.Nullable; final class OpenTelemetryNoRecordEventsSpanImpl extends Span implements io.opentelemetry.api.trace.Span { @@ -110,7 +110,7 @@ final class OpenTelemetryNoRecordEventsSpanImpl extends Span } @Override - public io.opentelemetry.api.trace.Span setAttribute(String key, @Nonnull String value) { + public io.opentelemetry.api.trace.Span setAttribute(String key, @Nullable String value) { return this; } @@ -130,7 +130,7 @@ final class OpenTelemetryNoRecordEventsSpanImpl extends Span } @Override - public io.opentelemetry.api.trace.Span setAttribute(AttributeKey key, @Nonnull T value) { + public io.opentelemetry.api.trace.Span setAttribute(AttributeKey key, @Nullable T value) { return this; } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java index 2e4b4b5e40..b38f4579e9 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java @@ -117,7 +117,7 @@ final class ExtendedSdkLogRecordBuilder extends SdkLogRecordBuilder } @Override - public ExtendedSdkLogRecordBuilder setAttribute(AttributeKey key, T value) { + public ExtendedSdkLogRecordBuilder setAttribute(AttributeKey key, @Nullable T value) { if (key == null || key.getKey().isEmpty() || value == null) { return this; } diff --git a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java index 1a108b366c..038338d657 100644 --- a/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java +++ b/sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java @@ -95,7 +95,7 @@ class SdkLogRecordBuilder implements LogRecordBuilder { } @Override - public SdkLogRecordBuilder setAttribute(AttributeKey key, T value) { + public SdkLogRecordBuilder setAttribute(AttributeKey key, @Nullable T value) { if (key == null || key.getKey().isEmpty() || value == null) { return this; } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index 30ee4bbdeb..352ccf3135 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -314,7 +314,7 @@ final class SdkSpan implements ReadWriteSpan { } @Override - public ReadWriteSpan setAttribute(AttributeKey key, T value) { + public ReadWriteSpan setAttribute(AttributeKey key, @Nullable T value) { if (key == null || key.getKey().isEmpty() || value == null) { return this; }