Add ConfigurableSamplerProvider to allow custom samplers in agent, etc (#3029)
This commit is contained in:
		
							parent
							
								
									66be330d7d
								
							
						
					
					
						commit
						f5e0a82e04
					
				| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
 | 
			
		||||
package io.opentelemetry.sdk.autoconfigure;
 | 
			
		||||
 | 
			
		||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableSamplerProvider;
 | 
			
		||||
import io.opentelemetry.sdk.autoconfigure.spi.SdkTracerProviderConfigurer;
 | 
			
		||||
import io.opentelemetry.sdk.resources.Resource;
 | 
			
		||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +19,10 @@ 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 java.util.Map;
 | 
			
		||||
import java.util.ServiceLoader;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.stream.StreamSupport;
 | 
			
		||||
 | 
			
		||||
final class TracerProviderConfiguration {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +119,14 @@ final class TracerProviderConfiguration {
 | 
			
		|||
 | 
			
		||||
  // Visible for testing
 | 
			
		||||
  static Sampler configureSampler(String sampler, ConfigProperties config) {
 | 
			
		||||
    Map<String, Sampler> spiSamplers =
 | 
			
		||||
        StreamSupport.stream(
 | 
			
		||||
                ServiceLoader.load(ConfigurableSamplerProvider.class).spliterator(), false)
 | 
			
		||||
            .collect(
 | 
			
		||||
                Collectors.toMap(
 | 
			
		||||
                    ConfigurableSamplerProvider::getName,
 | 
			
		||||
                    provider -> provider.createSampler(config)));
 | 
			
		||||
 | 
			
		||||
    switch (sampler) {
 | 
			
		||||
      case "always_on":
 | 
			
		||||
        return Sampler.alwaysOn();
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +153,12 @@ final class TracerProviderConfiguration {
 | 
			
		|||
          return Sampler.parentBased(Sampler.traceIdRatioBased(ratio));
 | 
			
		||||
        }
 | 
			
		||||
      default:
 | 
			
		||||
        throw new ConfigurationException("Unrecognized value for otel.traces.sampler: " + sampler);
 | 
			
		||||
        Sampler spiSampler = spiSamplers.get(sampler);
 | 
			
		||||
        if (spiSampler == null) {
 | 
			
		||||
          throw new ConfigurationException(
 | 
			
		||||
              "Unrecognized value for otel.traces.sampler: " + sampler);
 | 
			
		||||
        }
 | 
			
		||||
        return spiSampler;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright The OpenTelemetry Authors
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package io.opentelemetry.sdk.autoconfigure.spi;
 | 
			
		||||
 | 
			
		||||
import io.opentelemetry.sdk.autoconfigure.ConfigProperties;
 | 
			
		||||
import io.opentelemetry.sdk.trace.samplers.Sampler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A service provider interface (SPI) for providing additional samplers that can be used with the
 | 
			
		||||
 * autoconfigured SDK. If the {@code otel.traces.sampler} property contains a value equal to what is
 | 
			
		||||
 * returned by {@link #getName()}, the sampler returned by {@link #createSampler(ConfigProperties)}
 | 
			
		||||
 * will be enabled and added to the SDK.
 | 
			
		||||
 */
 | 
			
		||||
public interface ConfigurableSamplerProvider {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns a {@link Sampler} that can be registered to OpenTelemetry by providing the property
 | 
			
		||||
   * value specified by {@link #getName()}.
 | 
			
		||||
   */
 | 
			
		||||
  Sampler createSampler(ConfigProperties config);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the name of this sampler, which can be specified with the {@code otel.traces.sampler}
 | 
			
		||||
   * property to enable it. The name returned should NOT be the same as any other exporter name. If
 | 
			
		||||
   * the name does conflict with another exporter name, the resulting behavior is undefined and it
 | 
			
		||||
   * is explicitly unspecified which exporter will actually be used.
 | 
			
		||||
   */
 | 
			
		||||
  String getName();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -10,8 +10,8 @@ import io.opentelemetry.sdk.trace.export.SpanExporter;
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 * A service provider interface (SPI) for providing additional exporters that can be used with the
 | 
			
		||||
 * autoconfigured SDK. If the {@code otel.trace.exporter} property contains a value equal to what is
 | 
			
		||||
 * returned by {@link #getName()}, the exporter returned by {@link
 | 
			
		||||
 * autoconfigured SDK. If the {@code otel.traces.exporter} property contains a value equal to what
 | 
			
		||||
 * is returned by {@link #getName()}, the exporter returned by {@link
 | 
			
		||||
 * #createExporter(ConfigProperties)} will be enabled and added to the SDK.
 | 
			
		||||
 */
 | 
			
		||||
public interface ConfigurableSpanExporterProvider {
 | 
			
		||||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ public interface ConfigurableSpanExporterProvider {
 | 
			
		|||
  SpanExporter createExporter(ConfigProperties config);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the name of this exporter, which can be specified with the {@code otel.trace.exporter}
 | 
			
		||||
   * Returns the name of this exporter, which can be specified with the {@code otel.traces.exporter}
 | 
			
		||||
   * property to enable it. The name returned should NOT be the same as any other exporter name. If
 | 
			
		||||
   * the name does conflict with another exporter name, the resulting behavior is undefined and it
 | 
			
		||||
   * is explicitly unspecified which exporter will actually be used.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright The OpenTelemetry Authors
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package io.opentelemetry.sdk.autoconfigure;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
import io.opentelemetry.sdk.trace.samplers.Sampler;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
public class ConfigurableSamplerTest {
 | 
			
		||||
 | 
			
		||||
  @Test
 | 
			
		||||
  void configuration() {
 | 
			
		||||
    ConfigProperties config =
 | 
			
		||||
        ConfigProperties.createForTest(ImmutableMap.of("test.option", "true"));
 | 
			
		||||
    Sampler sampler = TracerProviderConfiguration.configureSampler("testSampler", config);
 | 
			
		||||
 | 
			
		||||
    assertThat(sampler)
 | 
			
		||||
        .isInstanceOfSatisfying(
 | 
			
		||||
            TestConfigurableSamplerProvider.TestSampler.class,
 | 
			
		||||
            s -> assertThat(s.getConfig()).isSameAs(config));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Test
 | 
			
		||||
  void samplerNotFound() {
 | 
			
		||||
    assertThatThrownBy(
 | 
			
		||||
            () ->
 | 
			
		||||
                TracerProviderConfiguration.configureSampler(
 | 
			
		||||
                    "catSampler", ConfigProperties.createForTest(Collections.emptyMap())))
 | 
			
		||||
        .isInstanceOf(ConfigurationException.class)
 | 
			
		||||
        .hasMessageContaining("catSampler");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright The OpenTelemetry Authors
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package io.opentelemetry.sdk.autoconfigure;
 | 
			
		||||
 | 
			
		||||
import io.opentelemetry.api.common.Attributes;
 | 
			
		||||
import io.opentelemetry.api.trace.SpanKind;
 | 
			
		||||
import io.opentelemetry.context.Context;
 | 
			
		||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableSamplerProvider;
 | 
			
		||||
import io.opentelemetry.sdk.trace.data.LinkData;
 | 
			
		||||
import io.opentelemetry.sdk.trace.samplers.Sampler;
 | 
			
		||||
import io.opentelemetry.sdk.trace.samplers.SamplingDecision;
 | 
			
		||||
import io.opentelemetry.sdk.trace.samplers.SamplingResult;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class TestConfigurableSamplerProvider implements ConfigurableSamplerProvider {
 | 
			
		||||
  @Override
 | 
			
		||||
  public Sampler createSampler(ConfigProperties config) {
 | 
			
		||||
    return new TestSampler(config);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getName() {
 | 
			
		||||
    return "testSampler";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static class TestSampler implements Sampler {
 | 
			
		||||
 | 
			
		||||
    private final ConfigProperties config;
 | 
			
		||||
 | 
			
		||||
    public TestSampler(ConfigProperties config) {
 | 
			
		||||
      this.config = config;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public SamplingResult shouldSample(
 | 
			
		||||
        Context parentContext,
 | 
			
		||||
        String traceId,
 | 
			
		||||
        String name,
 | 
			
		||||
        SpanKind spanKind,
 | 
			
		||||
        Attributes attributes,
 | 
			
		||||
        List<LinkData> parentLinks) {
 | 
			
		||||
      return SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getDescription() {
 | 
			
		||||
      return "test";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ConfigProperties getConfig() {
 | 
			
		||||
      return config;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
io.opentelemetry.sdk.autoconfigure.TestConfigurableSamplerProvider
 | 
			
		||||
		Loading…
	
		Reference in New Issue