Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import io.opentelemetry.contrib.dynamic.policy.PolicyTypeInitializer;
import io.opentelemetry.contrib.dynamic.policy.PolicyValidator;
import io.opentelemetry.contrib.dynamic.policy.TelemetryPolicy;
import io.opentelemetry.contrib.dynamic.policy.tracesampling.TraceSamplingRatePolicy;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.io.Closeable;
Expand Down Expand Up @@ -65,9 +66,8 @@ public final class PolicyInit {
private static final PolicyStore policyStore = new PolicyStore();

static {
// For now, policies will be registered here.
// TODO: register TraceSamplingRatePolicy when registerPolicyType implemented
// TraceSamplingRatePolicy.registerPolicyType();
// For now, policies will be registered here. TODO: move to a more dynamic way.
TraceSamplingRatePolicy.registerPolicyType();
}
Comment thread
jackshirazi marked this conversation as resolved.

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

package io.opentelemetry.contrib.dynamic.policy.tracesampling;

import io.opentelemetry.contrib.dynamic.policy.PolicyImplementer;
import io.opentelemetry.contrib.dynamic.policy.TelemetryPolicy;
import io.opentelemetry.contrib.dynamic.policy.registry.PolicyInit;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.extension.incubator.trace.samplers.ComposableSampler;
import io.opentelemetry.sdk.extension.incubator.trace.samplers.CompositeSampler;
Expand Down Expand Up @@ -35,12 +37,18 @@ public double getProbability() {
* <p>If the extension is configured to use this policy, this installs an opinionated sampler that
* overrides any other sampler
*/
public static void initialize(AutoConfigurationCustomizer autoConfiguration) {
public static PolicyImplementer initialize(AutoConfigurationCustomizer autoConfiguration) {
Objects.requireNonNull(autoConfiguration, "autoConfiguration cannot be null");
Sampler initialDelegate = createSampler(1.0);
DelegatingSampler delegatingSampler = new DelegatingSampler(initialDelegate);
initializedSampler = delegatingSampler;
autoConfiguration.addSamplerCustomizer((sampler, config) -> delegatingSampler);
return new TraceSamplingRatePolicyImplementer(delegatingSampler);
}

public static void registerPolicyType() {
PolicyInit.registerPolicyType(
POLICY_TYPE, TraceSamplingRatePolicy.class, TraceSamplingRatePolicy::initialize);
}
Comment thread
jackshirazi marked this conversation as resolved.

/**
Expand Down Expand Up @@ -69,6 +77,10 @@ public static DelegatingSampler getInitializedSampler() {
return initializedSampler;
}

static void resetForTest() {
initializedSampler = null;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ void readFromConfigPropertiesReadsJsonWhenYamlPathMissing() throws Exception {
assertThat(source.getLocation()).isEqualTo("vendor");
assertThat(source.getMappings()).hasSize(1);
assertThat(source.getMappings().get(0).getSourceKey()).isEqualTo("sampling_rate");
assertThat(source.getMappings().get(0).getPolicyType()).isEqualTo("trace_sampling_rate_policy");
assertThat(source.getMappings().get(0).getPolicyType()).isEqualTo("trace-sampling");
}

@Test
Expand Down Expand Up @@ -191,7 +191,7 @@ void readFromDeclarativeConfigPropertiesReadsTelemetryPolicySources() {
assertThat(source.getLocation()).isEqualTo("from-declarative");
assertThat(source.getMappings()).hasSize(1);
assertThat(source.getMappings().get(0).getSourceKey()).isEqualTo("sampling_rate");
assertThat(source.getMappings().get(0).getPolicyType()).isEqualTo("trace_sampling_rate_policy");
assertThat(source.getMappings().get(0).getPolicyType()).isEqualTo("trace-sampling");
}

@Test
Expand Down Expand Up @@ -428,7 +428,7 @@ private static DeclarativeConfigProperties mappingConfig() {
when(mapping.getString(PolicyInitConfig.SOURCE_KEY_DECLARATIVE_KEY))
.thenReturn("sampling_rate");
when(mapping.getString(PolicyInitConfig.POLICY_TYPE_DECLARATIVE_KEY))
.thenReturn("trace_sampling_rate_policy");
.thenReturn("trace-sampling");
return mapping;
}

Expand All @@ -453,13 +453,13 @@ public DeclarativeConfigProperties getGeneralConfig() {

private static String minimalJsonConfig() {
return "{\"sources\":[{\"kind\":\"opamp\",\"format\":\"jsonkeyvalue\",\"location\":\"vendor\","
+ "\"mappings\":[{\"sourceKey\":\"sampling_rate\",\"policyType\":\"trace_sampling_rate_policy\"}]}]}";
+ "\"mappings\":[{\"sourceKey\":\"sampling_rate\",\"policyType\":\"trace-sampling\"}]}]}";
}

private static String jsonWithLocation(String location) {
return "{\"sources\":[{\"kind\":\"opamp\",\"format\":\"jsonkeyvalue\",\"location\":\""
+ location
+ "\",\"mappings\":[{\"sourceKey\":\"sampling_rate\",\"policyType\":\"trace_sampling_rate_policy\"}]}]}";
+ "\",\"mappings\":[{\"sourceKey\":\"sampling_rate\",\"policyType\":\"trace-sampling\"}]}]}";
}

private static String minimalYamlConfig() {
Expand All @@ -469,7 +469,7 @@ private static String minimalYamlConfig() {
+ " location: vendor\n"
+ " mappings:\n"
+ " - sourceKey: sampling_rate\n"
+ " policyType: trace_sampling_rate_policy\n";
+ " policyType: trace-sampling\n";
}

private static String yamlWithLocation(String location) {
Expand All @@ -481,6 +481,6 @@ private static String yamlWithLocation(String location) {
+ "\n"
+ " mappings:\n"
+ " - sourceKey: sampling_rate\n"
+ " policyType: trace_sampling_rate_policy\n";
+ " policyType: trace-sampling\n";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.contrib.dynamic.policy.registry;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.contrib.dynamic.policy.tracesampling.TraceSamplingRatePolicy;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
import java.util.function.Function;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.ArgumentCaptor;

class PolicyInitTest {
@TempDir Path tempDir;

@AfterEach
void tearDown() throws Exception {
PolicyInit.resetForTest();
invokeStaticNoArg(TraceSamplingRatePolicy.class, "resetForTest");
}

@Test
void doesNotInitializePolicyFromDeclarativeOnlyConfigInAutoConfigurationMode() {
AutoConfigurationCustomizer customizer = mock(AutoConfigurationCustomizer.class);
PolicyInit.init(customizer);
Function<ConfigProperties, Map<String, String>> propertiesCustomizer =
capturePropertiesCustomizer(customizer);

ConfigProperties config = mock(ConfigProperties.class);
when(config.getString(PolicyInitConfig.POLICY_INIT_CONFIG_PROPERTY_YAML)).thenReturn(null);
when(config.getString(PolicyInitConfig.POLICY_INIT_CONFIG_PROPERTY_JSON)).thenReturn(null);
Map<String, String> ignored = propertiesCustomizer.apply(config);

assertThat(TraceSamplingRatePolicy.getInitializedSampler()).isNull();
assertThat(ignored).isNotNull();
}

@Test
void initializesPolicyFromInitConfigInAutoConfigurationMode() throws Exception {
AutoConfigurationCustomizer customizer = mock(AutoConfigurationCustomizer.class);
PolicyInit.init(customizer);
Function<ConfigProperties, Map<String, String>> propertiesCustomizer =
capturePropertiesCustomizer(customizer);

Path configPath = tempDir.resolve("policy-init.json");
Files.write(configPath, minimalJsonInitConfig().getBytes(StandardCharsets.UTF_8));

ConfigProperties config = mock(ConfigProperties.class);
when(config.getString(PolicyInitConfig.POLICY_INIT_CONFIG_PROPERTY_YAML)).thenReturn(null);
when(config.getString(PolicyInitConfig.POLICY_INIT_CONFIG_PROPERTY_JSON))
.thenReturn(configPath.toString());

Map<String, String> ignored = propertiesCustomizer.apply(config);

assertThat(ignored).isNotNull();
assertThat(TraceSamplingRatePolicy.getInitializedSampler()).isNotNull();
}

@Test
void initializesRegisteredPolicyTypeFromDeclarativeConfig() {
ConfigProperties config = mock(ConfigProperties.class);

PolicyInit.initFromDeclarativeConfig(
telemetryPolicyNodeConfig(TraceSamplingRatePolicy.POLICY_TYPE), config);

assertThat(TraceSamplingRatePolicy.getInitializedSampler()).isNotNull();
}

@Test
void throwsWhenDeclarativeConfigUsesUnknownPolicyType() {
ConfigProperties config = mock(ConfigProperties.class);

assertThatThrownBy(
() ->
PolicyInit.initFromDeclarativeConfig(
telemetryPolicyNodeConfig("trace_sampling_rate_policy"), config))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Unknown policyType");
}

private static Function<ConfigProperties, Map<String, String>> capturePropertiesCustomizer(
AutoConfigurationCustomizer customizer) {
@SuppressWarnings("unchecked")
ArgumentCaptor<Function<ConfigProperties, Map<String, String>>> captor =
ArgumentCaptor.forClass(Function.class);
verify(customizer).addPropertiesCustomizer(captor.capture());
return captor.getValue();
}

private static void invokeStaticNoArg(Class<?> targetClass, String methodName) throws Exception {
Method method = targetClass.getDeclaredMethod(methodName);
method.setAccessible(true);
method.invoke(null);
}

private static DeclarativeConfigProperties telemetryPolicyNodeConfig(String policyType) {
DeclarativeConfigProperties telemetryPolicy = mock(DeclarativeConfigProperties.class);
DeclarativeConfigProperties source = mock(DeclarativeConfigProperties.class);
DeclarativeConfigProperties mapping = mock(DeclarativeConfigProperties.class);

when(telemetryPolicy.getStructuredList(PolicyInitConfig.SOURCES_DECLARATIVE_KEY))
.thenReturn(Collections.singletonList(source));
when(source.getString(PolicyInitConfig.KIND_DECLARATIVE_KEY)).thenReturn("opamp");
when(source.getString(PolicyInitConfig.FORMAT_DECLARATIVE_KEY)).thenReturn("jsonkeyvalue");
when(source.getString(PolicyInitConfig.LOCATION_DECLARATIVE_KEY)).thenReturn("vendor");
when(source.getStructuredList(PolicyInitConfig.MAPPINGS_DECLARATIVE_KEY))
.thenReturn(Collections.singletonList(mapping));
when(mapping.getString(PolicyInitConfig.SOURCE_KEY_DECLARATIVE_KEY))
.thenReturn("sampling_rate");
when(mapping.getString(PolicyInitConfig.POLICY_TYPE_DECLARATIVE_KEY)).thenReturn(policyType);
return telemetryPolicy;
}

private static String minimalJsonInitConfig() {
return "{\"sources\":[{\"kind\":\"opamp\",\"format\":\"jsonkeyvalue\",\"location\":\"vendor\","
+ "\"mappings\":[{\"sourceKey\":\"sampling_rate\",\"policyType\":\""
+ TraceSamplingRatePolicy.POLICY_TYPE
+ "\"}]}]}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ void readsSourceCentricFixture() throws Exception {
assertThat(source.getLocation()).isEqualTo("vendor-specific");
assertThat(source.getMappings()).hasSize(4);
assertThat(source.getMappings().get(0).getSourceKey()).isEqualTo("sampling_rate");
assertThat(source.getMappings().get(0).getPolicyType())
.isEqualTo("trace_sampling_rate_policy");
assertThat(source.getMappings().get(0).getPolicyType()).isEqualTo("trace-sampling");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ void readsSourceCentricFixture() throws Exception {
assertThat(source.getLocation()).isEqualTo("vendor-specific");
assertThat(source.getMappings()).hasSize(4);
assertThat(source.getMappings().get(0).getSourceKey()).isEqualTo("sampling_rate");
assertThat(source.getMappings().get(0).getPolicyType())
.isEqualTo("trace_sampling_rate_policy");
assertThat(source.getMappings().get(0).getPolicyType()).isEqualTo("trace-sampling");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"format": "jsonkeyvalue",
"location": "vendor-specific",
"mappings": [
{ "sourceKey": "sampling_rate", "policyType": "trace_sampling_rate_policy" },
{ "sourceKey": "sampling_rate", "policyType": "trace-sampling" },
{ "sourceKey": "send_logs", "policyType": "log_export_enabled_policy" },
{ "sourceKey": "send_traces", "policyType": "trace_export_enabled_policy" },
{ "sourceKey": "send_metrics", "policyType": "metric_export_enabled_policy" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sources:
location: vendor-specific
mappings:
- sourceKey: sampling_rate
policyType: trace_sampling_rate_policy
policyType: trace-sampling
- sourceKey: send_logs
policyType: log_export_enabled_policy
- sourceKey: send_traces
Expand Down
Loading