Add SdkMeterProvider toString method (#4464)

* Add SdkMeterProvider toString method

* Fix build

* Ignore null values in InstrumentSelector / View #toString()
This commit is contained in:
jack-berg 2022-05-13 11:52:04 -05:00 committed by GitHub
parent 0d234f56c9
commit 078d55abe5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 416 additions and 103 deletions

View File

@ -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()

View File

@ -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();

View File

@ -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(

View File

@ -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()
+ "}";
}
/**

View File

@ -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{}}}]"
+ "}"
+ "}");
}
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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) {

View File

@ -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

View File

@ -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 {

View File

@ -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{}";
}
}

View File

@ -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()
+ "}";
}
}

View File

@ -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.
*

View File

@ -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"
+ "}");
}
}

View File

@ -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{}"
+ "}");
}
}

View File

@ -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);

View File

@ -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{}}"
+ "}");
}
}

View File

@ -90,4 +90,9 @@ public class InMemoryMetricReader implements MetricReader {
isShutdown.set(true);
return CompletableResultCode.ofSuccess();
}
@Override
public String toString() {
return "InMemoryMetricReader{aggregationTemporality=" + aggregationTemporality + "}";
}
}

View File

@ -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}");
}
}