Skip to content

Commit c138953

Browse files
committed
Stabilize ExemplarFilter
1 parent a01288b commit c138953

File tree

33 files changed

+176
-134
lines changed

33 files changed

+176
-134
lines changed
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
11
Comparing source compatibility of opentelemetry-sdk-metrics-1.56.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.55.0.jar
2-
No changes.
2+
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.ExemplarFilter (not serializable)
3+
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
4+
+++ NEW SUPERCLASS: java.lang.Object
5+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.ExemplarFilter alwaysOff()
6+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.ExemplarFilter alwaysOn()
7+
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.ExemplarFilter traceBased()
8+
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder (not serializable)
9+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
10+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder setExemplarFilter(io.opentelemetry.sdk.metrics.ExemplarFilter)

integration-tests/otlp/src/main/java/io/opentelemetry/integrationtest/OtlpExporterIntegrationTest.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,10 @@
6565
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
6666
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
6767
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
68+
import io.opentelemetry.sdk.metrics.ExemplarFilter;
6869
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
69-
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
7070
import io.opentelemetry.sdk.metrics.export.MetricExporter;
7171
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
72-
import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil;
73-
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter;
7472
import io.opentelemetry.sdk.resources.Resource;
7573
import io.opentelemetry.sdk.trace.IdGenerator;
7674
import io.opentelemetry.sdk.trace.SdkTracerProvider;
@@ -461,18 +459,16 @@ void testOtlpHttpMetricExport_mtls() throws Exception {
461459
}
462460

463461
private static void testMetricExport(MetricExporter metricExporter) {
464-
SdkMeterProviderBuilder meterProviderBuilder =
462+
SdkMeterProvider meterProvider =
465463
SdkMeterProvider.builder()
466464
.setResource(RESOURCE)
467465
.registerMetricReader(
468466
PeriodicMetricReader.builder(metricExporter)
469467
.setInterval(Duration.ofSeconds(Integer.MAX_VALUE))
470-
.build());
471-
472-
// Enable alwaysOn exemplar filter, instead of default traceBased filter
473-
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOn());
474-
475-
SdkMeterProvider meterProvider = meterProviderBuilder.build();
468+
.build())
469+
// Enable alwaysOn exemplar filter, instead of default traceBased filter
470+
.setExemplarFilter(ExemplarFilter.alwaysOn())
471+
.build();
476472

477473
Meter meter = meterProvider.meterBuilder(OtlpExporterIntegrationTest.class.getName()).build();
478474

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@
99
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
1010
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
1111
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
12+
import io.opentelemetry.sdk.metrics.ExemplarFilter;
1213
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
1314
import io.opentelemetry.sdk.metrics.export.MetricExporter;
1415
import io.opentelemetry.sdk.metrics.export.MetricReader;
15-
import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil;
16-
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter;
1716
import io.opentelemetry.sdk.metrics.internal.state.MetricStorage;
1817
import java.io.Closeable;
1918
import java.util.Collections;
@@ -43,14 +42,14 @@ static void configureMeterProvider(
4342
config.getString("otel.metrics.exemplar.filter", "trace_based").toLowerCase(Locale.ROOT);
4443
switch (exemplarFilter) {
4544
case "always_off":
46-
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOff());
45+
meterProviderBuilder.setExemplarFilter(ExemplarFilter.alwaysOff());
4746
break;
4847
case "always_on":
49-
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOn());
48+
meterProviderBuilder.setExemplarFilter(ExemplarFilter.alwaysOn());
5049
break;
5150
case "trace_based":
5251
default:
53-
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.traceBased());
52+
meterProviderBuilder.setExemplarFilter(ExemplarFilter.traceBased());
5453
break;
5554
}
5655

sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
1515
import io.opentelemetry.sdk.metrics.internal.exemplar.AlwaysOffFilter;
1616
import io.opentelemetry.sdk.metrics.internal.exemplar.AlwaysOnFilter;
17-
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter;
17+
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilterInternal;
1818
import io.opentelemetry.sdk.metrics.internal.exemplar.TraceBasedExemplarFilter;
1919
import java.util.ArrayList;
2020
import java.util.Collections;
@@ -45,7 +45,8 @@ void configureMeterProvider_ConfiguresExemplarFilter() {
4545
.isInstanceOf(AlwaysOnFilter.class);
4646
}
4747

48-
private static ObjectAssert<ExemplarFilter> assertExemplarFilter(Map<String, String> config) {
48+
private static ObjectAssert<ExemplarFilterInternal> assertExemplarFilter(
49+
Map<String, String> config) {
4950
Map<String, String> configWithDefault = new HashMap<>(config);
5051
configWithDefault.put("otel.metrics.exporter", "none");
5152
SdkMeterProviderBuilder builder = SdkMeterProvider.builder();
@@ -57,6 +58,7 @@ private static ObjectAssert<ExemplarFilter> assertExemplarFilter(Map<String, Str
5758
(a, b) -> a,
5859
new ArrayList<>());
5960
return assertThat(builder)
60-
.extracting("exemplarFilter", as(InstanceOfAssertFactories.type(ExemplarFilter.class)));
61+
.extracting(
62+
"exemplarFilter", as(InstanceOfAssertFactories.type(ExemplarFilterInternal.class)));
6163
}
6264
}

sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/TestSdk.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import io.opentelemetry.api.metrics.MeterProvider;
1010
import io.opentelemetry.api.trace.Tracer;
1111
import io.opentelemetry.sdk.common.Clock;
12-
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter;
1312
import io.opentelemetry.sdk.resources.Resource;
1413
import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader;
1514
import io.opentelemetry.sdk.trace.SdkTracerProvider;

sdk/metrics/src/jmh/java/io/opentelemetry/sdk/metrics/internal/aggregator/HistogramCollectBenchmark.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@
99
import io.opentelemetry.api.metrics.DoubleHistogram;
1010
import io.opentelemetry.sdk.common.CompletableResultCode;
1111
import io.opentelemetry.sdk.metrics.Aggregation;
12+
import io.opentelemetry.sdk.metrics.ExemplarFilter;
1213
import io.opentelemetry.sdk.metrics.InstrumentType;
1314
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
14-
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
1515
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
1616
import io.opentelemetry.sdk.metrics.data.MetricData;
1717
import io.opentelemetry.sdk.metrics.export.MetricExporter;
1818
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
19-
import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil;
20-
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter;
2119
import java.time.Duration;
2220
import java.util.ArrayList;
2321
import java.util.Collection;
@@ -64,7 +62,7 @@ public static class ThreadState {
6462

6563
@Setup
6664
public void setup() {
67-
SdkMeterProviderBuilder builder =
65+
SdkMeterProvider sdkMeterProvider =
6866
SdkMeterProvider.builder()
6967
.registerMetricReader(
7068
PeriodicMetricReader.builder(
@@ -74,10 +72,11 @@ public void setup() {
7472
aggregationTemporality, aggregationGenerator.aggregation))
7573
// Effectively disable periodic reading so reading is only done on #flush()
7674
.setInterval(Duration.ofSeconds(Integer.MAX_VALUE))
77-
.build());
78-
// Disable exemplars
79-
SdkMeterProviderUtil.setExemplarFilter(builder, ExemplarFilter.alwaysOff());
80-
sdkMeterProvider = builder.build();
75+
.build())
76+
// Disable exemplars
77+
.setExemplarFilter(ExemplarFilter.alwaysOff())
78+
.build();
79+
8180
histogram = sdkMeterProvider.get("meter").histogramBuilder("histogram").build();
8281

8382
random = new Random();

sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmark.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77

88
import io.opentelemetry.api.common.Attributes;
99
import io.opentelemetry.sdk.common.export.MemoryMode;
10+
import io.opentelemetry.sdk.metrics.ExemplarFilter;
1011
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
1112
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
1213
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
1314
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
14-
import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil;
15-
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter;
1615
import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType.InstrumentTester;
1716
import io.opentelemetry.sdk.metrics.internal.state.TestInstrumentType.TestInstrumentsState;
1817
import java.time.Duration;
@@ -96,7 +95,7 @@ public void setup() {
9695
attributesList = AttributesGenerator.generate(cardinality);
9796

9897
// Disable exemplars
99-
SdkMeterProviderUtil.setExemplarFilter(builder, ExemplarFilter.alwaysOff());
98+
builder.setExemplarFilter(ExemplarFilter.alwaysOff());
10099

101100
sdkMeterProvider = builder.build();
102101
testInstrumentsState =
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.metrics;
7+
8+
import io.opentelemetry.context.Context;
9+
import io.opentelemetry.sdk.metrics.internal.exemplar.AlwaysOffFilter;
10+
import io.opentelemetry.sdk.metrics.internal.exemplar.AlwaysOnFilter;
11+
import io.opentelemetry.sdk.metrics.internal.exemplar.DoubleExemplarReservoir;
12+
import io.opentelemetry.sdk.metrics.internal.exemplar.LongExemplarReservoir;
13+
import io.opentelemetry.sdk.metrics.internal.exemplar.TraceBasedExemplarFilter;
14+
15+
/**
16+
* Exemplar filters are used to pre-filter measurements before attempting to store them in a
17+
* reservoir ({@link DoubleExemplarReservoir}, {@link LongExemplarReservoir}.
18+
*
19+
* @see SdkMeterProviderBuilder#setExemplarFilter(ExemplarFilter)
20+
*/
21+
// TODO(jack-berg): Have methods when custom filters are supported.
22+
@SuppressWarnings("InterfaceWithOnlyStatics")
23+
public interface ExemplarFilter {
24+
/**
25+
* A filter that only accepts measurements where there is a {@code Span} in {@link Context} that
26+
* is being sampled.
27+
*/
28+
static ExemplarFilter traceBased() {
29+
return TraceBasedExemplarFilter.getInstance();
30+
}
31+
32+
/** A filter which makes all measurements eligible for being an exemplar. */
33+
static ExemplarFilter alwaysOn() {
34+
return AlwaysOnFilter.getInstance();
35+
}
36+
37+
/** A filter which makes no measurements eligible for being an exemplar. */
38+
static ExemplarFilter alwaysOff() {
39+
return AlwaysOffFilter.getInstance();
40+
}
41+
}

sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import io.opentelemetry.sdk.metrics.export.MetricReader;
2222
import io.opentelemetry.sdk.metrics.internal.MeterConfig;
2323
import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil;
24-
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter;
24+
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilterInternal;
2525
import io.opentelemetry.sdk.metrics.internal.export.RegisteredReader;
2626
import io.opentelemetry.sdk.metrics.internal.state.MeterProviderSharedState;
2727
import io.opentelemetry.sdk.metrics.internal.view.RegisteredView;
@@ -67,7 +67,7 @@ public static SdkMeterProviderBuilder builder() {
6767
List<MetricProducer> metricProducers,
6868
Clock clock,
6969
Resource resource,
70-
ExemplarFilter exemplarFilter,
70+
ExemplarFilterInternal exemplarFilter,
7171
ScopeConfigurator<MeterConfig> meterConfigurator) {
7272
long startEpochNanos = clock.now();
7373
this.registeredViews = registeredViews;

sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/SdkMeterProviderBuilder.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import io.opentelemetry.sdk.metrics.internal.MeterConfig;
1616
import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil;
1717
import io.opentelemetry.sdk.metrics.internal.debug.SourceInfo;
18-
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilter;
18+
import io.opentelemetry.sdk.metrics.internal.exemplar.ExemplarFilterInternal;
1919
import io.opentelemetry.sdk.metrics.internal.view.RegisteredView;
2020
import io.opentelemetry.sdk.resources.Resource;
2121
import java.util.ArrayList;
@@ -36,15 +36,16 @@ public final class SdkMeterProviderBuilder {
3636
*
3737
* @see #setExemplarFilter(ExemplarFilter)
3838
*/
39-
private static final ExemplarFilter DEFAULT_EXEMPLAR_FILTER = ExemplarFilter.traceBased();
39+
private static final ExemplarFilterInternal DEFAULT_EXEMPLAR_FILTER =
40+
ExemplarFilterInternal.asExemplarFilterInternal(ExemplarFilter.traceBased());
4041

4142
private Clock clock = Clock.getDefault();
4243
private Resource resource = Resource.getDefault();
4344
private final IdentityHashMap<MetricReader, CardinalityLimitSelector> metricReaders =
4445
new IdentityHashMap<>();
4546
private final List<MetricProducer> metricProducers = new ArrayList<>();
4647
private final List<RegisteredView> registeredViews = new ArrayList<>();
47-
private ExemplarFilter exemplarFilter = DEFAULT_EXEMPLAR_FILTER;
48+
private ExemplarFilterInternal exemplarFilter = DEFAULT_EXEMPLAR_FILTER;
4849
private ScopeConfiguratorBuilder<MeterConfig> meterConfiguratorBuilder =
4950
MeterConfig.configuratorBuilder();
5051

@@ -80,14 +81,9 @@ public SdkMeterProviderBuilder addResource(Resource resource) {
8081
return this;
8182
}
8283

83-
/**
84-
* Assign an {@link ExemplarFilter} for all metrics created by Meters.
85-
*
86-
* <p>This method is experimental so not public. You may reflectively call it using {@link
87-
* SdkMeterProviderUtil#setExemplarFilter(SdkMeterProviderBuilder, ExemplarFilter)}.
88-
*/
89-
SdkMeterProviderBuilder setExemplarFilter(ExemplarFilter filter) {
90-
this.exemplarFilter = filter;
84+
/** Set the {@link ExemplarFilter} used for all instruments from all meters. */
85+
public SdkMeterProviderBuilder setExemplarFilter(ExemplarFilter filter) {
86+
this.exemplarFilter = ExemplarFilterInternal.asExemplarFilterInternal(filter);
9187
return this;
9288
}
9389

0 commit comments

Comments
 (0)