Skip to content

Commit

Permalink
Refactor for improved ergonomics
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-berg committed Apr 10, 2024
1 parent 66277f5 commit 8486a31
Show file tree
Hide file tree
Showing 24 changed files with 635 additions and 158 deletions.
21 changes: 15 additions & 6 deletions docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
Comparing source compatibility of against
+++* NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.ScopeConfig (not serializable)
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.ScopeConfigurator (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
GENERIC TEMPLATES: +++ T:java.lang.Object
+++ NEW INTERFACE: java.util.function.Function
+++ NEW SUPERCLASS: java.lang.Object
+++* NEW METHOD: PUBLIC(+) STATIC(+) java.util.function.Function<io.opentelemetry.sdk.common.InstrumentationScopeInfo,T> applyToMatching(java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo>, java.lang.Object)
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.ScopeConfiguratorBuilder<T> builder()
GENERIC TEMPLATES: +++ T:java.lang.Object
+++* NEW METHOD: PUBLIC(+) STATIC(+) java.util.function.Function<io.opentelemetry.sdk.common.InstrumentationScopeInfo,T> applyToMatching(java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo>, java.lang.Object, java.lang.Object)
GENERIC TEMPLATES: +++ T:java.lang.Object
+++ NEW METHOD: PUBLIC(+) STATIC(+) java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo> scopeNameEquals(java.lang.String)
+++ NEW METHOD: PUBLIC(+) STATIC(+) java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo> scopeNameMatches(java.lang.String)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.ScopeConfiguratorBuilder<T> toBuilder()
+++ NEW ANNOTATION: java.lang.FunctionalInterface
+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.ScopeConfiguratorBuilder (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
GENERIC TEMPLATES: +++ T:java.lang.Object
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.ScopeConfiguratorBuilder<T> addCondition(java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo>, java.lang.Object)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.ScopeConfigurator<T> build()
+++ NEW METHOD: PUBLIC(+) STATIC(+) java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo> nameEquals(java.lang.String)
+++ NEW METHOD: PUBLIC(+) STATIC(+) java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo> nameMatchesGlob(java.lang.String)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.ScopeConfiguratorBuilder<T> setDefault(java.lang.Object)
5 changes: 4 additions & 1 deletion docs/apidiffs/current_vs_latest/opentelemetry-sdk-logs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ Comparing source compatibility of against
+++ NEW CLASS: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.logs.LoggerConfig (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.ScopeConfiguratorBuilder<io.opentelemetry.sdk.logs.LoggerConfig> configuratorBuilder()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.logs.LoggerConfig defaultConfig()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.logs.LoggerConfig disabled()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.logs.LoggerConfig enabled()
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) boolean isEnabled()
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder addScopeConfig(io.opentelemetry.sdk.common.ScopeSelector, io.opentelemetry.sdk.logs.LoggerConfig)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder addLoggerConfiguratorMatcher(java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo>, io.opentelemetry.sdk.logs.LoggerConfig)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder setLoggerConfigurator(io.opentelemetry.sdk.common.ScopeConfigurator<io.opentelemetry.sdk.logs.LoggerConfig>)
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ Comparing source compatibility of against
+++ NEW CLASS: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.MeterConfig (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.ScopeConfiguratorBuilder<io.opentelemetry.sdk.metrics.MeterConfig> configuratorBuilder()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.MeterConfig defaultConfig()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.MeterConfig disabled()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.MeterConfig enabled()
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) boolean isEnabled()
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder addScopeConfig(io.opentelemetry.sdk.common.ScopeSelector, io.opentelemetry.sdk.metrics.MeterConfig)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder addMeterConfiguratorMatcher(java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo>, io.opentelemetry.sdk.metrics.MeterConfig)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder setMeterConfigurator(io.opentelemetry.sdk.common.ScopeConfigurator<io.opentelemetry.sdk.metrics.MeterConfig>)
5 changes: 4 additions & 1 deletion docs/apidiffs/current_vs_latest/opentelemetry-sdk-trace.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
Comparing source compatibility of against
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.SdkTracerProviderBuilder (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.SdkTracerProviderBuilder addScopeConfig(io.opentelemetry.sdk.common.ScopeSelector, io.opentelemetry.sdk.trace.TracerConfig)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.SdkTracerProviderBuilder addTracerConfiguratorMatcher(java.util.function.Predicate<io.opentelemetry.sdk.common.InstrumentationScopeInfo>, io.opentelemetry.sdk.trace.TracerConfig)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.SdkTracerProviderBuilder setTracerConfigurator(io.opentelemetry.sdk.common.ScopeConfigurator<io.opentelemetry.sdk.trace.TracerConfig>)
+++ NEW CLASS: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.trace.TracerConfig (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.ScopeConfiguratorBuilder<io.opentelemetry.sdk.trace.TracerConfig> configuratorBuilder()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.TracerConfig defaultConfig()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.TracerConfig disabled()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.TracerConfig enabled()
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) boolean isEnabled()
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

package io.opentelemetry.sdk;

import static io.opentelemetry.sdk.common.ScopeConfig.applyToMatching;
import static io.opentelemetry.sdk.common.ScopeConfig.scopeNameEquals;
import static io.opentelemetry.sdk.common.ScopeConfiguratorBuilder.nameEquals;
import static org.assertj.core.api.Assertions.assertThat;

import io.opentelemetry.api.OpenTelemetry;
Expand Down Expand Up @@ -35,36 +34,31 @@
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;

class ScopeConfigTest {
class ScopeConfiguratorTest {

private final InMemoryLogRecordExporter logRecordExporter = InMemoryLogRecordExporter.create();
private final InMemoryMetricReader metricReader = InMemoryMetricReader.create();
private final InMemorySpanExporter spanExporter = InMemorySpanExporter.create();

/**
* Disable "scopeB". All other scopes are enabled by default.
*/
/** Disable "scopeB". All other scopes are enabled by default. */
@Test
void disableScopeB() {
OpenTelemetrySdk sdk =
OpenTelemetrySdk.builder()
.setTracerProvider(
SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(spanExporter))
.setTracerConfigProvider(
applyToMatching(scopeNameEquals("scopeB"), TracerConfig.disabled()))
.addTracerConfiguratorMatcher(nameEquals("scopeB"), TracerConfig.disabled())
.build())
.setMeterProvider(
SdkMeterProvider.builder()
.registerMetricReader(metricReader)
.setMeterConfigProvider(
applyToMatching(scopeNameEquals("scopeB"), MeterConfig.disabled()))
.addMeterConfiguratorMatcher(nameEquals("scopeB"), MeterConfig.disabled())
.build())
.setLoggerProvider(
SdkLoggerProvider.builder()
.addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter))
.setLoggerConfigProvider(
applyToMatching(scopeNameEquals("scopeB"), LoggerConfig.disabled()))
.addLoggerConfiguratorMatcher(nameEquals("scopeB"), LoggerConfig.disabled())
.build())
.build();

Expand Down Expand Up @@ -104,36 +98,44 @@ void disableScopeB() {
});
}

/**
* Disable all scopes by default and enable a single scope.
*/
/** Disable all scopes by default and enable a single scope. */
@Test
void disableAllScopesExceptB() {
OpenTelemetrySdk sdk =
OpenTelemetrySdk.builder()
.setTracerProvider(
SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(spanExporter))
.setTracerConfigProvider(
applyToMatching(scopeNameEquals("scopeB"), TracerConfig.enabled(), TracerConfig.disabled()))
.setTracerConfigurator(
TracerConfig.configuratorBuilder()
.setDefault(TracerConfig.disabled())
.addCondition(nameEquals("scopeB"), TracerConfig.enabled())
.build())
.build())
.setMeterProvider(
SdkMeterProvider.builder()
.registerMetricReader(metricReader)
.setMeterConfigProvider(
applyToMatching(scopeNameEquals("scopeB"), MeterConfig.enabled(), MeterConfig.disabled()))
.setMeterConfigurator(
MeterConfig.configuratorBuilder()
.setDefault(MeterConfig.disabled())
.addCondition(nameEquals("scopeB"), MeterConfig.enabled())
.build())
.build())
.setLoggerProvider(
SdkLoggerProvider.builder()
.addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter))
.setLoggerConfigProvider(
applyToMatching(scopeNameEquals("scopeB"), LoggerConfig.enabled(), LoggerConfig.disabled()))
.setLoggerConfigurator(
LoggerConfig.configuratorBuilder()
.setDefault(LoggerConfig.disabled())
.addCondition(nameEquals("scopeB"), LoggerConfig.enabled())
.build())
.build())
.build();

simulateInstrumentation(sdk);

// Collect all the telemetry. Ensure we only see telemetry from scopeB, since other scopes have been disabled by default.
// Collect all the telemetry. Ensure we only see telemetry from scopeB, since other scopes have
// been disabled by default.
assertThat(spanExporter.getFinishedSpanItems())
.satisfies(
spans -> {
Expand Down Expand Up @@ -166,7 +168,6 @@ void disableAllScopesExceptB() {
});
}


/**
* Emit spans, metrics and logs in a hierarchy of 3 scopes: scopeA -> scopeB -> scopeC. Exercise
* the scope config which is common across all signals.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.common;

import java.util.function.Function;

/**
* A {@link ScopeConfigurator} computes configuration for a given {@link InstrumentationScopeInfo}.
*/
@FunctionalInterface
public interface ScopeConfigurator<T> extends Function<InstrumentationScopeInfo, T> {

/** Create a new builder. */
static <T> ScopeConfiguratorBuilder<T> builder() {
return new ScopeConfiguratorBuilder<>(unused -> null);
}

/**
* Convert this {@link ScopeConfigurator} to a builder. Additional added matchers only apply when
* {@link #apply(Object)} returns {@code null}. If this configurator contains {@link
* ScopeConfiguratorBuilder#setDefault(Object)}, additional matchers are never applied.
*/
default ScopeConfiguratorBuilder<T> toBuilder() {
return new ScopeConfiguratorBuilder<>(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.common;

import io.opentelemetry.sdk.internal.GlobUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import javax.annotation.Nullable;

/**
* Builder for {@link ScopeConfigurator}.
*
* @param <T> The scope configuration object, e.g. {@code TracerConfig}, {@code LoggerConfig},
* {@code MeterConfig}.
*/
public final class ScopeConfiguratorBuilder<T> {

private final ScopeConfigurator<T> baseScopeConfigurator;
@Nullable private T defaultScopeConfig;
private final List<Condition<T>> conditions = new ArrayList<>();

ScopeConfiguratorBuilder(ScopeConfigurator<T> baseScopeConfigurator) {
this.baseScopeConfigurator = baseScopeConfigurator;
}

/**
* Set the default scope config, which is returned by {@link ScopeConfigurator#apply(Object)} if a
* {@link InstrumentationScopeInfo} does not match any {@link #addCondition(Predicate, Object)
* conditions}. If a default is not set, an SDK defined default is used.
*/
public ScopeConfiguratorBuilder<T> setDefault(T defaultScopeConfig) {
this.defaultScopeConfig = defaultScopeConfig;
return this;
}

/**
* Add a condition. Conditions are evaluated in order. The {@code scopeConfig} for the first match
* is returned by {@link ScopeConfigurator#apply(Object)}.
*
* @param scopePredicate predicate that {@link InstrumentationScopeInfo}s are evaluated against
* @param scopeConfig the scope config to use when this condition is the first matching {@code
* scopePredicate}
* @see #nameMatchesGlob(String)
* @see #nameEquals(String)
*/
public ScopeConfiguratorBuilder<T> addCondition(
Predicate<InstrumentationScopeInfo> scopePredicate, T scopeConfig) {
conditions.add(new Condition<>(scopePredicate, scopeConfig));
return this;
}

/**
* Helper function for pattern matching {@link InstrumentationScopeInfo#getName()} against the
* {@code globPattern}.
*
* <p>{@code globPattern} may contain the wildcard characters {@code *} and {@code ?} with the
* following matching criteria:
*
* <ul>
* <li>{@code *} matches 0 or more instances of any character
* <li>{@code ?} matches exactly one instance of any character
* </ul>
*
* @see #addCondition(Predicate, Object)
*/
public static Predicate<InstrumentationScopeInfo> nameMatchesGlob(String globPattern) {
Predicate<String> globPredicate = GlobUtil.toGlobPatternPredicate(globPattern);
return scopeInfo -> globPredicate.test(scopeInfo.getName());
}

/**
* Helper function for exact matching {@link InstrumentationScopeInfo#getName()} against the
* {@code scopeName}.
*
* @see #addCondition(Predicate, Object)
*/
public static Predicate<InstrumentationScopeInfo> nameEquals(String scopeName) {
return scopeInfo -> scopeInfo.getName().equals(scopeName);
}

/** Build a {@link ScopeConfigurator} with the configuration of this builder. */
public ScopeConfigurator<T> build() {
// TODO: return an instance with toString implementation which self describes rules
return scopeInfo -> {
T scopeConfig = baseScopeConfigurator.apply(scopeInfo);
if (scopeConfig != null) {
return scopeConfig;
}
for (Condition<T> condition : conditions) {
if (condition.scopeMatcher.test(scopeInfo)) {
return condition.scopeConfig;
}
}
return defaultScopeConfig;
};
}

private static final class Condition<T> {
private final Predicate<InstrumentationScopeInfo> scopeMatcher;
private final T scopeConfig;

private Condition(Predicate<InstrumentationScopeInfo> scopeMatcher, T scopeConfig) {
this.scopeMatcher = scopeMatcher;
this.scopeConfig = scopeConfig;
}
}
}
Loading

0 comments on commit 8486a31

Please sign in to comment.