Add SdkMeterProvider toString method (#4464)
* Add SdkMeterProvider toString method * Fix build * Ignore null values in InstrumentSelector / View #toString()
This commit is contained in:
parent
0d234f56c9
commit
078d55abe5
|
@ -1,2 +1,13 @@
|
|||
Comparing source compatibility of against
|
||||
No changes.
|
||||
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.export.PeriodicMetricReader (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) java.lang.String toString()
|
||||
*** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.InstrumentSelector (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) FINAL(+) java.lang.String toString()
|
||||
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProvider (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) java.lang.String toString()
|
||||
*** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.View (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) FINAL(+) java.lang.String toString()
|
||||
|
|
|
@ -147,6 +147,11 @@ public final class PrometheusHttpServer implements Closeable, MetricReader {
|
|||
shutdown().join(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PrometheusHttpServer{address=" + server.getAddress() + "}";
|
||||
}
|
||||
|
||||
// Visible for testing.
|
||||
InetSocketAddress getAddress() {
|
||||
return server.getAddress();
|
||||
|
|
|
@ -163,6 +163,12 @@ class PrometheusHttpServerTest {
|
|||
assertThat(response.contentUtf8()).isEqualTo("Exporter is Healthy.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringRepresentation() {
|
||||
assertThat(prometheusServer.toString())
|
||||
.isEqualTo("PrometheusHttpServer{address=" + prometheusServer.getAddress() + "}");
|
||||
}
|
||||
|
||||
private static ImmutableList<MetricData> generateTestData() {
|
||||
return ImmutableList.of(
|
||||
ImmutableMetricData.createLongSum(
|
||||
|
|
|
@ -76,8 +76,13 @@ public final class OpenTelemetrySdk implements OpenTelemetry {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
// TODO(anuraaga): Add metrics / logs / propagators
|
||||
return "OpenTelemetrySdk{" + "tracerProvider=" + tracerProvider.unobfuscate() + '}';
|
||||
// TODO(anuraaga): Add logs / propagators
|
||||
return "OpenTelemetrySdk{"
|
||||
+ "tracerProvider="
|
||||
+ tracerProvider.unobfuscate()
|
||||
+ ", meterProvider="
|
||||
+ meterProvider.unobfuscate()
|
||||
+ "}";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,13 +14,17 @@ import static org.mockito.Mockito.when;
|
|||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.trace.TracerProvider;
|
||||
import io.opentelemetry.context.propagation.ContextPropagators;
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator;
|
||||
import io.opentelemetry.sdk.common.Clock;
|
||||
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
|
||||
import io.opentelemetry.sdk.metrics.Aggregation;
|
||||
import io.opentelemetry.sdk.metrics.InstrumentSelector;
|
||||
import io.opentelemetry.sdk.metrics.InstrumentType;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import io.opentelemetry.sdk.metrics.View;
|
||||
import io.opentelemetry.sdk.metrics.export.MetricExporter;
|
||||
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.sdk.trace.IdGenerator;
|
||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
||||
|
@ -28,6 +32,7 @@ import io.opentelemetry.sdk.trace.SpanLimits;
|
|||
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
|
||||
import io.opentelemetry.sdk.trace.export.SpanExporter;
|
||||
import io.opentelemetry.sdk.trace.samplers.Sampler;
|
||||
import java.time.Duration;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
@ -41,7 +46,6 @@ class OpenTelemetrySdkTest {
|
|||
@Mock private SdkMeterProvider meterProvider;
|
||||
@Mock private SdkLogEmitterProvider logEmitterProvider;
|
||||
@Mock private ContextPropagators propagators;
|
||||
@Mock private Clock clock;
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
|
@ -49,7 +53,7 @@ class OpenTelemetrySdkTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testRegisterGlobal() {
|
||||
void buildAndRegisterGlobal() {
|
||||
OpenTelemetrySdk sdk =
|
||||
OpenTelemetrySdk.builder().setPropagators(propagators).buildAndRegisterGlobal();
|
||||
assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(sdk);
|
||||
|
@ -67,7 +71,7 @@ class OpenTelemetrySdkTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void castingGlobalToSdkFails() {
|
||||
void buildAndRegisterGlobal_castingGlobalToSdkFails() {
|
||||
OpenTelemetrySdk.builder().buildAndRegisterGlobal();
|
||||
|
||||
assertThatThrownBy(
|
||||
|
@ -79,40 +83,7 @@ class OpenTelemetrySdkTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testShortcutVersions() {
|
||||
assertThat(GlobalOpenTelemetry.getTracer("testTracer1"))
|
||||
.isSameAs(GlobalOpenTelemetry.getTracerProvider().get("testTracer1"));
|
||||
assertThat(GlobalOpenTelemetry.getTracer("testTracer2", "testVersion"))
|
||||
.isSameAs(GlobalOpenTelemetry.getTracerProvider().get("testTracer2", "testVersion"));
|
||||
assertThat(
|
||||
GlobalOpenTelemetry.tracerBuilder("testTracer2")
|
||||
.setInstrumentationVersion("testVersion")
|
||||
.setSchemaUrl("https://example.invalid")
|
||||
.build())
|
||||
.isSameAs(
|
||||
GlobalOpenTelemetry.getTracerProvider()
|
||||
.tracerBuilder("testTracer2")
|
||||
.setInstrumentationVersion("testVersion")
|
||||
.setSchemaUrl("https://example.invalid")
|
||||
.build());
|
||||
|
||||
assertThat(GlobalOpenTelemetry.getMeter("testMeter1"))
|
||||
.isSameAs(GlobalOpenTelemetry.getMeterProvider().get("testMeter1"));
|
||||
assertThat(
|
||||
GlobalOpenTelemetry.meterBuilder("testMeter2")
|
||||
.setInstrumentationVersion("testVersion")
|
||||
.setSchemaUrl("https://example.invalid")
|
||||
.build())
|
||||
.isSameAs(
|
||||
GlobalOpenTelemetry.getMeterProvider()
|
||||
.meterBuilder("testMeter2")
|
||||
.setInstrumentationVersion("testVersion")
|
||||
.setSchemaUrl("https://example.invalid")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuilderDefaults() {
|
||||
void builderDefaults() {
|
||||
OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder().build();
|
||||
assertThat(openTelemetry.getTracerProvider())
|
||||
.isInstanceOfSatisfying(
|
||||
|
@ -129,7 +100,7 @@ class OpenTelemetrySdkTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void building() {
|
||||
void builder() {
|
||||
OpenTelemetrySdk openTelemetry =
|
||||
OpenTelemetrySdk.builder()
|
||||
.setTracerProvider(tracerProvider)
|
||||
|
@ -151,54 +122,40 @@ class OpenTelemetrySdkTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testConfiguration_tracerSettings() {
|
||||
Resource resource = Resource.create(Attributes.builder().put("cat", "meow").build());
|
||||
IdGenerator idGenerator = mock(IdGenerator.class);
|
||||
SpanLimits spanLimits = SpanLimits.getDefault();
|
||||
OpenTelemetrySdk openTelemetry =
|
||||
OpenTelemetrySdk.builder()
|
||||
.setTracerProvider(
|
||||
SdkTracerProvider.builder()
|
||||
.setClock(clock)
|
||||
.setResource(resource)
|
||||
.setIdGenerator(idGenerator)
|
||||
.setSpanLimits(spanLimits)
|
||||
.build())
|
||||
.build();
|
||||
TracerProvider unobfuscatedTracerProvider =
|
||||
((OpenTelemetrySdk.ObfuscatedTracerProvider) openTelemetry.getTracerProvider())
|
||||
.unobfuscate();
|
||||
|
||||
assertThat(unobfuscatedTracerProvider)
|
||||
.isInstanceOfSatisfying(
|
||||
SdkTracerProvider.class,
|
||||
sdkTracerProvider ->
|
||||
assertThat(sdkTracerProvider.getSpanLimits()).isEqualTo(spanLimits));
|
||||
// Since TracerProvider is in a different package, the only alternative to this reflective
|
||||
// approach would be to make the fields public for testing which is worse than this.
|
||||
assertThat(unobfuscatedTracerProvider)
|
||||
.extracting("sharedState")
|
||||
.hasFieldOrPropertyWithValue("clock", clock)
|
||||
.hasFieldOrPropertyWithValue("resource", resource)
|
||||
.hasFieldOrPropertyWithValue("idGenerator", idGenerator);
|
||||
void getTracer() {
|
||||
assertThat(GlobalOpenTelemetry.getTracer("testTracer1"))
|
||||
.isSameAs(GlobalOpenTelemetry.getTracerProvider().get("testTracer1"));
|
||||
assertThat(GlobalOpenTelemetry.getTracer("testTracer2", "testVersion"))
|
||||
.isSameAs(GlobalOpenTelemetry.getTracerProvider().get("testTracer2", "testVersion"));
|
||||
assertThat(
|
||||
GlobalOpenTelemetry.tracerBuilder("testTracer2")
|
||||
.setInstrumentationVersion("testVersion")
|
||||
.setSchemaUrl("https://example.invalid")
|
||||
.build())
|
||||
.isSameAs(
|
||||
GlobalOpenTelemetry.getTracerProvider()
|
||||
.tracerBuilder("testTracer2")
|
||||
.setInstrumentationVersion("testVersion")
|
||||
.setSchemaUrl("https://example.invalid")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTracerBuilder() {
|
||||
void tracerBuilder() {
|
||||
OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder().build();
|
||||
assertThat(openTelemetry.tracerBuilder("instr"))
|
||||
.isNotSameAs(OpenTelemetry.noop().tracerBuilder("instr"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTracerBuilderViaProvider() {
|
||||
void tracerBuilder_ViaProvider() {
|
||||
OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder().build();
|
||||
assertThat(openTelemetry.getTracerProvider().tracerBuilder("instr"))
|
||||
.isNotSameAs(OpenTelemetry.noop().tracerBuilder("instr"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTracerProviderAccess() {
|
||||
void getTracerProvider() {
|
||||
OpenTelemetrySdk openTelemetry =
|
||||
OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).build();
|
||||
assertThat(openTelemetry.getTracerProvider())
|
||||
|
@ -210,7 +167,50 @@ class OpenTelemetrySdkTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testMeterProviderAccess() {
|
||||
void getMeter() {
|
||||
assertThat(GlobalOpenTelemetry.getMeter("testMeter1"))
|
||||
.isSameAs(GlobalOpenTelemetry.getMeterProvider().get("testMeter1"));
|
||||
assertThat(
|
||||
GlobalOpenTelemetry.meterBuilder("testMeter2")
|
||||
.setInstrumentationVersion("testVersion")
|
||||
.setSchemaUrl("https://example.invalid")
|
||||
.build())
|
||||
.isSameAs(
|
||||
GlobalOpenTelemetry.getMeterProvider()
|
||||
.meterBuilder("testMeter2")
|
||||
.setInstrumentationVersion("testVersion")
|
||||
.setSchemaUrl("https://example.invalid")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void meterBuilder() {
|
||||
OpenTelemetrySdk openTelemetry =
|
||||
OpenTelemetrySdk.builder()
|
||||
.setMeterProvider(
|
||||
SdkMeterProvider.builder()
|
||||
.registerMetricReader(PeriodicMetricReader.create(mock(MetricExporter.class)))
|
||||
.build())
|
||||
.build();
|
||||
assertThat(openTelemetry.meterBuilder("instr"))
|
||||
.isNotSameAs(OpenTelemetry.noop().meterBuilder("instr"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void meterBuilder_ViaProvider() {
|
||||
OpenTelemetrySdk openTelemetry =
|
||||
OpenTelemetrySdk.builder()
|
||||
.setMeterProvider(
|
||||
SdkMeterProvider.builder()
|
||||
.registerMetricReader(PeriodicMetricReader.create(mock(MetricExporter.class)))
|
||||
.build())
|
||||
.build();
|
||||
assertThat(openTelemetry.getMeterProvider().meterBuilder("instr"))
|
||||
.isNotSameAs(OpenTelemetry.noop().meterBuilder("instr"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMeterProvider() {
|
||||
OpenTelemetrySdk openTelemetry =
|
||||
OpenTelemetrySdk.builder().setMeterProvider(meterProvider).build();
|
||||
assertThat(openTelemetry.getMeterProvider())
|
||||
|
@ -225,22 +225,35 @@ class OpenTelemetrySdkTest {
|
|||
// Demonstrates how clear or confusing is SDK configuration
|
||||
@Test
|
||||
void fullOpenTelemetrySdkConfigurationDemo() {
|
||||
SpanLimits newConfig = SpanLimits.builder().setMaxNumberOfAttributes(512).build();
|
||||
|
||||
OpenTelemetrySdkBuilder sdkBuilder =
|
||||
OpenTelemetrySdk.builder()
|
||||
.setTracerProvider(
|
||||
SdkTracerProvider.builder()
|
||||
.setSampler(mock(Sampler.class))
|
||||
.addSpanProcessor(SimpleSpanProcessor.create(mock(SpanExporter.class)))
|
||||
.addSpanProcessor(SimpleSpanProcessor.create(mock(SpanExporter.class)))
|
||||
.setClock(mock(Clock.class))
|
||||
.setIdGenerator(mock(IdGenerator.class))
|
||||
.setResource(Resource.empty())
|
||||
.setSpanLimits(newConfig)
|
||||
.build());
|
||||
|
||||
sdkBuilder.build();
|
||||
OpenTelemetrySdk.builder()
|
||||
.setMeterProvider(
|
||||
SdkMeterProvider.builder()
|
||||
.setResource(Resource.empty())
|
||||
.setClock(mock(Clock.class))
|
||||
.registerMetricReader(
|
||||
PeriodicMetricReader.builder(mock(MetricExporter.class))
|
||||
.setInterval(Duration.ofSeconds(10))
|
||||
.build())
|
||||
.registerMetricReader(PeriodicMetricReader.create(mock(MetricExporter.class)))
|
||||
.registerView(
|
||||
InstrumentSelector.builder().setName("name").build(),
|
||||
View.builder().setName("new-name").build())
|
||||
.registerView(
|
||||
InstrumentSelector.builder().setType(InstrumentType.COUNTER).build(),
|
||||
View.builder().setAttributeFilter(key -> key.equals("foo")).build())
|
||||
.build())
|
||||
.setTracerProvider(
|
||||
SdkTracerProvider.builder()
|
||||
.setSampler(mock(Sampler.class))
|
||||
.addSpanProcessor(SimpleSpanProcessor.create(mock(SpanExporter.class)))
|
||||
.addSpanProcessor(SimpleSpanProcessor.create(mock(SpanExporter.class)))
|
||||
.setClock(mock(Clock.class))
|
||||
.setIdGenerator(mock(IdGenerator.class))
|
||||
.setResource(Resource.empty())
|
||||
.setSpanLimits(SpanLimits.builder().setMaxNumberOfAttributes(512).build())
|
||||
.build())
|
||||
.setPropagators(ContextPropagators.create(mock(TextMapPropagator.class)))
|
||||
.build();
|
||||
}
|
||||
|
||||
// This is just a demonstration of the bare minimal required configuration in order to get useful
|
||||
|
@ -249,6 +262,10 @@ class OpenTelemetrySdkTest {
|
|||
@Test
|
||||
void trivialOpenTelemetrySdkConfigurationDemo() {
|
||||
OpenTelemetrySdk.builder()
|
||||
.setMeterProvider(
|
||||
SdkMeterProvider.builder()
|
||||
.registerMetricReader(PeriodicMetricReader.create(mock(MetricExporter.class)))
|
||||
.build())
|
||||
.setTracerProvider(
|
||||
SdkTracerProvider.builder()
|
||||
.addSpanProcessor(SimpleSpanProcessor.create(mock(SpanExporter.class)))
|
||||
|
@ -262,6 +279,10 @@ class OpenTelemetrySdkTest {
|
|||
@Test
|
||||
void minimalOpenTelemetrySdkConfigurationDemo() {
|
||||
OpenTelemetrySdk.builder()
|
||||
.setMeterProvider(
|
||||
SdkMeterProvider.builder()
|
||||
.registerMetricReader(PeriodicMetricReader.create(mock(MetricExporter.class)))
|
||||
.build())
|
||||
.setTracerProvider(
|
||||
SdkTracerProvider.builder()
|
||||
.addSpanProcessor(SimpleSpanProcessor.create(mock(SpanExporter.class)))
|
||||
|
@ -271,6 +292,13 @@ class OpenTelemetrySdkTest {
|
|||
.build();
|
||||
|
||||
OpenTelemetrySdk.builder()
|
||||
.setMeterProvider(
|
||||
SdkMeterProvider.builder()
|
||||
.registerMetricReader(PeriodicMetricReader.create(mock(MetricExporter.class)))
|
||||
.registerView(
|
||||
InstrumentSelector.builder().setType(InstrumentType.COUNTER).build(),
|
||||
View.builder().setAggregation(Aggregation.explicitBucketHistogram()).build())
|
||||
.build())
|
||||
.setTracerProvider(
|
||||
SdkTracerProvider.builder()
|
||||
.addSpanProcessor(SimpleSpanProcessor.create(mock(SpanExporter.class)))
|
||||
|
@ -283,8 +311,10 @@ class OpenTelemetrySdkTest {
|
|||
|
||||
@Test
|
||||
void stringRepresentation() {
|
||||
SpanExporter exporter = mock(SpanExporter.class);
|
||||
when(exporter.toString()).thenReturn("MockSpanExporter{}");
|
||||
SpanExporter spanExporter = mock(SpanExporter.class);
|
||||
when(spanExporter.toString()).thenReturn("MockSpanExporter{}");
|
||||
MetricExporter metricExporter = mock(MetricExporter.class);
|
||||
when(metricExporter.toString()).thenReturn("MockMetricExporter{}");
|
||||
Resource resource =
|
||||
Resource.builder().put(AttributeKey.stringKey("service.name"), "otel-test").build();
|
||||
OpenTelemetrySdk sdk =
|
||||
|
@ -293,7 +323,16 @@ class OpenTelemetrySdkTest {
|
|||
SdkTracerProvider.builder()
|
||||
.setResource(resource)
|
||||
.addSpanProcessor(
|
||||
SimpleSpanProcessor.create(SpanExporter.composite(exporter, exporter)))
|
||||
SimpleSpanProcessor.create(
|
||||
SpanExporter.composite(spanExporter, spanExporter)))
|
||||
.build())
|
||||
.setMeterProvider(
|
||||
SdkMeterProvider.builder()
|
||||
.setResource(resource)
|
||||
.registerMetricReader(PeriodicMetricReader.create(metricExporter))
|
||||
.registerView(
|
||||
InstrumentSelector.builder().setName("instrument").build(),
|
||||
View.builder().setName("new-instrument").build())
|
||||
.build())
|
||||
.build();
|
||||
|
||||
|
@ -306,6 +345,14 @@ class OpenTelemetrySdkTest {
|
|||
+ "resource=Resource{schemaUrl=null, attributes={service.name=\"otel-test\"}}, "
|
||||
+ "spanLimitsSupplier=SpanLimitsValue{maxNumberOfAttributes=128, maxNumberOfEvents=128, maxNumberOfLinks=128, maxNumberOfAttributesPerEvent=128, maxNumberOfAttributesPerLink=128, maxAttributeValueLength=2147483647}, "
|
||||
+ "sampler=ParentBased{root:AlwaysOnSampler,remoteParentSampled:AlwaysOnSampler,remoteParentNotSampled:AlwaysOffSampler,localParentSampled:AlwaysOnSampler,localParentNotSampled:AlwaysOffSampler}, "
|
||||
+ "spanProcessor=SimpleSpanProcessor{spanExporter=MultiSpanExporter{spanExporters=[MockSpanExporter{}, MockSpanExporter{}]}}}}");
|
||||
+ "spanProcessor=SimpleSpanProcessor{spanExporter=MultiSpanExporter{spanExporters=[MockSpanExporter{}, MockSpanExporter{}]}}"
|
||||
+ "}, "
|
||||
+ "meterProvider=SdkMeterProvider{"
|
||||
+ "clock=SystemClock{}, "
|
||||
+ "resource=Resource{schemaUrl=null, attributes={service.name=\"otel-test\"}}, "
|
||||
+ "metricReaders=[PeriodicMetricReader{exporter=MockMetricExporter{}, intervalNanos=60000000000}], "
|
||||
+ "views=[RegisteredView{instrumentSelector=InstrumentSelector{instrumentName=instrument}, view=View{name=new-instrument, aggregation=DefaultAggregation, attributesProcessor=NoopAttributesProcessor{}}}]"
|
||||
+ "}"
|
||||
+ "}");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.opentelemetry.sdk.metrics;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import java.util.StringJoiner;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
|
@ -75,4 +76,25 @@ public abstract class InstrumentSelector {
|
|||
*/
|
||||
@Nullable
|
||||
public abstract String getMeterSchemaUrl();
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringJoiner joiner = new StringJoiner(", ", "InstrumentSelector{", "}");
|
||||
if (getInstrumentType() != null) {
|
||||
joiner.add("instrumentType=" + getInstrumentType());
|
||||
}
|
||||
if (getInstrumentName() != null) {
|
||||
joiner.add("instrumentName=" + getInstrumentName());
|
||||
}
|
||||
if (getMeterName() != null) {
|
||||
joiner.add("meterName=" + getMeterName());
|
||||
}
|
||||
if (getMeterVersion() != null) {
|
||||
joiner.add("meterVersion=" + getMeterVersion());
|
||||
}
|
||||
if (getMeterSchemaUrl() != null) {
|
||||
joiner.add("meterSchemaUrl=" + getMeterSchemaUrl());
|
||||
}
|
||||
return joiner.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ public final class SdkMeterProvider implements MeterProvider, Closeable {
|
|||
private static final Logger LOGGER = Logger.getLogger(SdkMeterProvider.class.getName());
|
||||
static final String DEFAULT_METER_NAME = "unknown";
|
||||
|
||||
private final List<MetricReader> metricReaders;
|
||||
private final ComponentRegistry<SdkMeter> registry;
|
||||
private final MeterProviderSharedState sharedState;
|
||||
private final Map<CollectionHandle, CollectionInfo> collectionInfoMap;
|
||||
|
@ -62,6 +63,7 @@ public final class SdkMeterProvider implements MeterProvider, Closeable {
|
|||
ViewRegistry viewRegistry,
|
||||
ExemplarFilter exemplarFilter,
|
||||
long minimumCollectionIntervalNanos) {
|
||||
this.metricReaders = metricReaders;
|
||||
this.sharedState =
|
||||
MeterProviderSharedState.create(clock, resource, viewRegistry, exemplarFilter);
|
||||
this.registry =
|
||||
|
@ -142,6 +144,20 @@ public final class SdkMeterProvider implements MeterProvider, Closeable {
|
|||
shutdown().join(10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SdkMeterProvider{"
|
||||
+ "clock="
|
||||
+ sharedState.getClock()
|
||||
+ ", resource="
|
||||
+ sharedState.getResource()
|
||||
+ ", metricReaders="
|
||||
+ metricReaders
|
||||
+ ", views="
|
||||
+ sharedState.getViewRegistry().getViews()
|
||||
+ "}";
|
||||
}
|
||||
|
||||
/** Helper class to expose registered metric exports. */
|
||||
private class LeasedMetricProducer implements MetricProducer {
|
||||
private final CollectionHandle handle;
|
||||
|
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.sdk.metrics;
|
|||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import io.opentelemetry.sdk.metrics.internal.view.AttributesProcessor;
|
||||
import java.util.StringJoiner;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
|
@ -47,4 +48,18 @@ public abstract class View {
|
|||
|
||||
/** The attribute processor used for this view. */
|
||||
abstract AttributesProcessor getAttributesProcessor();
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringJoiner joiner = new StringJoiner(", ", "View{", "}");
|
||||
if (getName() != null) {
|
||||
joiner.add("name=" + getName());
|
||||
}
|
||||
if (getDescription() != null) {
|
||||
joiner.add("description=" + getDescription());
|
||||
}
|
||||
joiner.add("aggregation=" + getAggregation());
|
||||
joiner.add("attributesProcessor=" + getAttributesProcessor());
|
||||
return joiner.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,16 @@ public final class PeriodicMetricReader implements MetricReader {
|
|||
start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PeriodicMetricReader{"
|
||||
+ "exporter="
|
||||
+ exporter
|
||||
+ ", intervalNanos="
|
||||
+ intervalNanos
|
||||
+ '}';
|
||||
}
|
||||
|
||||
void start() {
|
||||
synchronized (lock) {
|
||||
if (scheduledFuture != null) {
|
||||
|
|
|
@ -33,10 +33,10 @@ public abstract class MeterProviderSharedState {
|
|||
public abstract Clock getClock();
|
||||
|
||||
/** Returns the {@link Resource} to attach telemetry to. */
|
||||
abstract Resource getResource();
|
||||
public abstract Resource getResource();
|
||||
|
||||
/** Returns the {@link ViewRegistry} for custom aggregation and metric definitions. */
|
||||
abstract ViewRegistry getViewRegistry();
|
||||
public abstract ViewRegistry getViewRegistry();
|
||||
|
||||
/**
|
||||
* Returns the timestamp when this {@code MeterProvider} was started, in nanoseconds since Unix
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package io.opentelemetry.sdk.metrics.internal.view;
|
||||
|
||||
import static io.opentelemetry.sdk.metrics.internal.view.NoopAttributesProcessor.NOOP;
|
||||
|
||||
import io.opentelemetry.api.baggage.Baggage;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.common.AttributesBuilder;
|
||||
|
@ -27,7 +29,8 @@ import javax.annotation.concurrent.Immutable;
|
|||
*/
|
||||
@Immutable
|
||||
public abstract class AttributesProcessor {
|
||||
private AttributesProcessor() {}
|
||||
|
||||
AttributesProcessor() {}
|
||||
|
||||
/**
|
||||
* Manipulates a set of attributes, returning the desired set.
|
||||
|
@ -142,8 +145,6 @@ public abstract class AttributesProcessor {
|
|||
};
|
||||
}
|
||||
|
||||
static final AttributesProcessor NOOP = simple(incoming -> incoming);
|
||||
|
||||
/** A {@link AttributesProcessor} that runs a sequence of processors. */
|
||||
@Immutable
|
||||
static final class JoinedAttributesProcessor extends AttributesProcessor {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.sdk.metrics.internal.view;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.context.Context;
|
||||
|
||||
class NoopAttributesProcessor extends AttributesProcessor {
|
||||
|
||||
static final NoopAttributesProcessor NOOP = new NoopAttributesProcessor();
|
||||
|
||||
private NoopAttributesProcessor() {}
|
||||
|
||||
@Override
|
||||
public Attributes process(Attributes incoming, Context context) {
|
||||
return incoming;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesContext() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NoopAttributesProcessor{}";
|
||||
}
|
||||
}
|
|
@ -42,4 +42,14 @@ public abstract class RegisteredView {
|
|||
|
||||
/** The {@link SourceInfo} from where the view was registered. */
|
||||
public abstract SourceInfo getViewSourceInfo();
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return "RegisteredView{"
|
||||
+ "instrumentSelector="
|
||||
+ getInstrumentSelector()
|
||||
+ ", view="
|
||||
+ getView()
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package io.opentelemetry.sdk.metrics.internal.view;
|
||||
|
||||
import static io.opentelemetry.sdk.metrics.internal.view.NoopAttributesProcessor.NOOP;
|
||||
|
||||
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
|
||||
import io.opentelemetry.sdk.metrics.InstrumentSelector;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
|
||||
|
@ -36,7 +38,7 @@ public final class ViewRegistry {
|
|||
RegisteredView.create(
|
||||
InstrumentSelector.builder().setName("*").build(),
|
||||
DEFAULT_VIEW,
|
||||
AttributesProcessor.NOOP,
|
||||
NOOP,
|
||||
SourceInfo.noSourceInfo());
|
||||
private static final Logger logger = Logger.getLogger(ViewRegistry.class.getName());
|
||||
|
||||
|
@ -51,6 +53,11 @@ public final class ViewRegistry {
|
|||
return new ViewRegistryBuilder();
|
||||
}
|
||||
|
||||
/** Return a list of all registered views. */
|
||||
public List<RegisteredView> getViews() {
|
||||
return new ArrayList<>(reverseRegistration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the metric {@link View} for a given instrument.
|
||||
*
|
||||
|
|
|
@ -74,4 +74,27 @@ class InstrumentSelectorTest {
|
|||
.build();
|
||||
assertThat(selector.getMeterSchemaUrl()).isEqualTo("http://bar.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringRepresentation() {
|
||||
assertThat(InstrumentSelector.builder().setName("name").build().toString())
|
||||
.isEqualTo("InstrumentSelector{instrumentName=name}");
|
||||
assertThat(
|
||||
InstrumentSelector.builder()
|
||||
.setType(InstrumentType.COUNTER)
|
||||
.setName("name")
|
||||
.setMeterName("meter")
|
||||
.setMeterVersion("version")
|
||||
.setMeterSchemaUrl("http://url.com")
|
||||
.build()
|
||||
.toString())
|
||||
.isEqualTo(
|
||||
"InstrumentSelector{"
|
||||
+ "instrumentType=COUNTER, "
|
||||
+ "instrumentName=name, "
|
||||
+ "meterName=meter, "
|
||||
+ "meterVersion=version, "
|
||||
+ "meterSchemaUrl=http://url.com"
|
||||
+ "}");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.sdk.metrics;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ViewTest {
|
||||
|
||||
@Test
|
||||
void stringRepresentation() {
|
||||
assertThat(View.builder().build().toString())
|
||||
.isEqualTo(
|
||||
"View{aggregation=DefaultAggregation, attributesProcessor=NoopAttributesProcessor{}}");
|
||||
assertThat(
|
||||
View.builder()
|
||||
.setName("name")
|
||||
.setDescription("description")
|
||||
.setAggregation(Aggregation.sum())
|
||||
.build()
|
||||
.toString())
|
||||
.isEqualTo(
|
||||
"View{"
|
||||
+ "name=name, "
|
||||
+ "description=description, "
|
||||
+ "aggregation=SumAggregation, "
|
||||
+ "attributesProcessor=NoopAttributesProcessor{}"
|
||||
+ "}");
|
||||
}
|
||||
}
|
|
@ -208,6 +208,21 @@ class PeriodicMetricReaderTest {
|
|||
.hasMessage("executor");
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringRepresentation() {
|
||||
when(metricExporter.toString()).thenReturn("MockMetricExporter{}");
|
||||
assertThat(
|
||||
PeriodicMetricReader.builder(metricExporter)
|
||||
.setInterval(Duration.ofSeconds(1))
|
||||
.build()
|
||||
.toString())
|
||||
.isEqualTo(
|
||||
"PeriodicMetricReader{"
|
||||
+ "exporter=MockMetricExporter{}, "
|
||||
+ "intervalNanos=1000000000"
|
||||
+ "}");
|
||||
}
|
||||
|
||||
private static class WaitingMetricExporter implements MetricExporter {
|
||||
|
||||
private final AtomicBoolean hasShutdown = new AtomicBoolean(false);
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.sdk.metrics.internal.view;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
import io.opentelemetry.sdk.metrics.Aggregation;
|
||||
import io.opentelemetry.sdk.metrics.InstrumentSelector;
|
||||
import io.opentelemetry.sdk.metrics.InstrumentType;
|
||||
import io.opentelemetry.sdk.metrics.View;
|
||||
import io.opentelemetry.sdk.metrics.internal.debug.SourceInfo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class RegisteredViewTest {
|
||||
|
||||
@Test
|
||||
void stringRepresentation() {
|
||||
assertThat(
|
||||
RegisteredView.create(
|
||||
InstrumentSelector.builder()
|
||||
.setName("name")
|
||||
.setType(InstrumentType.COUNTER)
|
||||
.setMeterName("meter-name")
|
||||
.setMeterVersion("meter-version")
|
||||
.setMeterSchemaUrl("meter-schema-url")
|
||||
.build(),
|
||||
View.builder()
|
||||
.setName("name")
|
||||
.setDescription("description")
|
||||
.setAggregation(Aggregation.sum())
|
||||
.build(),
|
||||
AttributesProcessor.noop(),
|
||||
SourceInfo.fromCurrentStack())
|
||||
.toString())
|
||||
.isEqualTo(
|
||||
"RegisteredView{"
|
||||
+ "instrumentSelector=InstrumentSelector{instrumentType=COUNTER, instrumentName=name, meterName=meter-name, meterVersion=meter-version, meterSchemaUrl=meter-schema-url}, "
|
||||
+ "view=View{name=name, description=description, aggregation=SumAggregation, attributesProcessor=NoopAttributesProcessor{}}"
|
||||
+ "}");
|
||||
}
|
||||
}
|
|
@ -90,4 +90,9 @@ public class InMemoryMetricReader implements MetricReader {
|
|||
isShutdown.set(true);
|
||||
return CompletableResultCode.ofSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InMemoryMetricReader{aggregationTemporality=" + aggregationTemporality + "}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,4 +89,10 @@ class InMemoryMetricReaderTest {
|
|||
assertThat(cumulativeReader.collectAllMetrics()).hasSize(0);
|
||||
assertThat(deltaReader.collectAllMetrics()).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringRepresentation() {
|
||||
assertThat(deltaReader.toString())
|
||||
.isEqualTo("InMemoryMetricReader{aggregationTemporality=DELTA}");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue