Introduce usage of the OpenTelemetry schema with a Tracer/MeterBuilder (#3309)
* Add the OpenTelemetry schema URL to the InstrumentationLibraryInfo and the corresponding API calls. * small refactoring and doc tweaks from feedback * make the instrumentation version nullable on the method that takes a schema * update the apidiffs * add since tags and a few more missing nullable annotations * Switch to using a Builder rather than method overloads.
This commit is contained in:
parent
b212fce5a1
commit
ca92a9ab03
|
@ -7,6 +7,7 @@ package io.opentelemetry.api;
|
|||
|
||||
import io.opentelemetry.api.internal.GuardedBy;
|
||||
import io.opentelemetry.api.trace.Tracer;
|
||||
import io.opentelemetry.api.trace.TracerBuilder;
|
||||
import io.opentelemetry.api.trace.TracerProvider;
|
||||
import io.opentelemetry.context.propagation.ContextPropagators;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -126,6 +127,20 @@ public final class GlobalOpenTelemetry {
|
|||
return get().getTracer(instrumentationName, instrumentationVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TracerBuilder for a named {@link Tracer} instance.
|
||||
*
|
||||
* <p>This is a shortcut method for {@code get().tracerBuilder(instrumentationName)}
|
||||
*
|
||||
* @param instrumentationName The name of the instrumentation library, not the name of the
|
||||
* instrument*ed* library.
|
||||
* @return a TracerBuilder instance.
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public static TracerBuilder tracerBuilder(String instrumentationName) {
|
||||
return get().tracerBuilder(instrumentationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets the global {@link OpenTelemetry}. This is only meant to be used from tests which need to
|
||||
* reconfigure {@link OpenTelemetry}.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.opentelemetry.api;
|
||||
|
||||
import io.opentelemetry.api.trace.Tracer;
|
||||
import io.opentelemetry.api.trace.TracerBuilder;
|
||||
import io.opentelemetry.api.trace.TracerProvider;
|
||||
import io.opentelemetry.context.propagation.ContextPropagators;
|
||||
|
||||
|
@ -63,6 +64,18 @@ public interface OpenTelemetry {
|
|||
return getTracerProvider().get(instrumentationName, instrumentationVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link TracerBuilder} for a named {@link Tracer} instance.
|
||||
*
|
||||
* @param instrumentationName The name of the instrumentation library, not the name of the
|
||||
* instrument*ed* library.
|
||||
* @return a TracerBuilder instance.
|
||||
* @since 1.4.0
|
||||
*/
|
||||
default TracerBuilder tracerBuilder(String instrumentationName) {
|
||||
return getTracerProvider().tracerBuilder(instrumentationName);
|
||||
}
|
||||
|
||||
/** Returns the {@link ContextPropagators} for this {@link OpenTelemetry}. */
|
||||
ContextPropagators getPropagators();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.api.trace;
|
||||
|
||||
class DefaultTracerBuilder implements TracerBuilder {
|
||||
private static final DefaultTracerBuilder INSTANCE = new DefaultTracerBuilder();
|
||||
|
||||
static TracerBuilder getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TracerBuilder setSchemaUrl(String schemaUrl) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TracerBuilder setInstrumentationVersion(String instrumentationVersion) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tracer build() {
|
||||
return DefaultTracer.getInstance();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.api.trace;
|
||||
|
||||
/**
|
||||
* Builder class for creating {@link Tracer} instances.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public interface TracerBuilder {
|
||||
|
||||
/**
|
||||
* Assign an OpenTelemetry schema URL to the resulting Tracer.
|
||||
*
|
||||
* @param schemaUrl The URL of the OpenTelemetry schema being used by this instrumentation
|
||||
* library.
|
||||
* @return this
|
||||
*/
|
||||
TracerBuilder setSchemaUrl(String schemaUrl);
|
||||
|
||||
/**
|
||||
* Assign a version to the instrumentation library that is using the resulting Tracer.
|
||||
*
|
||||
* @param instrumentationVersion The version of the instrumentation library.
|
||||
* @return this
|
||||
*/
|
||||
TracerBuilder setInstrumentationVersion(String instrumentationVersion);
|
||||
|
||||
/**
|
||||
* Gets or creates a {@link Tracer} instance.
|
||||
*
|
||||
* @return a {@link Tracer} instance configured with the provided options.
|
||||
*/
|
||||
Tracer build();
|
||||
}
|
|
@ -46,4 +46,16 @@ public interface TracerProvider {
|
|||
* @return a tracer instance.
|
||||
*/
|
||||
Tracer get(String instrumentationName, String instrumentationVersion);
|
||||
|
||||
/**
|
||||
* Creates a TracerBuilder for a named {@link Tracer} instance.
|
||||
*
|
||||
* @param instrumentationName The name of the instrumentation library, not the name of the
|
||||
* instrument*ed* library.
|
||||
* @return a TracerBuilder instance.
|
||||
* @since 1.4.0
|
||||
*/
|
||||
default TracerBuilder tracerBuilder(String instrumentationName) {
|
||||
return DefaultTracerBuilder.getInstance();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.api.metrics;
|
||||
|
||||
class DefaultMeterBuilder implements MeterBuilder {
|
||||
private static final MeterBuilder INSTANCE = new DefaultMeterBuilder();
|
||||
|
||||
static MeterBuilder getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MeterBuilder setSchemaUrl(String schemaUrl) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MeterBuilder setInstrumentationVersion(String instrumentationVersion) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Meter build() {
|
||||
return DefaultMeter.getInstance();
|
||||
}
|
||||
}
|
|
@ -68,4 +68,18 @@ public final class GlobalMeterProvider {
|
|||
public static Meter getMeter(String instrumentationName, String instrumentationVersion) {
|
||||
return get().get(instrumentationName, instrumentationVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link MeterBuilder} for a named meter instance.
|
||||
*
|
||||
* <p>This is a shortcut method for {@code get().meterBuilder(instrumentationName)}
|
||||
*
|
||||
* @param instrumentationName The name of the instrumentation library, not the name of the
|
||||
* instrument*ed* library.
|
||||
* @return a MeterBuilder instance.
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public static MeterBuilder meterBuilder(String instrumentationName) {
|
||||
return get().meterBuilder(instrumentationName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.api.metrics;
|
||||
|
||||
/**
|
||||
* Builder class for creating {@link Meter} instances.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public interface MeterBuilder {
|
||||
|
||||
/**
|
||||
* Assign an OpenTelemetry schema URL to the resulting Meter.
|
||||
*
|
||||
* @param schemaUrl The URL of the OpenTelemetry schema being used by this instrumentation
|
||||
* library.
|
||||
* @return this
|
||||
*/
|
||||
MeterBuilder setSchemaUrl(String schemaUrl);
|
||||
|
||||
/**
|
||||
* Assign a version to the instrumentation library that is using the resulting Meter.
|
||||
*
|
||||
* @param instrumentationVersion The version of the instrumentation library.
|
||||
* @return this
|
||||
*/
|
||||
MeterBuilder setInstrumentationVersion(String instrumentationVersion);
|
||||
|
||||
/**
|
||||
* Gets or creates a {@link Meter} instance.
|
||||
*
|
||||
* @return a {@link Meter} instance configured with the provided options.
|
||||
*/
|
||||
Meter build();
|
||||
}
|
|
@ -42,4 +42,16 @@ public interface MeterProvider {
|
|||
* @return a tracer instance.
|
||||
*/
|
||||
Meter get(String instrumentationName, String instrumentationVersion);
|
||||
|
||||
/**
|
||||
* Creates a MeterBuilder for a named meter instance.
|
||||
*
|
||||
* @param instrumentationName The name of the instrumentation library, not the name of the
|
||||
* instrument*ed* library.
|
||||
* @return a MeterBuilder instance.
|
||||
* @since 1.4.0
|
||||
*/
|
||||
default MeterBuilder meterBuilder(String instrumentationName) {
|
||||
return DefaultMeterBuilder.getInstance();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,5 +15,12 @@ class DefaultMeterTest {
|
|||
assertThat(MeterProvider.noop().get("test")).isInstanceOf(DefaultMeter.class);
|
||||
assertThat(MeterProvider.noop().get("test")).isSameAs(DefaultMeter.getInstance());
|
||||
assertThat(MeterProvider.noop().get("test", "0.1.0")).isSameAs(DefaultMeter.getInstance());
|
||||
assertThat(
|
||||
MeterProvider.noop()
|
||||
.meterBuilder("test")
|
||||
.setInstrumentationVersion("0.1.0")
|
||||
.setSchemaUrl("http://url")
|
||||
.build())
|
||||
.isSameAs(DefaultMeter.getInstance());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,16 @@
|
|||
Comparing source compatibility of against
|
||||
No changes.
|
||||
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.api.GlobalOpenTelemetry (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.trace.TracerBuilder tracerBuilder(java.lang.String)
|
||||
***! MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.OpenTelemetry (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.TracerBuilder tracerBuilder(java.lang.String)
|
||||
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.trace.TracerBuilder (not serializable)
|
||||
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
|
||||
+++ NEW SUPERCLASS: java.lang.Object
|
||||
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.trace.Tracer build()
|
||||
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.trace.TracerBuilder setInstrumentationVersion(java.lang.String)
|
||||
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.api.trace.TracerBuilder setSchemaUrl(java.lang.String)
|
||||
***! MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.trace.TracerProvider (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.TracerBuilder tracerBuilder(java.lang.String)
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
Comparing source compatibility of against
|
||||
No changes.
|
||||
**** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.common.InstrumentationLibraryInfo (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.InstrumentationLibraryInfo create(java.lang.String, java.lang.String, java.lang.String)
|
||||
+++* NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String getSchemaUrl()
|
||||
+++ NEW ANNOTATION: javax.annotation.Nullable
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
Comparing source compatibility of against
|
||||
No changes.
|
||||
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.SdkTracerProvider (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.trace.TracerBuilder tracerBuilder(java.lang.String)
|
||||
|
|
|
@ -58,12 +58,7 @@ public final class MetricAdapter {
|
|||
new ArrayList<>(entryResource.getValue().size());
|
||||
for (Map.Entry<InstrumentationLibraryInfo, List<Metric>> entryLibrary :
|
||||
entryResource.getValue().entrySet()) {
|
||||
instrumentationLibraryMetrics.add(
|
||||
InstrumentationLibraryMetrics.newBuilder()
|
||||
.setInstrumentationLibrary(
|
||||
CommonAdapter.toProtoInstrumentationLibrary(entryLibrary.getKey()))
|
||||
.addAllMetrics(entryLibrary.getValue())
|
||||
.build());
|
||||
instrumentationLibraryMetrics.add(buildInstrumentationLibraryMetrics(entryLibrary));
|
||||
}
|
||||
resourceMetrics.add(
|
||||
ResourceMetrics.newBuilder()
|
||||
|
@ -74,6 +69,19 @@ public final class MetricAdapter {
|
|||
return resourceMetrics;
|
||||
}
|
||||
|
||||
private static InstrumentationLibraryMetrics buildInstrumentationLibraryMetrics(
|
||||
Map.Entry<InstrumentationLibraryInfo, List<Metric>> entryLibrary) {
|
||||
InstrumentationLibraryMetrics.Builder metricsBuilder =
|
||||
InstrumentationLibraryMetrics.newBuilder()
|
||||
.setInstrumentationLibrary(
|
||||
CommonAdapter.toProtoInstrumentationLibrary(entryLibrary.getKey()))
|
||||
.addAllMetrics(entryLibrary.getValue());
|
||||
if (entryLibrary.getKey().getSchemaUrl() != null) {
|
||||
metricsBuilder.setSchemaUrl(entryLibrary.getKey().getSchemaUrl());
|
||||
}
|
||||
return metricsBuilder.build();
|
||||
}
|
||||
|
||||
private static Map<Resource, Map<InstrumentationLibraryInfo, List<Metric>>>
|
||||
groupByResourceAndLibrary(Collection<MetricData> metricDataList) {
|
||||
Map<Resource, Map<InstrumentationLibraryInfo, List<Metric>>> result = new HashMap<>();
|
||||
|
|
|
@ -75,18 +75,27 @@ public final class SpanAdapter {
|
|||
ResourceSpans.Builder resourceSpansBuilder =
|
||||
ResourceSpans.newBuilder().setResource(ResourceAdapter.toProtoResource(resource));
|
||||
librarySpans.forEach(
|
||||
(library, spans) ->
|
||||
resourceSpansBuilder.addInstrumentationLibrarySpans(
|
||||
InstrumentationLibrarySpans.newBuilder()
|
||||
.setInstrumentationLibrary(
|
||||
CommonAdapter.toProtoInstrumentationLibrary(library))
|
||||
.addAllSpans(spans)
|
||||
.build()));
|
||||
(library, spans) -> {
|
||||
resourceSpansBuilder.addInstrumentationLibrarySpans(
|
||||
buildInstrumentationLibrarySpan(library, spans));
|
||||
});
|
||||
resourceSpans.add(resourceSpansBuilder.build());
|
||||
});
|
||||
return resourceSpans;
|
||||
}
|
||||
|
||||
private static InstrumentationLibrarySpans buildInstrumentationLibrarySpan(
|
||||
InstrumentationLibraryInfo library, List<Span> spans) {
|
||||
InstrumentationLibrarySpans.Builder spansBuilder =
|
||||
InstrumentationLibrarySpans.newBuilder()
|
||||
.setInstrumentationLibrary(CommonAdapter.toProtoInstrumentationLibrary(library))
|
||||
.addAllSpans(spans);
|
||||
if (library.getSchemaUrl() != null) {
|
||||
spansBuilder.setSchemaUrl(library.getSchemaUrl());
|
||||
}
|
||||
return spansBuilder.build();
|
||||
}
|
||||
|
||||
private static Map<Resource, Map<InstrumentationLibraryInfo, List<Span>>>
|
||||
groupByResourceAndLibrary(Collection<SpanData> spanDataList) {
|
||||
Map<Resource, Map<InstrumentationLibraryInfo, List<Span>>> result = new HashMap<>();
|
||||
|
|
|
@ -568,7 +568,7 @@ class MetricAdapterTest {
|
|||
io.opentelemetry.proto.resource.v1.Resource emptyResourceProto =
|
||||
io.opentelemetry.proto.resource.v1.Resource.newBuilder().build();
|
||||
InstrumentationLibraryInfo instrumentationLibraryInfo =
|
||||
InstrumentationLibraryInfo.create("name", "version");
|
||||
InstrumentationLibraryInfo.create("name", "version", "http://url");
|
||||
InstrumentationLibrary instrumentationLibraryProto =
|
||||
InstrumentationLibrary.newBuilder().setName("name").setVersion("version").build();
|
||||
InstrumentationLibrary emptyInstrumentationLibraryProto =
|
||||
|
@ -652,6 +652,7 @@ class MetricAdapterTest {
|
|||
InstrumentationLibraryMetrics.newBuilder()
|
||||
.setInstrumentationLibrary(instrumentationLibraryProto)
|
||||
.addAllMetrics(ImmutableList.of(metricDoubleSum, metricDoubleSum))
|
||||
.setSchemaUrl("http://url")
|
||||
.build()))
|
||||
.build(),
|
||||
ResourceMetrics.newBuilder()
|
||||
|
@ -659,11 +660,12 @@ class MetricAdapterTest {
|
|||
.addAllInstrumentationLibraryMetrics(
|
||||
ImmutableList.of(
|
||||
InstrumentationLibraryMetrics.newBuilder()
|
||||
.setInstrumentationLibrary(emptyInstrumentationLibraryProto)
|
||||
.setInstrumentationLibrary(instrumentationLibraryProto)
|
||||
.addAllMetrics(singletonList(metricDoubleSum))
|
||||
.setSchemaUrl("http://url")
|
||||
.build(),
|
||||
InstrumentationLibraryMetrics.newBuilder()
|
||||
.setInstrumentationLibrary(instrumentationLibraryProto)
|
||||
.setInstrumentationLibrary(emptyInstrumentationLibraryProto)
|
||||
.addAllMetrics(singletonList(metricDoubleSum))
|
||||
.build()))
|
||||
.build());
|
||||
|
|
|
@ -29,14 +29,19 @@ import io.opentelemetry.api.trace.TraceFlags;
|
|||
import io.opentelemetry.api.trace.TraceId;
|
||||
import io.opentelemetry.api.trace.TraceState;
|
||||
import io.opentelemetry.proto.common.v1.AnyValue;
|
||||
import io.opentelemetry.proto.common.v1.InstrumentationLibrary;
|
||||
import io.opentelemetry.proto.common.v1.KeyValue;
|
||||
import io.opentelemetry.proto.trace.v1.InstrumentationLibrarySpans;
|
||||
import io.opentelemetry.proto.trace.v1.ResourceSpans;
|
||||
import io.opentelemetry.proto.trace.v1.Span;
|
||||
import io.opentelemetry.proto.trace.v1.Status;
|
||||
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
|
||||
import io.opentelemetry.sdk.testing.trace.TestSpanData;
|
||||
import io.opentelemetry.sdk.trace.data.EventData;
|
||||
import io.opentelemetry.sdk.trace.data.LinkData;
|
||||
import io.opentelemetry.sdk.trace.data.StatusData;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -52,6 +57,35 @@ class SpanAdapterTest {
|
|||
private static final SpanAdapter.ThreadLocalCache threadLocalCache =
|
||||
new SpanAdapter.ThreadLocalCache();
|
||||
|
||||
@Test
|
||||
void toProtoResourceSpans() {
|
||||
List<ResourceSpans> resourceSpans =
|
||||
SpanAdapter.toProtoResourceSpans(
|
||||
Collections.singleton(
|
||||
TestSpanData.builder()
|
||||
.setHasEnded(true)
|
||||
.setSpanContext(SPAN_CONTEXT)
|
||||
.setParentSpanContext(SpanContext.getInvalid())
|
||||
.setName("GET /api/endpoint")
|
||||
.setKind(SpanKind.SERVER)
|
||||
.setStartEpochNanos(12345)
|
||||
.setEndEpochNanos(12349)
|
||||
.setStatus(StatusData.unset())
|
||||
.setInstrumentationLibraryInfo(
|
||||
InstrumentationLibraryInfo.create("testLib", "1.0", "http://url"))
|
||||
.build()));
|
||||
|
||||
assertThat(resourceSpans).hasSize(1);
|
||||
ResourceSpans onlyResourceSpans = resourceSpans.get(0);
|
||||
assertThat(onlyResourceSpans.getInstrumentationLibrarySpansCount()).isEqualTo(1);
|
||||
InstrumentationLibrarySpans instrumentationLibrarySpans =
|
||||
onlyResourceSpans.getInstrumentationLibrarySpans(0);
|
||||
assertThat(instrumentationLibrarySpans.getSchemaUrl()).isEqualTo("http://url");
|
||||
assertThat(instrumentationLibrarySpans.getInstrumentationLibrary())
|
||||
.isEqualTo(
|
||||
InstrumentationLibrary.newBuilder().setName("testLib").setVersion("1.0").build());
|
||||
}
|
||||
|
||||
// Repeat to reuse the cache. If we forgot to clear any reused builder it will fail.
|
||||
@RepeatedTest(3)
|
||||
void toProtoSpan() {
|
||||
|
@ -115,7 +149,8 @@ class SpanAdapterTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation") // setDeprecatedCode is deprecated.
|
||||
@SuppressWarnings("deprecation")
|
||||
// setDeprecatedCode is deprecated.
|
||||
void toProtoStatus() {
|
||||
assertThat(SpanAdapter.toStatusProto(StatusData.unset()))
|
||||
.isEqualTo(
|
||||
|
|
|
@ -28,6 +28,7 @@ import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
|
|||
import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc;
|
||||
import io.opentelemetry.proto.trace.v1.ResourceSpans;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
|
||||
import io.opentelemetry.sdk.testing.trace.TestSpanData;
|
||||
import io.opentelemetry.sdk.trace.data.SpanData;
|
||||
import io.opentelemetry.sdk.trace.data.StatusData;
|
||||
|
@ -301,6 +302,8 @@ class OtlpGrpcSpanExporterTest {
|
|||
.setLinks(Collections.emptyList())
|
||||
.setTotalRecordedLinks(0)
|
||||
.setTotalRecordedEvents(0)
|
||||
.setInstrumentationLibraryInfo(
|
||||
InstrumentationLibraryInfo.create("testLib", "1.0", "http://url"))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,24 @@ public abstract class InstrumentationLibraryInfo {
|
|||
*/
|
||||
public static InstrumentationLibraryInfo create(String name, @Nullable String version) {
|
||||
requireNonNull(name, "name");
|
||||
return new AutoValue_InstrumentationLibraryInfo(name, version);
|
||||
return new AutoValue_InstrumentationLibraryInfo(name, version, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link InstrumentationLibraryInfo}.
|
||||
*
|
||||
* @param name name of the instrumentation library (e.g., "io.opentelemetry.contrib.mongodb"),
|
||||
* must not be null
|
||||
* @param version version of the instrumentation library (e.g., "1.0.0"), might be null
|
||||
* @param schemaUrl the URL of the OpenTelemetry schema being used by this instrumentation
|
||||
* library.
|
||||
* @return the new instance
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public static InstrumentationLibraryInfo create(
|
||||
String name, @Nullable String version, @Nullable String schemaUrl) {
|
||||
requireNonNull(name, "name");
|
||||
return new AutoValue_InstrumentationLibraryInfo(name, version, schemaUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,6 +75,16 @@ public abstract class InstrumentationLibraryInfo {
|
|||
@Nullable
|
||||
public abstract String getVersion();
|
||||
|
||||
/**
|
||||
* Returns the URL of the schema used by this instrumentation library, or {@code null} if not
|
||||
* available.
|
||||
*
|
||||
* @return the URL of the schema used by this instrumentation library, or {@code null} if not
|
||||
* available.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String getSchemaUrl();
|
||||
|
||||
// Package protected ctor to avoid others to extend this class.
|
||||
InstrumentationLibraryInfo() {}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ public final class ComponentRegistry<V> {
|
|||
|
||||
/**
|
||||
* Returns the registered value associated with this name and {@code null} version if any,
|
||||
* otherwise creates a new instance and associates it with the given name and {@code null}
|
||||
* version.
|
||||
* otherwise creates a new instance and associates it with the given name and {@code null} version
|
||||
* and schemaUrl.
|
||||
*
|
||||
* @param instrumentationName the name of the instrumentation library.
|
||||
* @return the registered value associated with this name and {@code null} version.
|
||||
|
@ -42,15 +42,33 @@ public final class ComponentRegistry<V> {
|
|||
|
||||
/**
|
||||
* Returns the registered value associated with this name and version if any, otherwise creates a
|
||||
* new instance and associates it with the given name and version.
|
||||
* new instance and associates it with the given name and version. The schemaUrl will be set to
|
||||
* null.
|
||||
*
|
||||
* @param instrumentationName the name of the instrumentation library.
|
||||
* @param instrumentationVersion the version of the instrumentation library.
|
||||
* @return the registered value associated with this name and version.
|
||||
*/
|
||||
public final V get(String instrumentationName, @Nullable String instrumentationVersion) {
|
||||
return get(instrumentationName, instrumentationVersion, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered value associated with this name and version if any, otherwise creates a
|
||||
* new instance and associates it with the given name and version.
|
||||
*
|
||||
* @param instrumentationName the name of the instrumentation library.
|
||||
* @param instrumentationVersion the version of the instrumentation library.
|
||||
* @param schemaUrl the URL of the OpenTelemetry schema used by the instrumentation library.
|
||||
* @return the registered value associated with this name and version.
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public final V get(
|
||||
String instrumentationName,
|
||||
@Nullable String instrumentationVersion,
|
||||
@Nullable String schemaUrl) {
|
||||
InstrumentationLibraryInfo instrumentationLibraryInfo =
|
||||
InstrumentationLibraryInfo.create(instrumentationName, instrumentationVersion);
|
||||
InstrumentationLibraryInfo.create(instrumentationName, instrumentationVersion, schemaUrl);
|
||||
|
||||
// Optimistic lookup, before creating the new component.
|
||||
V component = registry.get(instrumentationLibraryInfo);
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.sdk.metrics;
|
||||
|
||||
import io.opentelemetry.api.metrics.Meter;
|
||||
import io.opentelemetry.api.metrics.MeterBuilder;
|
||||
import io.opentelemetry.sdk.internal.ComponentRegistry;
|
||||
|
||||
class SdkMeterBuilder implements MeterBuilder {
|
||||
|
||||
private final ComponentRegistry<SdkMeter> registry;
|
||||
private final String instrumentationName;
|
||||
private String instrumentationVersion;
|
||||
private String schemaUrl;
|
||||
|
||||
SdkMeterBuilder(ComponentRegistry<SdkMeter> registry, String instrumentationName) {
|
||||
this.registry = registry;
|
||||
this.instrumentationName = instrumentationName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MeterBuilder setSchemaUrl(String schemaUrl) {
|
||||
this.schemaUrl = schemaUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MeterBuilder setInstrumentationVersion(String instrumentationVersion) {
|
||||
this.instrumentationVersion = instrumentationVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Meter build() {
|
||||
return registry.get(instrumentationName, instrumentationVersion, schemaUrl);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.sdk.metrics;
|
|||
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.api.metrics.Meter;
|
||||
import io.opentelemetry.api.metrics.MeterBuilder;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.sdk.common.Clock;
|
||||
import io.opentelemetry.sdk.internal.ComponentRegistry;
|
||||
|
@ -47,17 +48,23 @@ public final class SdkMeterProvider implements MeterProvider, MetricProducer {
|
|||
|
||||
@Override
|
||||
public Meter get(String instrumentationName) {
|
||||
return get(instrumentationName, null);
|
||||
return meterBuilder(instrumentationName).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Meter get(String instrumentationName, @Nullable String instrumentationVersion) {
|
||||
// Per the spec, both null and empty are "invalid" and a "default" should be used.
|
||||
public Meter get(String instrumentationName, String instrumentationVersion) {
|
||||
return meterBuilder(instrumentationName)
|
||||
.setInstrumentationVersion(instrumentationVersion)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MeterBuilder meterBuilder(@Nullable String instrumentationName) {
|
||||
if (instrumentationName == null || instrumentationName.isEmpty()) {
|
||||
LOGGER.fine("Meter requested without instrumentation name.");
|
||||
instrumentationName = DEFAULT_METER_NAME;
|
||||
}
|
||||
return registry.get(instrumentationName, instrumentationVersion);
|
||||
return new SdkMeterBuilder(registry, instrumentationName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -62,18 +62,43 @@ class SdkMeterRegistryTest {
|
|||
void getSameInstanceForSameName_WithoutVersion() {
|
||||
assertThat(meterProvider.get("test")).isSameAs(meterProvider.get("test"));
|
||||
assertThat(meterProvider.get("test")).isSameAs(meterProvider.get("test", null));
|
||||
assertThat(meterProvider.get("test")).isSameAs(meterProvider.meterBuilder("test").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSameInstanceForSameName_WithVersion() {
|
||||
assertThat(meterProvider.get("test", "version")).isSameAs(meterProvider.get("test", "version"));
|
||||
assertThat(meterProvider.get("test", "version"))
|
||||
.isSameAs(meterProvider.get("test", "version"))
|
||||
.isSameAs(meterProvider.meterBuilder("test").setInstrumentationVersion("version").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSameInstanceForSameName_WithVersionAndSchema() {
|
||||
assertThat(
|
||||
meterProvider
|
||||
.meterBuilder("test")
|
||||
.setInstrumentationVersion("version")
|
||||
.setSchemaUrl("http://url")
|
||||
.build())
|
||||
.isSameAs(
|
||||
meterProvider
|
||||
.meterBuilder("test")
|
||||
.setInstrumentationVersion("version")
|
||||
.setSchemaUrl("http://url")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void propagatesInstrumentationLibraryInfoToMeter() {
|
||||
InstrumentationLibraryInfo expected =
|
||||
InstrumentationLibraryInfo.create("theName", "theVersion");
|
||||
SdkMeter meter = (SdkMeter) meterProvider.get(expected.getName(), expected.getVersion());
|
||||
InstrumentationLibraryInfo.create("theName", "theVersion", "http://theschema");
|
||||
SdkMeter meter =
|
||||
(SdkMeter)
|
||||
meterProvider
|
||||
.meterBuilder(expected.getName())
|
||||
.setInstrumentationVersion(expected.getVersion())
|
||||
.setSchemaUrl(expected.getSchemaUrl())
|
||||
.build();
|
||||
assertThat(meter.getInstrumentationLibraryInfo()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
|
@ -123,6 +148,10 @@ class SdkMeterRegistryTest {
|
|||
meter = (SdkMeter) meterProvider.get(null, null);
|
||||
assertThat(meter.getInstrumentationLibraryInfo().getName())
|
||||
.isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME);
|
||||
|
||||
meter = (SdkMeter) meterProvider.meterBuilder(null).build();
|
||||
assertThat(meter.getInstrumentationLibraryInfo().getName())
|
||||
.isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -134,5 +163,9 @@ class SdkMeterRegistryTest {
|
|||
meter = (SdkMeter) meterProvider.get("", "");
|
||||
assertThat(meter.getInstrumentationLibraryInfo().getName())
|
||||
.isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME);
|
||||
|
||||
meter = (SdkMeter) meterProvider.meterBuilder("").build();
|
||||
assertThat(meter.getInstrumentationLibraryInfo().getName())
|
||||
.isEqualTo(SdkMeterProvider.DEFAULT_METER_NAME);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.sdk.trace;
|
||||
|
||||
import io.opentelemetry.api.trace.Tracer;
|
||||
import io.opentelemetry.api.trace.TracerBuilder;
|
||||
import io.opentelemetry.sdk.internal.ComponentRegistry;
|
||||
|
||||
class SdkTracerBuilder implements TracerBuilder {
|
||||
|
||||
private final ComponentRegistry<SdkTracer> registry;
|
||||
private final String instrumentationName;
|
||||
private String instrumentationVersion;
|
||||
private String schemaUrl;
|
||||
|
||||
SdkTracerBuilder(ComponentRegistry<SdkTracer> registry, String instrumentationName) {
|
||||
this.registry = registry;
|
||||
this.instrumentationName = instrumentationName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TracerBuilder setSchemaUrl(String schemaUrl) {
|
||||
this.schemaUrl = schemaUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TracerBuilder setInstrumentationVersion(String instrumentationVersion) {
|
||||
this.instrumentationVersion = instrumentationVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tracer build() {
|
||||
return registry.get(instrumentationName, instrumentationVersion, schemaUrl);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.sdk.trace;
|
|||
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.api.trace.Tracer;
|
||||
import io.opentelemetry.api.trace.TracerBuilder;
|
||||
import io.opentelemetry.api.trace.TracerProvider;
|
||||
import io.opentelemetry.sdk.common.Clock;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
|
@ -60,17 +61,24 @@ public final class SdkTracerProvider implements TracerProvider, Closeable {
|
|||
|
||||
@Override
|
||||
public Tracer get(String instrumentationName) {
|
||||
return get(instrumentationName, null);
|
||||
return tracerBuilder(instrumentationName).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tracer get(String instrumentationName, @Nullable String instrumentationVersion) {
|
||||
public Tracer get(String instrumentationName, String instrumentationVersion) {
|
||||
return tracerBuilder(instrumentationName)
|
||||
.setInstrumentationVersion(instrumentationVersion)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TracerBuilder tracerBuilder(@Nullable String instrumentationName) {
|
||||
// Per the spec, both null and empty are "invalid" and a default value should be used.
|
||||
if (instrumentationName == null || instrumentationName.isEmpty()) {
|
||||
logger.fine("Tracer requested without instrumentation name.");
|
||||
instrumentationName = DEFAULT_TRACER_NAME;
|
||||
}
|
||||
return tracerSdkComponentRegistry.get(instrumentationName, instrumentationVersion);
|
||||
return new SdkTracerBuilder(tracerSdkComponentRegistry, instrumentationName);
|
||||
}
|
||||
|
||||
/** Returns the {@link SpanLimits} that are currently applied to created spans. */
|
||||
|
|
|
@ -957,7 +957,7 @@ class SdkSpanBuilderTest {
|
|||
+ "telemetry.sdk.language=\"java\", telemetry.sdk.name=\"opentelemetry\", "
|
||||
+ "telemetry.sdk.version=\"\\d+.\\d+.\\d+(-SNAPSHOT)?\"}}, "
|
||||
+ "instrumentationLibraryInfo=InstrumentationLibraryInfo\\{"
|
||||
+ "name=SpanBuilderSdkTest, version=null}, "
|
||||
+ "name=SpanBuilderSdkTest, version=null, schemaUrl=null}, "
|
||||
+ "name=span_name, "
|
||||
+ "kind=INTERNAL, "
|
||||
+ "startEpochNanos=[0-9]+, "
|
||||
|
|
|
@ -139,19 +139,44 @@ class SdkTracerProviderTest {
|
|||
@Test
|
||||
void getSameInstanceForSameName_WithoutVersion() {
|
||||
assertThat(tracerFactory.get("test")).isSameAs(tracerFactory.get("test"));
|
||||
assertThat(tracerFactory.get("test")).isSameAs(tracerFactory.get("test", null));
|
||||
assertThat(tracerFactory.get("test"))
|
||||
.isSameAs(tracerFactory.get("test", null))
|
||||
.isSameAs(tracerFactory.tracerBuilder("test").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSameInstanceForSameName_WithVersion() {
|
||||
assertThat(tracerFactory.get("test", "version")).isSameAs(tracerFactory.get("test", "version"));
|
||||
assertThat(tracerFactory.get("test", "version"))
|
||||
.isSameAs(tracerFactory.get("test", "version"))
|
||||
.isSameAs(tracerFactory.tracerBuilder("test").setInstrumentationVersion("version").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSameInstanceForSameName_WithVersionAndSchema() {
|
||||
assertThat(
|
||||
tracerFactory
|
||||
.tracerBuilder("test")
|
||||
.setInstrumentationVersion("version")
|
||||
.setSchemaUrl("http://url")
|
||||
.build())
|
||||
.isSameAs(
|
||||
tracerFactory
|
||||
.tracerBuilder("test")
|
||||
.setInstrumentationVersion("version")
|
||||
.setSchemaUrl("http://url")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void propagatesInstrumentationLibraryInfoToTracer() {
|
||||
InstrumentationLibraryInfo expected =
|
||||
InstrumentationLibraryInfo.create("theName", "theVersion");
|
||||
Tracer tracer = tracerFactory.get(expected.getName(), expected.getVersion());
|
||||
InstrumentationLibraryInfo.create("theName", "theVersion", "http://url");
|
||||
Tracer tracer =
|
||||
tracerFactory
|
||||
.tracerBuilder(expected.getName())
|
||||
.setInstrumentationVersion(expected.getVersion())
|
||||
.setSchemaUrl(expected.getSchemaUrl())
|
||||
.build();
|
||||
assertThat(((SdkTracer) tracer).getInstrumentationLibraryInfo()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,14 +19,7 @@ import io.opentelemetry.sdk.trace.export.SpanExporter;
|
|||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
/** Unit tests for {@link SdkTracer}. */
|
||||
// Need to suppress warnings for MustBeClosed because Android 14 does not support
|
||||
// try-with-resources.
|
||||
@SuppressWarnings("MustBeClosedChecker")
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class SdkTracerTest {
|
||||
|
||||
private static final String SPAN_NAME = "span_name";
|
||||
|
@ -35,12 +28,15 @@ class SdkTracerTest {
|
|||
private static final String INSTRUMENTATION_LIBRARY_VERSION = "0.2.0";
|
||||
private static final InstrumentationLibraryInfo instrumentationLibraryInfo =
|
||||
InstrumentationLibraryInfo.create(
|
||||
INSTRUMENTATION_LIBRARY_NAME, INSTRUMENTATION_LIBRARY_VERSION);
|
||||
INSTRUMENTATION_LIBRARY_NAME, INSTRUMENTATION_LIBRARY_VERSION, "http://schemaurl");
|
||||
private final SdkTracer tracer =
|
||||
(SdkTracer)
|
||||
SdkTracerProvider.builder()
|
||||
.build()
|
||||
.get(INSTRUMENTATION_LIBRARY_NAME, INSTRUMENTATION_LIBRARY_VERSION);
|
||||
.tracerBuilder(INSTRUMENTATION_LIBRARY_NAME)
|
||||
.setInstrumentationVersion(INSTRUMENTATION_LIBRARY_VERSION)
|
||||
.setSchemaUrl("http://schemaurl")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void defaultSpanBuilder() {
|
||||
|
|
Loading…
Reference in New Issue