Move builders to top level. (#1958)

* Move builders (and TraceStateEntry) to top level.

* Revert Entry

* Fix and more revert

* Drift
This commit is contained in:
Anuraag Agrawal 2020-11-10 14:50:37 +09:00 committed by GitHub
parent 813025a3fb
commit b5efbcf187
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 897 additions and 792 deletions

View File

@ -117,7 +117,7 @@ final class DefaultOpenTelemetry implements OpenTelemetry {
.setPropagators(propagators);
}
static class Builder implements OpenTelemetry.Builder<Builder> {
static class Builder implements OpenTelemetryBuilder<Builder> {
private ContextPropagators propagators = DefaultContextPropagators.builder().build();
private TracerProvider tracerProvider;

View File

@ -203,25 +203,9 @@ public interface OpenTelemetry {
/** Returns the {@link ContextPropagators} for this {@link OpenTelemetry}. */
ContextPropagators getPropagators();
/** Returns a new {@link Builder} with the configuration of this {@link OpenTelemetry}. */
Builder<?> toBuilder();
/**
* A builder of an implementation of the OpenTelemetry API. Generally used to reconfigure SDK
* implementations.
* Returns a new {@link OpenTelemetryBuilder} with the configuration of this {@link
* OpenTelemetry}.
*/
interface Builder<T extends Builder<T>> {
/** Sets the {@link TracerProvider} to use. */
T setTracerProvider(TracerProvider tracerProvider);
/** Sets the {@link MeterProvider} to use. */
T setMeterProvider(MeterProvider meterProvider);
/** Sets the {@link ContextPropagators} to use. */
T setPropagators(ContextPropagators propagators);
/** Returns a new {@link OpenTelemetry} based on the configuration in this {@link Builder}. */
OpenTelemetry build();
}
OpenTelemetryBuilder<?> toBuilder();
}

View File

@ -0,0 +1,32 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.context.propagation.ContextPropagators;
/**
* A builder of an implementation of the OpenTelemetry API. Generally used to reconfigure SDK
* implementations.
*/
public interface OpenTelemetryBuilder<T extends OpenTelemetryBuilder<T>> {
/** Sets the {@link TracerProvider} to use. */
T setTracerProvider(TracerProvider tracerProvider);
/** Sets the {@link MeterProvider} to use. */
T setMeterProvider(MeterProvider meterProvider);
/** Sets the {@link ContextPropagators} to use. */
T setPropagators(ContextPropagators propagators);
/**
* Returns a new {@link OpenTelemetry} based on the configuration in this {@link
* OpenTelemetryBuilder}.
*/
OpenTelemetry build();
}

View File

@ -22,11 +22,11 @@ public interface Baggage extends ImplicitContextKeyed {
/** Baggage with no entries. */
static Baggage empty() {
return ImmutableBaggage.EMPTY;
return ImmutableBaggage.empty();
}
/** Creates a new {@link Builder} for creating Baggage. */
static Builder builder() {
/** Creates a new {@link BaggageBuilder} for creating Baggage. */
static BaggageBuilder builder() {
return ImmutableBaggage.builder();
}
@ -86,72 +86,5 @@ public interface Baggage extends ImplicitContextKeyed {
* Create a Builder pre-initialized with the contents of this Baggage. The returned Builder will
* be set to not use an implicit parent, so any parent assignment must be done manually.
*/
Builder toBuilder();
/** Builder for the {@link Baggage} class. */
interface Builder {
/**
* Sets the parent {@link Baggage} to use from the specified {@code Context}. If no parent
* {@link Baggage} is provided, the value of {@link Baggage#current()} at {@link #build()} time
* will be used as parent, unless {@link #setNoParent()} was called.
*
* <p>If no parent {@link Baggage} is available in the specified {@code Context}, the resulting
* {@link Baggage} will become a root instance, as if {@link #setNoParent()} had been called.
*
* <p>This <b>must</b> be used to create a {@link Baggage} when manual Context propagation is
* used.
*
* <p>If called multiple times, only the last specified value will be used.
*
* @param context the {@code Context}.
* @return this.
* @throws NullPointerException if {@code context} is {@code null}.
* @see #setNoParent()
*/
Builder setParent(Context context);
/**
* Sets the option to become a root {@link Baggage} with no parent. If <b>not</b> called, the
* value provided using {@link #setParent(Context)} or otherwise {@link Baggage#current()} at
* {@link #build()} time will be used as parent.
*
* @return this.
*/
Builder setNoParent();
/**
* Adds the key/value pair and metadata regardless of whether the key is present.
*
* @param key the {@code String} key which will be set.
* @param value the {@code String} value to set for the given key.
* @param entryMetadata the {@code EntryMetadata} associated with this {@link Entry}.
* @return this
*/
Builder put(String key, String value, EntryMetadata entryMetadata);
/**
* Adds the key/value pair with empty metadata regardless of whether the key is present.
*
* @param key the {@code String} key which will be set.
* @param value the {@code String} value to set for the given key.
* @return this
*/
Builder put(String key, String value);
/**
* Removes the key if it exists.
*
* @param key the {@code String} key which will be removed.
* @return this
*/
Builder remove(String key);
/**
* Creates a {@code Baggage} from this builder.
*
* @return a {@code Baggage} with the same entries as this builder.
*/
Baggage build();
}
BaggageBuilder toBuilder();
}

View File

@ -0,0 +1,79 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.baggage;
import io.opentelemetry.context.Context;
/**
* A builder of {@link Baggage}.
*
* @see Baggage#builder()
*/
public interface BaggageBuilder {
/**
* Sets the parent {@link Baggage} to use from the specified {@code Context}. If no parent {@link
* Baggage} is provided, the value of {@link Baggage#current()} at {@link #build()} time will be
* used as parent, unless {@link #setNoParent()} was called.
*
* <p>If no parent {@link Baggage} is available in the specified {@code Context}, the resulting
* {@link Baggage} will become a root instance, as if {@link #setNoParent()} had been called.
*
* <p>This <b>must</b> be used to create a {@link Baggage} when manual Context propagation is
* used.
*
* <p>If called multiple times, only the last specified value will be used.
*
* @param context the {@code Context}.
* @return this.
* @throws NullPointerException if {@code context} is {@code null}.
* @see #setNoParent()
*/
BaggageBuilder setParent(Context context);
/**
* Sets the option to become a root {@link Baggage} with no parent. If <b>not</b> called, the
* value provided using {@link #setParent(Context)} or otherwise {@link Baggage#current()} at
* {@link #build()} time will be used as parent.
*
* @return this.
*/
BaggageBuilder setNoParent();
/**
* Adds the key/value pair and metadata regardless of whether the key is present.
*
* @param key the {@code String} key which will be set.
* @param value the {@code String} value to set for the given key.
* @param entryMetadata the {@code EntryMetadata} associated with this {@link Entry}.
* @return this
*/
BaggageBuilder put(String key, String value, EntryMetadata entryMetadata);
/**
* Adds the key/value pair with empty metadata regardless of whether the key is present.
*
* @param key the {@code String} key which will be set.
* @param value the {@code String} value to set for the given key.
* @return this
*/
BaggageBuilder put(String key, String value);
/**
* Removes the key if it exists.
*
* @param key the {@code String} key which will be removed.
* @return this
*/
BaggageBuilder remove(String key);
/**
* Creates a {@code Baggage} from this builder.
*
* @return a {@code Baggage} with the same entries as this builder.
*/
Baggage build();
}

View File

@ -18,7 +18,15 @@ import javax.annotation.concurrent.Immutable;
@Immutable
class ImmutableBaggage extends ImmutableKeyValuePairs<String, Entry> implements Baggage {
static final Baggage EMPTY = new ImmutableBaggage.Builder().setNoParent().build();
private static final Baggage EMPTY = new ImmutableBaggage.Builder().build();
static Baggage empty() {
return EMPTY;
}
static BaggageBuilder builder() {
return new Builder();
}
@AutoValue
@Immutable
@ -29,15 +37,11 @@ class ImmutableBaggage extends ImmutableKeyValuePairs<String, Entry> implements
protected abstract List<Object> data();
@Override
public Baggage.Builder toBuilder() {
public BaggageBuilder toBuilder() {
return new ImmutableBaggage.Builder(new ArrayList<>(data()));
}
}
public static Baggage.Builder builder() {
return new Builder();
}
@Override
public void forEach(BaggageConsumer consumer) {
for (int i = 0; i < data().size(); i += 2) {
@ -54,7 +58,7 @@ class ImmutableBaggage extends ImmutableKeyValuePairs<String, Entry> implements
}
@Override
public Baggage.Builder toBuilder() {
public BaggageBuilder toBuilder() {
Builder builder = new Builder(data());
builder.noImplicitParent = true;
return builder;
@ -67,7 +71,7 @@ class ImmutableBaggage extends ImmutableKeyValuePairs<String, Entry> implements
// TODO: Migrate to AutoValue.Builder
// @AutoValue.Builder
static class Builder implements Baggage.Builder {
static class Builder implements BaggageBuilder {
@Nullable private Baggage parent;
private boolean noImplicitParent;
@ -82,21 +86,21 @@ class ImmutableBaggage extends ImmutableKeyValuePairs<String, Entry> implements
}
@Override
public Baggage.Builder setParent(Context context) {
public BaggageBuilder setParent(Context context) {
requireNonNull(context, "context");
parent = Baggage.fromContext(context);
return this;
}
@Override
public Baggage.Builder setNoParent() {
public BaggageBuilder setNoParent() {
this.parent = null;
noImplicitParent = true;
return this;
}
@Override
public Baggage.Builder put(String key, String value, EntryMetadata entryMetadata) {
public BaggageBuilder put(String key, String value, EntryMetadata entryMetadata) {
requireNonNull(key, "key");
requireNonNull(value, "value");
requireNonNull(entryMetadata, "entryMetadata");
@ -107,14 +111,14 @@ class ImmutableBaggage extends ImmutableKeyValuePairs<String, Entry> implements
}
@Override
public Baggage.Builder put(String key, String value) {
public BaggageBuilder put(String key, String value) {
requireNonNull(key, "key");
requireNonNull(value, "value");
return put(key, value, EntryMetadata.EMPTY);
}
@Override
public Baggage.Builder remove(String key) {
public BaggageBuilder remove(String key) {
requireNonNull(key, "key");
data.add(key);
data.add(null);

View File

@ -8,6 +8,7 @@ package io.opentelemetry.api.baggage.propagation;
import static java.util.Collections.singletonList;
import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageBuilder;
import io.opentelemetry.api.baggage.EntryMetadata;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapPropagator;
@ -67,7 +68,7 @@ public final class W3CBaggagePropagator implements TextMapPropagator {
return context.with(Baggage.empty());
}
Baggage.Builder baggageBuilder = Baggage.builder();
BaggageBuilder baggageBuilder = Baggage.builder();
try {
extractEntries(baggageHeader, baggageBuilder);
} catch (Exception e) {
@ -77,7 +78,7 @@ public final class W3CBaggagePropagator implements TextMapPropagator {
}
@SuppressWarnings("StringSplitter")
private static void extractEntries(String baggageHeader, Baggage.Builder baggageBuilder) {
private static void extractEntries(String baggageHeader, BaggageBuilder baggageBuilder) {
// todo: optimize this implementation; it can probably done with a single pass through the
// string.
String[] entries = baggageHeader.split(",");

View File

@ -5,19 +5,9 @@
package io.opentelemetry.api.common;
import static io.opentelemetry.api.common.AttributeKey.booleanArrayKey;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
import static io.opentelemetry.api.common.AttributeKey.doubleArrayKey;
import static io.opentelemetry.api.common.AttributeKey.doubleKey;
import static io.opentelemetry.api.common.AttributeKey.longArrayKey;
import static io.opentelemetry.api.common.AttributeKey.longKey;
import static io.opentelemetry.api.common.AttributeKey.stringArrayKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import com.google.auto.value.AutoValue;
import io.opentelemetry.api.internal.ImmutableKeyValuePairs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.concurrent.Immutable;
@ -46,8 +36,8 @@ public abstract class Attributes extends ImmutableKeyValuePairs<AttributeKey, Ob
protected abstract List<Object> data();
@Override
public Builder toBuilder() {
return new Builder(new ArrayList<>(data()));
public AttributesBuilder toBuilder() {
return new AttributesBuilder(new ArrayList<>(data()));
}
}
@ -164,7 +154,25 @@ public abstract class Attributes extends ImmutableKeyValuePairs<AttributeKey, Ob
key6, value6);
}
private static Attributes sortAndFilterToAttributes(Object... data) {
/** Returns a new {@link AttributesBuilder} instance for creating arbitrary {@link Attributes}. */
public static AttributesBuilder builder() {
return new AttributesBuilder();
}
/** Returns a new {@link AttributesBuilder} instance from ReadableAttributes. */
public static AttributesBuilder builder(ReadableAttributes attributes) {
final AttributesBuilder builder = new AttributesBuilder();
attributes.forEach(builder::put);
return builder;
}
/**
* Returns a new {@link AttributesBuilder} instance populated with the data of this {@link
* Attributes}.
*/
public abstract AttributesBuilder toBuilder();
static Attributes sortAndFilterToAttributes(Object... data) {
// null out any empty keys or keys with null values
// so they will then be removed by the sortAndFilter method.
for (int i = 0; i < data.length; i += 2) {
@ -176,161 +184,4 @@ public abstract class Attributes extends ImmutableKeyValuePairs<AttributeKey, Ob
return new AutoValue_Attributes_ArrayBackedAttributes(
sortAndFilter(data, /* filterNullValues= */ true));
}
/** Returns a new {@link Builder} instance for creating arbitrary {@link Attributes}. */
public static Builder builder() {
return new Builder();
}
/** Returns a new {@link Builder} instance from ReadableAttributes. */
public static Builder builder(ReadableAttributes attributes) {
final Builder builder = new Builder();
attributes.forEach(builder::put);
return builder;
}
/** Returns a new {@link Builder} instance populated with the data of this {@link Attributes}. */
public abstract Builder toBuilder();
/**
* Enables the creation of an {@link Attributes} instance with an arbitrary number of key-value
* pairs.
*/
public static class Builder {
private final List<Object> data;
private Builder() {
data = new ArrayList<>();
}
private Builder(List<Object> data) {
this.data = data;
}
/** Create the {@link Attributes} from this. */
public Attributes build() {
return sortAndFilterToAttributes(data.toArray());
}
/** Puts a {@link AttributeKey} with associated value into this. */
public <T> Builder put(AttributeKey<Long> key, int value) {
return put(key, (long) value);
}
/** Puts a {@link AttributeKey} with associated value into this. */
public <T> Builder put(AttributeKey<T> key, T value) {
if (key == null || key.getKey() == null || key.getKey().length() == 0 || value == null) {
return this;
}
data.add(key);
data.add(value);
return this;
}
/**
* Puts a String attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
public Builder put(String key, String value) {
return put(stringKey(key), value);
}
/**
* Puts a long attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
public Builder put(String key, long value) {
return put(longKey(key), value);
}
/**
* Puts a double attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
public Builder put(String key, double value) {
return put(doubleKey(key), value);
}
/**
* Puts a boolean attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
public Builder put(String key, boolean value) {
return put(booleanKey(key), value);
}
/**
* Puts a String array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
public Builder put(String key, String... value) {
return put(stringArrayKey(key), value == null ? null : Arrays.asList(value));
}
/**
* Puts a Long array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
public Builder put(String key, Long... value) {
return put(longArrayKey(key), value == null ? null : Arrays.asList(value));
}
/**
* Puts a Double array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
public Builder put(String key, Double... value) {
return put(doubleArrayKey(key), value == null ? null : Arrays.asList(value));
}
/**
* Puts a Boolean array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @return this Builder
*/
public Builder put(String key, Boolean... value) {
return put(booleanArrayKey(key), value == null ? null : Arrays.asList(value));
}
/**
* Puts all the provided attributes into this Builder.
*
* @return this Builder
*/
public Builder putAll(Attributes attributes) {
data.addAll(attributes.data());
return this;
}
}
}

View File

@ -0,0 +1,158 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import static io.opentelemetry.api.common.AttributeKey.booleanArrayKey;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
import static io.opentelemetry.api.common.AttributeKey.doubleArrayKey;
import static io.opentelemetry.api.common.AttributeKey.doubleKey;
import static io.opentelemetry.api.common.AttributeKey.longArrayKey;
import static io.opentelemetry.api.common.AttributeKey.longKey;
import static io.opentelemetry.api.common.AttributeKey.stringArrayKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** A builder of {@link Attributes} supporting an arbitrary number of key-value pairs. */
public class AttributesBuilder {
private final List<Object> data;
AttributesBuilder() {
data = new ArrayList<>();
}
AttributesBuilder(List<Object> data) {
this.data = data;
}
/** Create the {@link Attributes} from this. */
public Attributes build() {
return Attributes.sortAndFilterToAttributes(data.toArray());
}
/** Puts a {@link AttributeKey} with associated value into this. */
public <T> AttributesBuilder put(AttributeKey<Long> key, int value) {
return put(key, (long) value);
}
/** Puts a {@link AttributeKey} with associated value into this. */
public <T> AttributesBuilder put(AttributeKey<T> key, T value) {
if (key == null || key.getKey() == null || key.getKey().length() == 0 || value == null) {
return this;
}
data.add(key);
data.add(value);
return this;
}
/**
* Puts a String attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public AttributesBuilder put(String key, String value) {
return put(stringKey(key), value);
}
/**
* Puts a long attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public AttributesBuilder put(String key, long value) {
return put(longKey(key), value);
}
/**
* Puts a double attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public AttributesBuilder put(String key, double value) {
return put(doubleKey(key), value);
}
/**
* Puts a boolean attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public AttributesBuilder put(String key, boolean value) {
return put(booleanKey(key), value);
}
/**
* Puts a String array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public AttributesBuilder put(String key, String... value) {
return put(stringArrayKey(key), value == null ? null : Arrays.asList(value));
}
/**
* Puts a Long array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public AttributesBuilder put(String key, Long... value) {
return put(longArrayKey(key), value == null ? null : Arrays.asList(value));
}
/**
* Puts a Double array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public AttributesBuilder put(String key, Double... value) {
return put(doubleArrayKey(key), value == null ? null : Arrays.asList(value));
}
/**
* Puts a Boolean array attribute into this.
*
* <p>Note: It is strongly recommended to use {@link #put(AttributeKey, Object)}, and pre-allocate
* your keys, if possible.
*
* @return this Builder
*/
public AttributesBuilder put(String key, Boolean... value) {
return put(booleanArrayKey(key), value == null ? null : Arrays.asList(value));
}
/**
* Puts all the provided attributes into this Builder.
*
* @return this Builder
*/
public AttributesBuilder putAll(Attributes attributes) {
attributes.forEach(this::put);
return this;
}
}

View File

@ -7,7 +7,6 @@ package io.opentelemetry.api.common;
import com.google.auto.value.AutoValue;
import io.opentelemetry.api.internal.ImmutableKeyValuePairs;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import javax.annotation.concurrent.Immutable;
@ -107,43 +106,18 @@ public abstract class Labels extends ImmutableKeyValuePairs<String, String> {
return sortAndFilterToLabels((Object[]) keyValueLabelPairs);
}
private static Labels sortAndFilterToLabels(Object... data) {
static Labels sortAndFilterToLabels(Object... data) {
return new AutoValue_Labels_ArrayBackedLabels(
sortAndFilter(data, /* filterNullValues= */ false));
}
/** Create a {@link Builder} pre-populated with the contents of this Labels instance. */
public Builder toBuilder() {
Builder builder = new Builder();
builder.data.addAll(data());
return builder;
/** Create a {@link LabelsBuilder} pre-populated with the contents of this Labels instance. */
public LabelsBuilder toBuilder() {
return new LabelsBuilder(data());
}
/** Creates a new {@link Builder} instance for creating arbitrary {@link Labels}. */
public static Builder builder() {
return new Builder();
}
/**
* Enables the creation of an {@link Labels} instance with an arbitrary number of key-value pairs.
*/
public static class Builder {
private final List<Object> data = new ArrayList<>();
/** Create the {@link Labels} from this. */
public Labels build() {
return sortAndFilterToLabels(data.toArray());
}
/**
* Puts a single label into this Builder.
*
* @return this Builder
*/
public Builder put(String key, String value) {
data.add(key);
data.add(value);
return this;
}
/** Creates a new {@link LabelsBuilder} instance for creating arbitrary {@link Labels}. */
public static LabelsBuilder builder() {
return new LabelsBuilder();
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.common;
import java.util.ArrayList;
import java.util.List;
/** A builder of {@link Labels} supporting an arbitrary number of key-value pairs. */
public class LabelsBuilder {
private final List<Object> data;
LabelsBuilder() {
data = new ArrayList<>();
}
LabelsBuilder(List<Object> data) {
this.data = new ArrayList<>(data);
}
/** Create the {@link Labels} from this. */
public Labels build() {
return Labels.sortAndFilterToLabels(data.toArray());
}
/**
* Puts a single label into this Builder.
*
* @return this Builder
*/
public LabelsBuilder put(String key, String value) {
data.add(key);
data.add(value);
return this;
}
}

View File

@ -25,14 +25,14 @@ final class DefaultTracer implements Tracer {
}
@Override
public Span.Builder spanBuilder(String spanName) {
public SpanBuilder spanBuilder(String spanName) {
return NoopSpanBuilder.create(spanName);
}
private DefaultTracer() {}
// Noop implementation of Span.Builder.
private static final class NoopSpanBuilder implements Span.Builder {
private static final class NoopSpanBuilder implements SpanBuilder {
static NoopSpanBuilder create(String spanName) {
return new NoopSpanBuilder(spanName);
}

View File

@ -21,7 +21,7 @@ import javax.annotation.concurrent.ThreadSafe;
/**
* An interface that represents a span. It has an associated {@link SpanContext}.
*
* <p>Spans are created by the {@link Builder#startSpan} method.
* <p>Spans are created by the {@link SpanBuilder#startSpan} method.
*
* <p>{@code Span} <b>must</b> be ended by calling {@link #end()}.
*/
@ -411,299 +411,4 @@ public interface Span extends ImplicitContextKeyed {
default Context storeInContext(Context context) {
return context.with(SpanContextKey.KEY, this);
}
/**
* {@link Builder} is used to construct {@link Span} instances which define arbitrary scopes of
* code that are sampled for distributed tracing as a single atomic unit.
*
* <p>This is a simple example where all the work is being done within a single scope and a single
* thread and the Context is automatically propagated:
*
* <pre>{@code
* class MyClass {
* private static final Tracer tracer = OpenTelemetry.getTracer();
* void doWork {
* // Create a Span as a child of the current Span.
* Span span = tracer.spanBuilder("MyChildSpan").startSpan();
* try (Scope ss = TracingContextUtils.currentContextWith(span)) {
* TracingContextUtils.getCurrentSpan().addEvent("my event");
* doSomeWork(); // Here the new span is in the current Context, so it can be used
* // implicitly anywhere down the stack.
* } finally {
* span.end();
* }
* }
* }
* }</pre>
*
* <p>There might be cases where you do not perform all the work inside one static scope and the
* Context is automatically propagated:
*
* <pre>{@code
* class MyRpcServerInterceptorListener implements RpcServerInterceptor.Listener {
* private static final Tracer tracer = OpenTelemetry.getTracer();
* private Span mySpan;
*
* public MyRpcInterceptor() {}
*
* public void onRequest(String rpcName, Metadata metadata) {
* // Create a Span as a child of the remote Span.
* mySpan = tracer.spanBuilder(rpcName)
* .setParent(getTraceContextFromMetadata(metadata)).startSpan();
* }
*
* public void onExecuteHandler(ServerCallHandler serverCallHandler) {
* try (Scope ws = TracingContextUtils.currentContextWith(mySpan)) {
* TracingContextUtils.getCurrentSpan().addEvent("Start rpc execution.");
* serverCallHandler.run(); // Here the new span is in the current Context, so it can be
* // used implicitly anywhere down the stack.
* }
* }
*
* // Called when the RPC is canceled and guaranteed onComplete will not be called.
* public void onCancel() {
* // IMPORTANT: DO NOT forget to ended the Span here as the work is done.
* mySpan.setStatus(Status.CANCELLED);
* mySpan.end();
* }
*
* // Called when the RPC is done and guaranteed onCancel will not be called.
* public void onComplete(RpcStatus rpcStatus) {
* // IMPORTANT: DO NOT forget to ended the Span here as the work is done.
* mySpan.setStatus(rpcStatusToCanonicalTraceStatus(status);
* mySpan.end();
* }
* }
* }</pre>
*
* <p>This is a simple example where all the work is being done within a single scope and the
* Context is manually propagated:
*
* <pre>{@code
* class MyClass {
* private static final Tracer tracer = OpenTelemetry.getTracer();
* void DoWork(Span parent) {
* Span childSpan = tracer.spanBuilder("MyChildSpan")
* .setParent(parent).startSpan();
* childSpan.addEvent("my event");
* try {
* doSomeWork(childSpan); // Manually propagate the new span down the stack.
* } finally {
* // To make sure we end the span even in case of an exception.
* childSpan.end(); // Manually end the span.
* }
* }
* }
* }</pre>
*
* <p>If your Java version is less than Java SE 7, see {@link Builder#startSpan} for usage
* examples.
*/
interface Builder {
/**
* Sets the parent to use from the specified {@code Context}. If not set, the value of {@code
* Span.current()} at {@link #startSpan()} time will be used as parent.
*
* <p>If no {@link Span} is available in the specified {@code Context}, the resulting {@code
* Span} will become a root instance, as if {@link #setNoParent()} had been called.
*
* <p>If called multiple times, only the last specified value will be used. Observe that the
* state defined by a previous call to {@link #setNoParent()} will be discarded.
*
* @param context the {@code Context}.
* @return this.
* @throws NullPointerException if {@code context} is {@code null}.
*/
Builder setParent(Context context);
/**
* Sets the option to become a root {@code Span} for a new trace. If not set, the value of
* {@code Span.current()} at {@link #startSpan()} time will be used as parent.
*
* <p>Observe that any previously set parent will be discarded.
*
* @return this.
*/
Builder setNoParent();
/**
* Adds a link to the newly created {@code Span}.
*
* <p>Links are used to link {@link Span}s in different traces. Used (for example) in batching
* operations, where a single batch handler processes multiple requests from different traces or
* the same trace.
*
* @param spanContext the context of the linked {@code Span}.
* @return this.
* @throws NullPointerException if {@code spanContext} is {@code null}.
*/
Builder addLink(SpanContext spanContext);
/**
* Adds a link to the newly created {@code Span}.
*
* <p>Links are used to link {@link Span}s in different traces. Used (for example) in batching
* operations, where a single batch handler processes multiple requests from different traces or
* the same trace.
*
* @param spanContext the context of the linked {@code Span}.
* @param attributes the attributes of the {@code Link}.
* @return this.
* @throws NullPointerException if {@code spanContext} is {@code null}.
* @throws NullPointerException if {@code attributes} is {@code null}.
*/
Builder addLink(SpanContext spanContext, Attributes attributes);
/**
* Sets an attribute to the newly created {@code Span}. If {@code Span.Builder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>If a null or empty String {@code value} is passed in, the behavior is undefined, and hence
* strongly discouraged.
*
* <p>Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
*/
Builder setAttribute(String key, @Nonnull String value);
/**
* Sets an attribute to the newly created {@code Span}. If {@code Span.Builder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
*/
Builder setAttribute(String key, long value);
/**
* Sets an attribute to the newly created {@code Span}. If {@code Span.Builder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
*/
Builder setAttribute(String key, double value);
/**
* Sets an attribute to the newly created {@code Span}. If {@code Span.Builder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
*/
Builder setAttribute(String key, boolean value);
/**
* Sets an attribute to the newly created {@code Span}. If {@code Span.Builder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>Note: the behavior of null values is undefined, and hence strongly discouraged.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
* @throws NullPointerException if {@code value} is {@code null}.
*/
<T> Builder setAttribute(AttributeKey<T> key, @Nonnull T value);
/**
* Sets the {@link Span.Kind} for the newly created {@code Span}. If not called, the
* implementation will provide a default value {@link Span.Kind#INTERNAL}.
*
* @param spanKind the kind of the newly created {@code Span}.
* @return this.
*/
Builder setSpanKind(Span.Kind spanKind);
/**
* Sets an explicit start timestamp for the newly created {@code Span}.
*
* <p>Use this method to specify an explicit start timestamp. If not called, the implementation
* will use the timestamp value at {@link #startSpan()} time, which should be the default case.
*
* <p>Important this is NOT equivalent with System.nanoTime().
*
* @param startTimestamp the explicit start timestamp from the epoch of the newly created {@code
* Span}.
* @param unit the unit of the timestamp.
* @return this.
*/
Builder setStartTimestamp(long startTimestamp, TimeUnit unit);
/**
* Sets an explicit start timestamp for the newly created {@code Span}.
*
* <p>Use this method to specify an explicit start timestamp. If not called, the implementation
* will use the timestamp value at {@link #startSpan()} time, which should be the default case.
*
* <p>Important this is NOT equivalent with System.nanoTime().
*
* @param startTimestamp the explicit start timestamp from the epoch of the newly created {@code
* Span}.
* @return this.
*/
default Builder setStartTimestamp(Instant startTimestamp) {
if (startTimestamp == null) {
return this;
}
return setStartTimestamp(
SECONDS.toNanos(startTimestamp.getEpochSecond()) + startTimestamp.getNano(), NANOSECONDS);
}
/**
* Starts a new {@link Span}.
*
* <p>Users <b>must</b> manually call {@link Span#end()} to end this {@code Span}.
*
* <p>Does not install the newly created {@code Span} to the current Context.
*
* <p>IMPORTANT: This method can be called only once per {@link Builder} instance and as the
* last method called. After this method is called calling any method is undefined behavior.
*
* <p>Example of usage:
*
* <pre>{@code
* class MyClass {
* private static final Tracer tracer = OpenTelemetry.getTracer();
* void DoWork(Span parent) {
* Span childSpan = tracer.spanBuilder("MyChildSpan")
* .setParent(parent)
* .startSpan();
* childSpan.addEvent("my event");
* try {
* doSomeWork(childSpan); // Manually propagate the new span down the stack.
* } finally {
* // To make sure we end the span even in case of an exception.
* childSpan.end(); // Manually end the span.
* }
* }
* }
* }</pre>
*
* @return the newly created {@code Span}.
*/
Span startSpan();
}
}

View File

@ -0,0 +1,312 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.trace;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.Context;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
/**
* {@link SpanBuilder} is used to construct {@link Span} instances which define arbitrary scopes of
* code that are sampled for distributed tracing as a single atomic unit.
*
* <p>This is a simple example where all the work is being done within a single scope and a single
* thread and the Context is automatically propagated:
*
* <pre>{@code
* class MyClass {
* private static final Tracer tracer = OpenTelemetry.getTracer();
* void doWork {
* // Create a Span as a child of the current Span.
* Span span = tracer.spanBuilder("MyChildSpan").startSpan();
* try (Scope ss = TracingContextUtils.currentContextWith(span)) {
* TracingContextUtils.getCurrentSpan().addEvent("my event");
* doSomeWork(); // Here the new span is in the current Context, so it can be used
* // implicitly anywhere down the stack.
* } finally {
* span.end();
* }
* }
* }
* }</pre>
*
* <p>There might be cases where you do not perform all the work inside one static scope and the
* Context is automatically propagated:
*
* <pre>{@code
* class MyRpcServerInterceptorListener implements RpcServerInterceptor.Listener {
* private static final Tracer tracer = OpenTelemetry.getTracer();
* private Span mySpan;
*
* public MyRpcInterceptor() {}
*
* public void onRequest(String rpcName, Metadata metadata) {
* // Create a Span as a child of the remote Span.
* mySpan = tracer.spanBuilder(rpcName)
* .setParent(getTraceContextFromMetadata(metadata)).startSpan();
* }
*
* public void onExecuteHandler(ServerCallHandler serverCallHandler) {
* try (Scope ws = TracingContextUtils.currentContextWith(mySpan)) {
* TracingContextUtils.getCurrentSpan().addEvent("Start rpc execution.");
* serverCallHandler.run(); // Here the new span is in the current Context, so it can be
* // used implicitly anywhere down the stack.
* }
* }
*
* // Called when the RPC is canceled and guaranteed onComplete will not be called.
* public void onCancel() {
* // IMPORTANT: DO NOT forget to ended the Span here as the work is done.
* mySpan.setStatus(Status.CANCELLED);
* mySpan.end();
* }
*
* // Called when the RPC is done and guaranteed onCancel will not be called.
* public void onComplete(RpcStatus rpcStatus) {
* // IMPORTANT: DO NOT forget to ended the Span here as the work is done.
* mySpan.setStatus(rpcStatusToCanonicalTraceStatus(status);
* mySpan.end();
* }
* }
* }</pre>
*
* <p>This is a simple example where all the work is being done within a single scope and the
* Context is manually propagated:
*
* <pre>{@code
* class MyClass {
* private static final Tracer tracer = OpenTelemetry.getTracer();
* void DoWork(Span parent) {
* Span childSpan = tracer.spanBuilder("MyChildSpan")
* .setParent(parent).startSpan();
* childSpan.addEvent("my event");
* try {
* doSomeWork(childSpan); // Manually propagate the new span down the stack.
* } finally {
* // To make sure we end the span even in case of an exception.
* childSpan.end(); // Manually end the span.
* }
* }
* }
* }</pre>
*
* <p>If your Java version is less than Java SE 7, see {@link SpanBuilder#startSpan} for usage
* examples.
*/
public interface SpanBuilder {
/**
* Sets the parent to use from the specified {@code Context}. If not set, the value of {@code
* Span.current()} at {@link #startSpan()} time will be used as parent.
*
* <p>If no {@link Span} is available in the specified {@code Context}, the resulting {@code Span}
* will become a root instance, as if {@link #setNoParent()} had been called.
*
* <p>If called multiple times, only the last specified value will be used. Observe that the state
* defined by a previous call to {@link #setNoParent()} will be discarded.
*
* @param context the {@code Context}.
* @return this.
* @throws NullPointerException if {@code context} is {@code null}.
*/
SpanBuilder setParent(Context context);
/**
* Sets the option to become a root {@code Span} for a new trace. If not set, the value of {@code
* Span.current()} at {@link #startSpan()} time will be used as parent.
*
* <p>Observe that any previously set parent will be discarded.
*
* @return this.
*/
SpanBuilder setNoParent();
/**
* Adds a link to the newly created {@code Span}.
*
* <p>Links are used to link {@link Span}s in different traces. Used (for example) in batching
* operations, where a single batch handler processes multiple requests from different traces or
* the same trace.
*
* @param spanContext the context of the linked {@code Span}.
* @return this.
* @throws NullPointerException if {@code spanContext} is {@code null}.
*/
SpanBuilder addLink(SpanContext spanContext);
/**
* Adds a link to the newly created {@code Span}.
*
* <p>Links are used to link {@link Span}s in different traces. Used (for example) in batching
* operations, where a single batch handler processes multiple requests from different traces or
* the same trace.
*
* @param spanContext the context of the linked {@code Span}.
* @param attributes the attributes of the {@code Link}.
* @return this.
* @throws NullPointerException if {@code spanContext} is {@code null}.
* @throws NullPointerException if {@code attributes} is {@code null}.
*/
SpanBuilder addLink(SpanContext spanContext, Attributes attributes);
/**
* Sets an attribute to the newly created {@code Span}. If {@code SpanBuilder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>If a null or empty String {@code value} is passed in, the behavior is undefined, and hence
* strongly discouraged.
*
* <p>Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
*/
SpanBuilder setAttribute(String key, @Nonnull String value);
/**
* Sets an attribute to the newly created {@code Span}. If {@code SpanBuilder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
*/
SpanBuilder setAttribute(String key, long value);
/**
* Sets an attribute to the newly created {@code Span}. If {@code SpanBuilder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
*/
SpanBuilder setAttribute(String key, double value);
/**
* Sets an attribute to the newly created {@code Span}. If {@code SpanBuilder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>Note: It is strongly recommended to use {@link #setAttribute(AttributeKey, Object)}, and
* pre-allocate your keys, if possible.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
*/
SpanBuilder setAttribute(String key, boolean value);
/**
* Sets an attribute to the newly created {@code Span}. If {@code SpanBuilder} previously
* contained a mapping for the key, the old value is replaced by the specified value.
*
* <p>Note: the behavior of null values is undefined, and hence strongly discouraged.
*
* @param key the key for this attribute.
* @param value the value for this attribute.
* @return this.
* @throws NullPointerException if {@code key} is {@code null}.
* @throws NullPointerException if {@code value} is {@code null}.
*/
<T> SpanBuilder setAttribute(AttributeKey<T> key, @Nonnull T value);
/**
* Sets the {@link Span.Kind} for the newly created {@code Span}. If not called, the
* implementation will provide a default value {@link Span.Kind#INTERNAL}.
*
* @param spanKind the kind of the newly created {@code Span}.
* @return this.
*/
SpanBuilder setSpanKind(Span.Kind spanKind);
/**
* Sets an explicit start timestamp for the newly created {@code Span}.
*
* <p>LIRInstruction.Use this method to specify an explicit start timestamp. If not called, the
* implementation will use the timestamp value at {@link #startSpan()} time, which should be the
* default case.
*
* <p>Important this is NOT equivalent with System.nanoTime().
*
* @param startTimestamp the explicit start timestamp from the epoch of the newly created {@code
* Span}.
* @param unit the unit of the timestamp.
* @return this.
*/
SpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit);
/**
* Sets an explicit start timestamp for the newly created {@code Span}.
*
* <p>Use this method to specify an explicit start timestamp. If not called, the implementation
* will use the timestamp value at {@link #startSpan()} time, which should be the default case.
*
* <p>Important this is NOT equivalent with System.nanoTime().
*
* @param startTimestamp the explicit start timestamp from the epoch of the newly created {@code
* Span}.
* @return this.
*/
default SpanBuilder setStartTimestamp(Instant startTimestamp) {
if (startTimestamp == null) {
return this;
}
return setStartTimestamp(
SECONDS.toNanos(startTimestamp.getEpochSecond()) + startTimestamp.getNano(), NANOSECONDS);
}
/**
* Starts a new {@link Span}.
*
* <p>Users <b>must</b> manually call {@link Span#end()} to end this {@code Span}.
*
* <p>Does not install the newly created {@code Span} to the current Context.
*
* <p>IMPORTANT: This method can be called only once per {@link SpanBuilder} instance and as the
* last method called. After this method is called calling any method is undefined behavior.
*
* <p>Example of usage:
*
* <pre>{@code
* class MyClass {
* private static final Tracer tracer = OpenTelemetry.getTracer();
* void DoWork(Span parent) {
* Span childSpan = tracer.spanBuilder("MyChildSpan")
* .setParent(parent)
* .startSpan();
* childSpan.addEvent("my event");
* try {
* doSomeWork(childSpan); // Manually propagate the new span down the stack.
* } finally {
* // To make sure we end the span even in case of an exception.
* childSpan.end(); // Manually end the span.
* }
* }
* }
* }</pre>
*
* @return the newly created {@code Span}.
*/
Span startSpan();
}

View File

@ -7,7 +7,6 @@ package io.opentelemetry.api.trace;
import com.google.auto.value.AutoValue;
import io.opentelemetry.api.internal.Utils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@ -94,8 +93,8 @@ public abstract class TraceState {
*
* @return a {@code Builder} based on an empty {@code TraceState}.
*/
public static Builder builder() {
return new Builder(Builder.EMPTY);
public static TraceStateBuilder builder() {
return new TraceStateBuilder();
}
/**
@ -103,88 +102,17 @@ public abstract class TraceState {
*
* @return a {@code Builder} based on this {@code TraceState}.
*/
public Builder toBuilder() {
return new Builder(this);
public TraceStateBuilder toBuilder() {
return new TraceStateBuilder(this);
}
/** Builder class for {@link TraceState}. */
public static final class Builder {
private final TraceState parent;
@Nullable private ArrayList<Entry> entries;
// Needs to be in this class to avoid initialization deadlock because super class depends on
// subclass (the auto-value generate class).
private static final TraceState EMPTY = create(Collections.emptyList());
private Builder(TraceState parent) {
Objects.requireNonNull(parent, "parent");
this.parent = parent;
this.entries = null;
}
/**
* Adds or updates the {@code Entry} that has the given {@code key} if it is present. The new
* {@code Entry} will always be added in the front of the list of entries.
*
* @param key the key for the {@code Entry} to be added.
* @param value the value for the {@code Entry} to be added.
* @return this.
*/
public Builder set(String key, String value) {
// Initially create the Entry to validate input.
Entry entry = Entry.create(key, value);
if (entries == null) {
// Copy entries from the parent.
entries = new ArrayList<>(parent.getEntries());
}
for (int i = 0; i < entries.size(); i++) {
if (entries.get(i).getKey().equals(entry.getKey())) {
entries.remove(i);
// Exit now because the entries list cannot contain duplicates.
break;
}
}
// Inserts the element at the front of this list.
entries.add(0, entry);
return this;
}
/**
* Removes the {@code Entry} that has the given {@code key} if it is present.
*
* @param key the key for the {@code Entry} to be removed.
* @return this.
*/
public Builder remove(String key) {
Objects.requireNonNull(key, "key");
if (entries == null) {
// Copy entries from the parent.
entries = new ArrayList<>(parent.getEntries());
}
for (int i = 0; i < entries.size(); i++) {
if (entries.get(i).getKey().equals(key)) {
entries.remove(i);
// Exit now because the entries list cannot contain duplicates.
break;
}
}
return this;
}
/**
* Builds a TraceState by adding the entries to the parent in front of the key-value pairs list
* and removing duplicate entries.
*
* @return a TraceState with the new entries.
*/
public TraceState build() {
if (entries == null) {
return parent;
}
return TraceState.create(entries);
}
static TraceState create(List<Entry> entries) {
Utils.checkState(entries.size() <= MAX_KEY_VALUE_PAIRS, "Invalid size");
return new AutoValue_TraceState(Collections.unmodifiableList(entries));
}
TraceState() {}
/** Immutable key-value pair for {@code TraceState}. */
@Immutable
@AutoValue
@ -296,11 +224,4 @@ public abstract class TraceState {
}
return true;
}
private static TraceState create(List<Entry> entries) {
Utils.checkState(entries.size() <= MAX_KEY_VALUE_PAIRS, "Invalid size");
return new AutoValue_TraceState(Collections.unmodifiableList(entries));
}
TraceState() {}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.trace;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Objects;
import javax.annotation.Nullable;
/** A builder of {@link TraceState}. */
public final class TraceStateBuilder {
// Needs to be in this class to avoid initialization deadlock because super class depends on
// subclass (the auto-value generate class).
private static final TraceState EMPTY = TraceState.create(Collections.emptyList());
private final TraceState parent;
@Nullable private ArrayList<TraceState.Entry> entries;
TraceStateBuilder() {
parent = EMPTY;
}
TraceStateBuilder(TraceState parent) {
Objects.requireNonNull(parent, "parent");
this.parent = parent;
}
/**
* Adds or updates the {@code Entry} that has the given {@code key} if it is present. The new
* {@code Entry} will always be added in the front of the list of entries.
*
* @param key the key for the {@code Entry} to be added.
* @param value the value for the {@code Entry} to be added.
* @return this.
*/
public TraceStateBuilder set(String key, String value) {
// Initially create the Entry to validate input.
TraceState.Entry entry = TraceState.Entry.create(key, value);
if (entries == null) {
// Copy entries from the parent.
entries = new ArrayList<>(parent.getEntries());
}
for (int i = 0; i < entries.size(); i++) {
if (entries.get(i).getKey().equals(entry.getKey())) {
entries.remove(i);
// Exit now because the entries list cannot contain duplicates.
break;
}
}
// Inserts the element at the front of this list.
entries.add(0, entry);
return this;
}
/**
* Removes the {@code Entry} that has the given {@code key} if it is present.
*
* @param key the key for the {@code Entry} to be removed.
* @return this.
*/
public TraceStateBuilder remove(String key) {
Objects.requireNonNull(key, "key");
if (entries == null) {
// Copy entries from the parent.
entries = new ArrayList<>(parent.getEntries());
}
for (int i = 0; i < entries.size(); i++) {
if (entries.get(i).getKey().equals(key)) {
entries.remove(i);
// Exit now because the entries list cannot contain duplicates.
break;
}
}
return this;
}
/**
* Builds a TraceState by adding the entries to the parent in front of the key-value pairs list
* and removing duplicate entries.
*
* @return a TraceState with the new entries.
*/
public TraceState build() {
if (entries == null) {
return parent;
}
return TraceState.create(entries);
}
}

View File

@ -67,13 +67,13 @@ public interface Tracer {
}
/**
* Returns a {@link Span.Builder} to create and start a new {@link Span}.
* Returns a {@link SpanBuilder} to create and start a new {@link Span}.
*
* <p>See {@link Span.Builder} for usage examples.
* <p>See {@link SpanBuilder} for usage examples.
*
* @param spanName The name of the returned Span.
* @return a {@code Span.Builder} to create and start a new {@code Span}.
* @throws NullPointerException if {@code spanName} is {@code null}.
*/
Span.Builder spanBuilder(String spanName);
SpanBuilder spanBuilder(String spanName);
}

View File

@ -14,6 +14,7 @@ import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceFlags;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.api.trace.TraceState;
import io.opentelemetry.api.trace.TraceStateBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapPropagator;
import java.util.Arrays;
@ -217,7 +218,7 @@ public final class HttpTraceContext implements TextMapPropagator {
}
private static TraceState extractTraceState(String traceStateHeader) {
TraceState.Builder traceStateBuilder = TraceState.builder();
TraceStateBuilder traceStateBuilder = TraceState.builder();
String[] listMembers = TRACESTATE_ENTRY_DELIMITER_SPLIT_PATTERN.split(traceStateHeader);
checkArgument(
listMembers.length <= TRACESTATE_MAX_MEMBERS, "TraceState has too many elements.");

View File

@ -23,7 +23,7 @@ import io.opentelemetry.api.metrics.LongValueObserver;
import io.opentelemetry.api.metrics.LongValueRecorder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.context.propagation.ContextPropagators;
@ -214,7 +214,7 @@ class OpenTelemetryTest {
@Nullable
@Override
public Span.Builder spanBuilder(String spanName) {
public SpanBuilder spanBuilder(String spanName) {
return null;
}

View File

@ -16,7 +16,7 @@ class BaggageTestUtil {
}
static Baggage listToBaggage(List<Entry> entries) {
Baggage.Builder builder = Baggage.builder();
BaggageBuilder builder = Baggage.builder();
for (Entry entry : entries) {
builder.put(entry.getKey(), entry.getValue(), entry.getEntryMetadata());
}

View File

@ -16,7 +16,7 @@ import io.opentelemetry.context.Scope;
import org.junit.jupiter.api.Test;
/**
* Tests for {@link Baggage} and {@link Baggage.Builder}.
* Tests for {@link Baggage} and {@link BaggageBuilder}.
*
* <p>Tests for scope management with {@link Baggage} are in {@link ScopedBaggageTest}.
*/
@ -81,7 +81,7 @@ class ImmutableBaggageTest {
void put_nullKey() {
Baggage parent = listToBaggage(T1);
Context parentContext = Context.root().with(parent);
Baggage.Builder builder = Baggage.builder().setParent(parentContext);
BaggageBuilder builder = Baggage.builder().setParent(parentContext);
assertThrows(NullPointerException.class, () -> builder.put(null, V2, TMD), "key");
}
@ -89,7 +89,7 @@ class ImmutableBaggageTest {
void put_nullValue() {
Baggage parent = listToBaggage(T1);
Context parentContext = Context.root().with(parent);
Baggage.Builder builder = Baggage.builder().setParent(parentContext);
BaggageBuilder builder = Baggage.builder().setParent(parentContext);
assertThrows(NullPointerException.class, () -> builder.put(K2, null, TMD), "value");
}
@ -125,7 +125,7 @@ class ImmutableBaggageTest {
@Test
void remove_existingKey() {
Baggage.Builder builder = Baggage.builder();
BaggageBuilder builder = Baggage.builder();
builder.put(T1.getKey(), T1.getValue(), T1.getEntryMetadata());
builder.put(T2.getKey(), T2.getValue(), T2.getEntryMetadata());
@ -134,7 +134,7 @@ class ImmutableBaggageTest {
@Test
void remove_differentKey() {
Baggage.Builder builder = Baggage.builder();
BaggageBuilder builder = Baggage.builder();
builder.put(T1.getKey(), T1.getValue(), T1.getEntryMetadata());
builder.put(T2.getKey(), T2.getValue(), T2.getEntryMetadata());
@ -151,7 +151,7 @@ class ImmutableBaggageTest {
@Test
void remove_nullKey() {
Baggage.Builder builder = Baggage.builder();
BaggageBuilder builder = Baggage.builder();
assertThrows(NullPointerException.class, () -> builder.remove(null), "key");
}

View File

@ -148,7 +148,7 @@ class AttributesTest {
false);
assertThat(attributes).isEqualTo(wantAttributes);
Attributes.Builder newAttributes = Attributes.builder(attributes);
AttributesBuilder newAttributes = Attributes.builder(attributes);
newAttributes.put("newKey", "newValue");
assertThat(newAttributes.build())
.isEqualTo(
@ -246,7 +246,7 @@ class AttributesTest {
@Test
void nullsAreNoOps() {
Attributes.Builder builder = Attributes.builder();
AttributesBuilder builder = Attributes.builder();
builder.put(stringKey("attrValue"), "attrValue");
builder.put("string", "string");
builder.put("long", 10);

View File

@ -16,13 +16,13 @@ import java.time.Instant;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link Span.Builder}. */
/** Unit tests for {@link SpanBuilder}. */
class SpanBuilderTest {
private final Tracer tracer = Tracer.getDefault();
@Test
void doNotCrash_NoopImplementation() {
Span.Builder spanBuilder = tracer.spanBuilder("MySpanName");
SpanBuilder spanBuilder = tracer.spanBuilder("MySpanName");
spanBuilder.setSpanKind(Kind.SERVER);
spanBuilder.setParent(Context.root().with(Span.wrap(null)));
spanBuilder.setParent(Context.root());
@ -41,13 +41,13 @@ class SpanBuilderTest {
@Test
void setParent_NullContext() {
Span.Builder spanBuilder = tracer.spanBuilder("MySpanName");
SpanBuilder spanBuilder = tracer.spanBuilder("MySpanName");
assertThrows(NullPointerException.class, () -> spanBuilder.setParent(null));
}
@Test
void setStartTimestamp_Negative() {
Span.Builder spanBuilder = tracer.spanBuilder("MySpanName");
SpanBuilder spanBuilder = tracer.spanBuilder("MySpanName");
assertThrows(
IllegalArgumentException.class,
() -> spanBuilder.setStartTimestamp(-1, TimeUnit.NANOSECONDS),

View File

@ -6,6 +6,7 @@
package io.opentelemetry.extension.trace.propagation;
import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageBuilder;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.api.trace.SpanId;
@ -208,7 +209,7 @@ public class JaegerPropagator implements TextMapPropagator {
}
private static <C> Baggage getBaggageFromHeader(C carrier, Getter<C> getter) {
Baggage.Builder builder = null;
BaggageBuilder builder = null;
for (String key : getter.keys(carrier)) {
if (key.startsWith(BAGGAGE_PREFIX)) {
@ -228,7 +229,7 @@ public class JaegerPropagator implements TextMapPropagator {
}
@SuppressWarnings("StringSplitter")
private static Baggage.Builder parseBaggageHeader(String header, Baggage.Builder builder) {
private static BaggageBuilder parseBaggageHeader(String header, BaggageBuilder builder) {
for (String part : header.split("\\s*,\\s*")) {
String[] kv = part.split("\\s*=\\s*");
if (kv.length == 2) {

View File

@ -10,6 +10,7 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.trace.Span;
import javax.annotation.concurrent.Immutable;
@ -51,7 +52,7 @@ public final class MessageEvent {
*/
public static void record(
Span span, Type type, long messageId, long uncompressedSize, long compressedSize) {
Attributes.Builder attributeBuilder = Attributes.builder();
AttributesBuilder attributeBuilder = Attributes.builder();
attributeBuilder.put(TYPE, type == Type.SENT ? Type.SENT.name() : Type.RECEIVED.name());
attributeBuilder.put(ID, messageId);
attributeBuilder.put(UNCOMPRESSED_SIZE, uncompressedSize);

View File

@ -21,7 +21,9 @@ import io.opencensus.trace.export.SpanData.TimedEvent;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceFlags;
import io.opentelemetry.api.trace.TraceId;
@ -77,7 +79,7 @@ class SpanConverter {
return io.opentelemetry.api.trace.Span.getInvalid();
}
SpanData ocSpanData = ((RecordEventsSpanImpl) span).toSpanData();
io.opentelemetry.api.trace.Span.Builder builder =
SpanBuilder builder =
TRACER
.spanBuilder(ocSpanData.getName())
.setStartTimestamp(
@ -102,7 +104,7 @@ class SpanConverter {
}
if (ocSpanData.getLinks() != null) {
for (Link link : ocSpanData.getLinks().getLinks()) {
Attributes.Builder attributesBuilder = Attributes.builder();
AttributesBuilder attributesBuilder = Attributes.builder();
link.getAttributes()
.forEach(
(s, attributeValue) ->
@ -176,7 +178,7 @@ class SpanConverter {
static void mapAndAddAnnotations(
io.opentelemetry.api.trace.Span span, List<TimedEvent<Annotation>> annotations) {
for (TimedEvent<Annotation> annotation : annotations) {
Attributes.Builder attributesBuilder = Attributes.builder();
AttributesBuilder attributesBuilder = Attributes.builder();
annotation
.getEvent()
.getAttributes()
@ -197,7 +199,7 @@ class SpanConverter {
}
}
private static Function<String, Void> setStringAttribute(Attributes.Builder builder, String key) {
private static Function<String, Void> setStringAttribute(AttributesBuilder builder, String key) {
return arg -> {
builder.put(key, arg);
return null;
@ -205,8 +207,7 @@ class SpanConverter {
}
private static Function<String, Void> setStringAttribute(
io.opentelemetry.api.trace.Span.Builder builder,
Map.Entry<String, AttributeValue> attribute) {
SpanBuilder builder, Map.Entry<String, AttributeValue> attribute) {
return arg -> {
builder.setAttribute(attribute.getKey(), arg);
return null;
@ -214,7 +215,7 @@ class SpanConverter {
}
private static Function<Boolean, Void> setBooleanAttribute(
Attributes.Builder builder, String key) {
AttributesBuilder builder, String key) {
return arg -> {
builder.put(key, arg);
return null;
@ -222,15 +223,14 @@ class SpanConverter {
}
private static Function<Boolean, Void> setBooleanAttribute(
io.opentelemetry.api.trace.Span.Builder builder,
Map.Entry<String, AttributeValue> attribute) {
SpanBuilder builder, Map.Entry<String, AttributeValue> attribute) {
return arg -> {
builder.setAttribute(attribute.getKey(), arg);
return null;
};
}
private static Function<Long, Void> setLongAttribute(Attributes.Builder builder, String key) {
private static Function<Long, Void> setLongAttribute(AttributesBuilder builder, String key) {
return arg -> {
builder.put(key, arg);
return null;
@ -238,15 +238,14 @@ class SpanConverter {
}
private static Function<Long, Void> setLongAttribute(
io.opentelemetry.api.trace.Span.Builder builder,
Map.Entry<String, AttributeValue> attribute) {
SpanBuilder builder, Map.Entry<String, AttributeValue> attribute) {
return arg -> {
builder.setAttribute(attribute.getKey(), arg);
return null;
};
}
private static Function<Double, Void> setDoubleAttribute(Attributes.Builder builder, String key) {
private static Function<Double, Void> setDoubleAttribute(AttributesBuilder builder, String key) {
return arg -> {
builder.put(key, arg);
return null;
@ -254,8 +253,7 @@ class SpanConverter {
}
private static Function<Double, Void> setDoubleAttribute(
io.opentelemetry.api.trace.Span.Builder builder,
Map.Entry<String, AttributeValue> attribute) {
SpanBuilder builder, Map.Entry<String, AttributeValue> attribute) {
return arg -> {
builder.setAttribute(attribute.getKey(), arg);
return null;

View File

@ -183,7 +183,7 @@ final class SpanBuilderShim extends BaseShimObject implements SpanBuilder {
@Override
public Span start() {
Baggage baggage = null;
io.opentelemetry.api.trace.Span.Builder builder = tracer().spanBuilder(spanName);
io.opentelemetry.api.trace.SpanBuilder builder = tracer().spanBuilder(spanName);
if (ignoreActiveSpan && parentSpan == null && parentSpanContext == null) {
builder.setNoParent();

View File

@ -6,6 +6,7 @@
package io.opentelemetry.opentracingshim;
import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageBuilder;
import io.opentelemetry.api.baggage.EntryMetadata;
import io.opentelemetry.context.Context;
import io.opentracing.SpanContext;
@ -43,7 +44,7 @@ final class SpanContextShim extends BaseShimObject implements SpanContext {
SpanContextShim newWithKeyValue(String key, String value) {
Context parentContext = Context.current().with(baggage);
Baggage.Builder builder = Baggage.builder().setParent(parentContext);
BaggageBuilder builder = Baggage.builder().setParent(parentContext);
builder.put(key, value, EntryMetadata.EMPTY);
return new SpanContextShim(telemetryInfo(), context, builder.build());

View File

@ -11,6 +11,7 @@ import static io.opentelemetry.api.common.AttributeKey.longKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.trace.StatusCode;
import io.opentracing.Span;
import io.opentracing.SpanContext;
@ -187,7 +188,7 @@ final class SpanShim extends BaseShimObject implements Span {
}
static Attributes convertToAttributes(Map<String, ?> fields) {
Attributes.Builder attributesBuilder = Attributes.builder();
AttributesBuilder attributesBuilder = Attributes.builder();
for (Map.Entry<String, ?> entry : fields.entrySet()) {
String key = entry.getKey();

View File

@ -10,6 +10,7 @@ import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.google.common.annotations.VisibleForTesting;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.ResourceAttributes;
import io.opentelemetry.sdk.resources.ResourceProvider;
import java.io.File;
@ -53,7 +54,7 @@ public class BeanstalkResource extends ResourceProvider {
return Attributes.empty();
}
Attributes.Builder attrBuilders = Attributes.builder();
AttributesBuilder attrBuilders = Attributes.builder();
try (JsonParser parser = JSON_FACTORY.createParser(configFile)) {
parser.nextToken();

View File

@ -11,6 +11,7 @@ import com.fasterxml.jackson.core.JsonToken;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.io.ByteStreams;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.ResourceAttributes;
import io.opentelemetry.sdk.resources.ResourceProvider;
import java.io.ByteArrayOutputStream;
@ -148,7 +149,7 @@ public class Ec2Resource extends ResourceProvider {
String hostname = fetchHostname(token);
Attributes.Builder attrBuilders = Attributes.builder();
AttributesBuilder attrBuilders = Attributes.builder();
attrBuilders.put(ResourceAttributes.CLOUD_PROVIDER, AwsResourceConstants.cloudProvider());
try (JsonParser parser = JSON_FACTORY.createParser(identity)) {

View File

@ -8,6 +8,7 @@ package io.opentelemetry.sdk.extension.trace.aws.resource;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.ResourceAttributes;
import io.opentelemetry.sdk.resources.ResourceProvider;
import java.net.InetAddress;
@ -50,7 +51,7 @@ public class EcsResource extends ResourceProvider {
return Attributes.empty();
}
Attributes.Builder attrBuilders = Attributes.builder();
AttributesBuilder attrBuilders = Attributes.builder();
attrBuilders.put(ResourceAttributes.CLOUD_PROVIDER, AwsResourceConstants.cloudProvider());
try {
String hostName = InetAddress.getLocalHost().getHostName();

View File

@ -12,6 +12,7 @@ import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.io.Files;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.ResourceAttributes;
import io.opentelemetry.sdk.resources.ResourceProvider;
import java.io.File;
@ -60,7 +61,7 @@ public class EksResource extends ResourceProvider {
return Attributes.empty();
}
Attributes.Builder attrBuilders = Attributes.builder();
AttributesBuilder attrBuilders = Attributes.builder();
String clusterName = getClusterName();
if (!Strings.isNullOrEmpty(clusterName)) {

View File

@ -21,6 +21,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.ResourceAttributes;
import io.opentelemetry.sdk.resources.ResourceProvider;
import java.util.ServiceLoader;
@ -69,7 +70,7 @@ public class Ec2ResourceTest {
stubFor(any(urlPathEqualTo("/latest/meta-data/hostname")).willReturn(ok("ec2-1-2-3-4")));
Attributes attributes = populator.getAttributes();
Attributes.Builder expectedAttrBuilders = Attributes.builder();
AttributesBuilder expectedAttrBuilders = Attributes.builder();
expectedAttrBuilders.put(ResourceAttributes.CLOUD_PROVIDER, "aws");
expectedAttrBuilders.put(ResourceAttributes.HOST_ID, "i-1234567890abcdef0");
@ -103,7 +104,7 @@ public class Ec2ResourceTest {
Attributes attributes = populator.getAttributes();
Attributes.Builder expectedAttrBuilders =
AttributesBuilder expectedAttrBuilders =
Attributes.builder()
.put(ResourceAttributes.CLOUD_PROVIDER, "aws")
.put(ResourceAttributes.HOST_ID, "i-1234567890abcdef0")

View File

@ -7,6 +7,7 @@ package io.opentelemetry.sdk.logging.data;
import com.google.auto.value.AutoValue;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
@ -90,7 +91,7 @@ public abstract class LogRecord {
private String severityText;
private String name;
private AnyValue body = AnyValue.stringAnyValue("");
private final Attributes.Builder attributeBuilder = Attributes.builder();
private final AttributesBuilder attributeBuilder = Attributes.builder();
public Builder setUnixTimeNano(long timestamp) {
this.timeUnixNano = timestamp;

View File

@ -6,6 +6,7 @@
package io.opentelemetry.sdk.extension.resources;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.ResourceAttributes;
import io.opentelemetry.sdk.resources.ResourceProvider;
import javax.annotation.Nullable;
@ -27,7 +28,7 @@ public class OsResource extends ResourceProvider {
return Attributes.empty();
}
Attributes.Builder attributes = Attributes.builder();
AttributesBuilder attributes = Attributes.builder();
String osName = getOs(os);
if (osName != null) {

View File

@ -6,6 +6,7 @@
package io.opentelemetry.sdk.extension.resources;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.resources.ResourceAttributes;
import io.opentelemetry.sdk.resources.ResourceProvider;
import java.io.File;
@ -16,7 +17,7 @@ import java.lang.management.RuntimeMXBean;
public class ProcessResource extends ResourceProvider {
@Override
protected Attributes getAttributes() {
Attributes.Builder attributes = Attributes.builder();
AttributesBuilder attributes = Attributes.builder();
// TODO(anuraaga): Use reflection to get more stable values on Java 9+
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();

View File

@ -11,6 +11,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.testing.EqualsTester;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.common.ReadableAttributes;
import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.SpanId;
@ -44,7 +45,7 @@ class DelegatingSpanDataTest {
} else {
clientType = "unknown";
}
Attributes.Builder newAttributes = Attributes.builder();
AttributesBuilder newAttributes = Attributes.builder();
delegate.getAttributes().forEach(newAttributes::put);
newAttributes.put("client_type", clientType);
attributes = newAttributes.build();

View File

@ -9,6 +9,7 @@ import static java.util.Objects.requireNonNull;
import com.google.common.annotations.VisibleForTesting;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.OpenTelemetryBuilder;
import io.opentelemetry.api.internal.Obfuscated;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.api.trace.Tracer;
@ -128,7 +129,7 @@ public final class OpenTelemetrySdk implements OpenTelemetry {
}
/** A builder for configuring an {@link OpenTelemetrySdk}. */
public static class Builder implements OpenTelemetry.Builder<Builder> {
public static class Builder implements OpenTelemetryBuilder<Builder> {
private Clock clock = MillisClock.getInstance();
private Resource resource = Resource.getDefault();
private ContextPropagators propagators = DefaultContextPropagators.builder().build();

View File

@ -7,6 +7,7 @@ package io.opentelemetry.sdk.resources;
import com.google.common.annotations.VisibleForTesting;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.common.export.ConfigBuilder;
import java.util.Map;
import javax.annotation.Nullable;
@ -37,7 +38,7 @@ final class EnvAutodetectResource {
if (rawEnvAttributes == null) {
return Attributes.empty();
} else {
Attributes.Builder attrBuilders = Attributes.builder();
AttributesBuilder attrBuilders = Attributes.builder();
String[] rawAttributes = rawEnvAttributes.split(ATTRIBUTE_LIST_SPLITTER, -1);
for (String rawAttribute : rawAttributes) {
String[] keyValuePair = rawAttribute.split(ATTRIBUTE_KEY_VALUE_SPLITTER, -1);

View File

@ -14,6 +14,7 @@ import com.google.auto.value.extension.memoized.Memoized;
import io.opentelemetry.api.common.AttributeConsumer;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.common.ReadableAttributes;
import io.opentelemetry.api.internal.StringUtils;
import io.opentelemetry.api.internal.Utils;
@ -154,7 +155,7 @@ public abstract class Resource {
return this;
}
Attributes.Builder attrBuilder = Attributes.builder();
AttributesBuilder attrBuilder = Attributes.builder();
Merger merger = new Merger(attrBuilder);
other.getAttributes().forEach(merger);
this.getAttributes().forEach(merger);
@ -162,9 +163,9 @@ public abstract class Resource {
}
private static final class Merger implements AttributeConsumer {
private final Attributes.Builder attrBuilder;
private final AttributesBuilder attrBuilder;
private Merger(Attributes.Builder attrBuilder) {
private Merger(AttributesBuilder attrBuilder) {
this.attrBuilder = attrBuilder;
}

View File

@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.testing.EqualsTester;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.common.ReadableAttributes;
import java.util.Arrays;
import java.util.Collections;
@ -54,7 +55,7 @@ class ResourceTest {
@Test
void create_ignoreNull() {
Attributes.Builder attributes = Attributes.builder();
AttributesBuilder attributes = Attributes.builder();
attributes.put(stringKey("string"), null);
Resource resource = Resource.create(attributes.build());
@ -95,7 +96,7 @@ class ResourceTest {
@Test
void create_NullEmptyArray() {
Attributes.Builder attributes = Attributes.builder();
AttributesBuilder attributes = Attributes.builder();
// Empty arrays should be maintained
attributes.put(stringArrayKey("stringArrayAttribute"), Collections.emptyList());

View File

@ -14,6 +14,7 @@ import com.google.common.collect.EvictingQueue;
import io.opentelemetry.api.common.AttributeConsumer;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.common.ReadableAttributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
@ -361,7 +362,7 @@ final class RecordEventsReadableSpan implements ReadWriteSpan {
return attributes;
}
Attributes.Builder result = Attributes.builder();
AttributesBuilder result = Attributes.builder();
attributes.forEach(new LimitingAttributeConsumer(limit, result));
return result.build();
}
@ -411,7 +412,7 @@ final class RecordEventsReadableSpan implements ReadWriteSpan {
}
long timestampNanos = clock.now();
Attributes.Builder attributes = Attributes.builder();
AttributesBuilder attributes = Attributes.builder();
attributes.put(SemanticAttributes.EXCEPTION_TYPE, exception.getClass().getCanonicalName());
if (exception.getMessage() != null) {
attributes.put(SemanticAttributes.EXCEPTION_MESSAGE, exception.getMessage());
@ -577,10 +578,10 @@ final class RecordEventsReadableSpan implements ReadWriteSpan {
@SuppressWarnings({"rawtypes", "unchecked"})
private static class LimitingAttributeConsumer implements AttributeConsumer {
private final int limit;
private final Attributes.Builder builder;
private final AttributesBuilder builder;
private int added;
public LimitingAttributeConsumer(int limit, Attributes.Builder builder) {
public LimitingAttributeConsumer(int limit, AttributesBuilder builder) {
this.limit = limit;
this.builder = builder;
}

View File

@ -18,6 +18,7 @@ import io.opentelemetry.api.common.ReadableAttributes;
import io.opentelemetry.api.internal.Utils;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.api.trace.TraceFlags;
import io.opentelemetry.api.trace.TraceState;
@ -37,8 +38,8 @@ import java.util.Objects;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
/** {@link SpanBuilderSdk} is SDK implementation of {@link Span.Builder}. */
final class SpanBuilderSdk implements Span.Builder {
/** {@link SpanBuilderSdk} is SDK implementation of {@link SpanBuilder}. */
final class SpanBuilderSdk implements SpanBuilder {
private final String spanName;
private final InstrumentationLibraryInfo instrumentationLibraryInfo;
@ -74,7 +75,7 @@ final class SpanBuilderSdk implements Span.Builder {
}
@Override
public Span.Builder setParent(Context context) {
public SpanBuilder setParent(Context context) {
Objects.requireNonNull(context, "context");
this.isRootSpan = false;
this.parent = context;
@ -82,26 +83,26 @@ final class SpanBuilderSdk implements Span.Builder {
}
@Override
public Span.Builder setNoParent() {
public SpanBuilder setNoParent() {
this.isRootSpan = true;
this.parent = null;
return this;
}
@Override
public Span.Builder setSpanKind(Kind spanKind) {
public SpanBuilder setSpanKind(Kind spanKind) {
this.spanKind = Objects.requireNonNull(spanKind, "spanKind");
return this;
}
@Override
public Span.Builder addLink(SpanContext spanContext) {
public SpanBuilder addLink(SpanContext spanContext) {
addLink(Link.create(spanContext));
return this;
}
@Override
public Span.Builder addLink(SpanContext spanContext, Attributes attributes) {
public SpanBuilder addLink(SpanContext spanContext, Attributes attributes) {
int totalAttributeCount = attributes.size();
addLink(
Link.create(
@ -128,27 +129,27 @@ final class SpanBuilderSdk implements Span.Builder {
}
@Override
public Span.Builder setAttribute(String key, String value) {
public SpanBuilder setAttribute(String key, String value) {
return setAttribute(stringKey(key), value);
}
@Override
public Span.Builder setAttribute(String key, long value) {
public SpanBuilder setAttribute(String key, long value) {
return setAttribute(longKey(key), value);
}
@Override
public Span.Builder setAttribute(String key, double value) {
public SpanBuilder setAttribute(String key, double value) {
return setAttribute(doubleKey(key), value);
}
@Override
public Span.Builder setAttribute(String key, boolean value) {
public SpanBuilder setAttribute(String key, boolean value) {
return setAttribute(booleanKey(key), value);
}
@Override
public <T> Span.Builder setAttribute(AttributeKey<T> key, T value) {
public <T> SpanBuilder setAttribute(AttributeKey<T> key, T value) {
Objects.requireNonNull(key, "key");
if (value == null) {
return this;
@ -166,7 +167,7 @@ final class SpanBuilderSdk implements Span.Builder {
}
@Override
public Span.Builder setStartTimestamp(long startTimestamp, TimeUnit unit) {
public SpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) {
Utils.checkArgument(startTimestamp >= 0, "Negative startTimestamp");
startEpochNanos = unit.toNanos(startTimestamp);
return this;

View File

@ -5,7 +5,7 @@
package io.opentelemetry.sdk.trace;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
@ -20,7 +20,7 @@ final class TracerSdk implements Tracer {
}
@Override
public Span.Builder spanBuilder(String spanName) {
public SpanBuilder spanBuilder(String spanName) {
if (sharedState.isStopped()) {
return Tracer.getDefault().spanBuilder(spanName);
}

View File

@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import io.opentelemetry.api.common.AttributeConsumer;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.common.ReadableAttributes;
import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.SpanContext;
@ -87,7 +88,7 @@ class RecordEventsReadableSpanTest {
attributes.put(stringKey("MyStringAttributeKey"), "MyStringAttributeValue");
attributes.put(longKey("MyLongAttributeKey"), 123L);
attributes.put(booleanKey("MyBooleanAttributeKey"), false);
Attributes.Builder builder =
AttributesBuilder builder =
Attributes.builder().put("MySingleStringAttributeKey", "MySingleStringAttributeValue");
for (Map.Entry<AttributeKey, Object> entry : attributes.entrySet()) {
builder.put(entry.getKey(), entry.getValue());

View File

@ -22,6 +22,7 @@ import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.ReadableAttributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceFlags;
@ -82,7 +83,7 @@ class SpanBuilderSdkTest {
@Test
void addLink() {
// Verify methods do not crash.
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.addLink(Span.getInvalid().getSpanContext());
spanBuilder.addLink(Span.getInvalid().getSpanContext(), Attributes.empty());
@ -103,7 +104,7 @@ class SpanBuilderSdkTest {
.build();
tracerSdkFactory.updateActiveTraceConfig(traceConfig);
// Verify methods do not crash.
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
for (int i = 0; i < 2 * maxNumberOfLinks; i++) {
spanBuilder.addLink(sampledSpanContext);
}
@ -129,7 +130,7 @@ class SpanBuilderSdkTest {
.setMaxNumberOfAttributesPerLink(1)
.build();
tracerSdkFactory.updateActiveTraceConfig(traceConfig);
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
Attributes attributes =
Attributes.of(
stringKey("key0"), "str",
@ -149,7 +150,7 @@ class SpanBuilderSdkTest {
@Test
void addLink_NoEffectAfterStartSpan() {
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.addLink(sampledSpanContext);
RecordEventsReadableSpan span = (RecordEventsReadableSpan) spanBuilder.startSpan();
try {
@ -191,7 +192,7 @@ class SpanBuilderSdkTest {
@Test
void setAttribute() {
Span.Builder spanBuilder =
SpanBuilder spanBuilder =
tracerSdk
.spanBuilder(SPAN_NAME)
.setAttribute("string", "value")
@ -218,7 +219,7 @@ class SpanBuilderSdkTest {
@Test
void setAttribute_afterEnd() {
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.setAttribute("string", "value");
spanBuilder.setAttribute("long", 12345L);
spanBuilder.setAttribute("double", .12345);
@ -255,7 +256,7 @@ class SpanBuilderSdkTest {
@Test
void setAttribute_emptyArrayAttributeValue() {
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.setAttribute(stringArrayKey("stringArrayAttribute"), emptyList());
spanBuilder.setAttribute(booleanArrayKey("boolArrayAttribute"), emptyList());
spanBuilder.setAttribute(longArrayKey("longArrayAttribute"), emptyList());
@ -266,7 +267,7 @@ class SpanBuilderSdkTest {
@Test
void setAttribute_nullStringValue() {
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.setAttribute("emptyString", "");
spanBuilder.setAttribute("nullString", null);
spanBuilder.setAttribute(stringKey("nullStringAttributeValue"), null);
@ -277,7 +278,7 @@ class SpanBuilderSdkTest {
@Test
void setAttribute_onlyNullStringValue() {
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.setAttribute(stringKey("nullStringAttributeValue"), null);
RecordEventsReadableSpan span = (RecordEventsReadableSpan) spanBuilder.startSpan();
assertThat(span.toSpanData().getAttributes().isEmpty()).isTrue();
@ -285,7 +286,7 @@ class SpanBuilderSdkTest {
@Test
void setAttribute_NoEffectAfterStartSpan() {
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.setAttribute("key1", "value1");
spanBuilder.setAttribute("key2", "value2");
RecordEventsReadableSpan span = (RecordEventsReadableSpan) spanBuilder.startSpan();
@ -305,7 +306,7 @@ class SpanBuilderSdkTest {
@Test
void setAttribute_nullAttributeValue() {
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.setAttribute("emptyString", "");
spanBuilder.setAttribute("nullString", null);
spanBuilder.setAttribute(stringKey("nullStringAttributeValue"), null);
@ -323,7 +324,7 @@ class SpanBuilderSdkTest {
@Test
void setAttribute_nullAttributeValue_afterEnd() {
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.setAttribute("emptyString", "");
spanBuilder.setAttribute(stringKey("emptyStringAttributeValue"), "");
spanBuilder.setAttribute("longAttribute", 0L);
@ -356,7 +357,7 @@ class SpanBuilderSdkTest {
.setMaxNumberOfAttributes(maxNumberOfAttrs)
.build();
tracerSdkFactory.updateActiveTraceConfig(traceConfig);
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
for (int i = 0; i < 2 * maxNumberOfAttrs; i++) {
spanBuilder.setAttribute("key" + i, i);
}
@ -380,7 +381,7 @@ class SpanBuilderSdkTest {
.setMaxLengthOfAttributeValues(10)
.build();
tracerSdkFactory.updateActiveTraceConfig(traceConfig);
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
spanBuilder.setAttribute("builderStringNull", null);
spanBuilder.setAttribute("builderStringSmall", "small");
spanBuilder.setAttribute("builderStringLarge", "very large string that we have to cut");
@ -429,7 +430,7 @@ class SpanBuilderSdkTest {
.setSampler(Sampler.traceIdRatioBased(1))
.build();
tracerSdkFactory.updateActiveTraceConfig(traceConfig);
Span.Builder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
SpanBuilder spanBuilder = tracerSdk.spanBuilder(SPAN_NAME);
RecordEventsReadableSpan span = (RecordEventsReadableSpan) spanBuilder.startSpan();
try {
assertThat(span.toSpanData().getAttributes().size()).isEqualTo(1);

View File

@ -8,8 +8,8 @@ package io.opentelemetry.sdk.trace;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.api.trace.Tracer;
@ -64,7 +64,7 @@ public final class TestUtils {
*
* @return A SpanData instance.
*/
public static Span.Builder startSpanWithSampler(
public static SpanBuilder startSpanWithSampler(
TracerSdkManagement tracerSdkManagement, Tracer tracer, String spanName, Sampler sampler) {
return startSpanWithSampler(
tracerSdkManagement, tracer, spanName, sampler, Collections.emptyMap());
@ -76,7 +76,7 @@ public final class TestUtils {
*
* @return A SpanData instance.
*/
public static Span.Builder startSpanWithSampler(
public static SpanBuilder startSpanWithSampler(
TracerSdkManagement tracerSdkManagement,
Tracer tracer,
String spanName,
@ -86,7 +86,7 @@ public final class TestUtils {
tracerSdkManagement.updateActiveTraceConfig(
originalConfig.toBuilder().setSampler(sampler).build());
try {
Span.Builder builder = tracer.spanBuilder(spanName);
SpanBuilder builder = tracer.spanBuilder(spanName);
attributes.forEach(builder::setAttribute);
return builder;

View File

@ -7,6 +7,7 @@ package io.opentelemetry.sdk.trace.testbed.concurrentcommonrequesthandler;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context;
@ -33,7 +34,7 @@ final class RequestHandler {
public void beforeRequest(Object request, RequestHandlerContext requestHandlerContext) {
// we cannot use active span because we don't know in which thread it is executed
// and we cannot therefore activate span. thread can come from common thread pool.
Span.Builder spanBuilder =
SpanBuilder spanBuilder =
tracer.spanBuilder(OPERATION_NAME).setNoParent().setSpanKind(Kind.CLIENT);
if (parentContext != null) {