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
19 changes: 19 additions & 0 deletions buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ val dependencyManagement by configurations.creating {
isCanBeResolved = false
}

val mockitoAgent by configurations.creating {
extendsFrom(dependencyManagement)
}

dependencies {
dependencyManagement(platform(project(":dependencyManagement")))
afterEvaluate {
Expand All @@ -226,6 +230,8 @@ dependencies {
}
}

mockitoAgent("org.mockito:mockito-core")

compileOnly("com.google.auto.value:auto-value-annotations")
compileOnly("com.google.code.findbugs:jsr305")

Expand Down Expand Up @@ -272,6 +278,19 @@ testing {
all {
testTask.configure {
systemProperty("java.util.logging.config.class", "io.opentelemetry.internal.testing.slf4j.JulBridgeInitializer")

// Starting in java 21, dynamically attaching agents triggers warnings. Mockito depends on
// agents to redefine classes. Hence, on java 21+ we get warnings of the form:
// WARNING: A Java agent has been loaded dynamically (/Users/jberg/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.12.19/450917cf3b358b691a824acf4c67aa89c826f67e/byte-buddy-agent-1.12.19.jar)
// WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
// WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
// WARNING: Dynamic loading of agents will be disallowed by default in a future release
// To remove these warnings, we attach the byte-buddy-agent used by mockito directly.
val mockitoAgent: FileCollection = mockitoAgent
doFirst {
val mockitoAgentJar = mockitoAgent.files.single { it.name.contains("byte-buddy-agent")}
jvmArgs("-javaagent:${mockitoAgentJar}")
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
Expand Down Expand Up @@ -276,13 +277,15 @@ void extract_nullContext() {
}

@Test
@SuppressLogger(TracerShim.class)
void inject_nullContext() {
Map<String, String> map = new HashMap<>();
tracerShim.inject(null, Format.Builtin.TEXT_MAP, new TextMapAdapter(map));
assertThat(map).isEmpty();
}

@Test
@SuppressLogger(TracerShim.class)
void inject_invalid() {
Map<String, String> map = new HashMap<>();
tracerShim.inject(mock(SpanContext.class), Format.Builtin.TEXT_MAP, new TextMapAdapter(map));
Expand Down Expand Up @@ -358,6 +361,7 @@ void extract_onlyBaggage() {
}

@Test
@SuppressLogger(TracerShim.class)
void close_OpenTelemetrySdk() {
SdkTracerProvider sdkProvider = mock(SdkTracerProvider.class);
doThrow(new RuntimeException("testing error")).when(sdkProvider).close();
Expand All @@ -375,6 +379,7 @@ void close_OpenTelemetrySdk() {
}

@Test
@SuppressLogger(TracerShim.class)
void close_GlobalOpenTelemetry() {
GlobalOpenTelemetry.resetForTest();
SdkTracerProvider sdkProvider = mock(SdkTracerProvider.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.common.ComponentLoader;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel;
import io.opentelemetry.sdk.trace.samplers.ParentBasedSamplerBuilder;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -58,6 +60,7 @@ class DeclarativeConfigurationCreateTest {
* can pass {@link DeclarativeConfiguration#parseAndCreate(InputStream)}.
*/
@Test
@SuppressLogger(ParentBasedSamplerBuilder.class)
void parseAndCreate_Examples(@TempDir Path tempDir)
throws IOException, CertificateEncodingException {
// Write certificates to temp files
Expand Down Expand Up @@ -175,6 +178,7 @@ void create_ModelCustomizer() {
}

@Test
@SuppressLogger(DeclarativeConfiguration.class)
void callAutoConfigureListeners_exceptionIsCaught() {
SpiHelper spiHelper = mock(SpiHelper.class);
when(spiHelper.getListeners())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.opentelemetry.sdk.extension.incubator.trace.samplers.ComposableSampler;
import io.opentelemetry.sdk.extension.incubator.trace.samplers.CompositeSampler;
import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler;
import io.opentelemetry.sdk.trace.samplers.ParentBasedSamplerBuilder;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.io.Closeable;
import java.time.Duration;
Expand All @@ -45,6 +46,7 @@
// Suppress logs from JaegerRemoteSampler
@SuppressLogger(
loggerName = "io.opentelemetry.sdk.extension.trace.jaeger.sampler.OkHttpGrpcService")
@SuppressLogger(ParentBasedSamplerBuilder.class)
class SamplerFactoryTest {

@RegisterExtension CleanupExtension cleanup = new CleanupExtension();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.google.common.collect.ImmutableSet;
import io.github.netmikey.logunit.api.LogCapturer;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
Expand All @@ -21,6 +22,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

@SuppressLogger(YamlDeclarativeConfigProperties.class)
class YamlDeclarativeConfigPropertiesTest {

@RegisterExtension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ void builderInvalidConfig() {
}

@Test
@SuppressLogger(BatchLogRecordProcessorBuilder.class)
void builderAdjustMaxBatchSize() {
LogRecordExporter dummyExporter = new CompletableLogRecordExporter();

Expand All @@ -136,6 +137,7 @@ void builderAdjustMaxBatchSize() {
}

@Test
@SuppressLogger(BatchLogRecordProcessorBuilder.class)
void maxExportBatchSizeExceedsQueueSize() throws InterruptedException {
// Given a processor configured with a maxExportBatchSize > maxQueueSize, ensure that after n =
// maxQueueSize logs are emitted, export is triggered and that the queue is fully drained and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ void flush() throws Exception {
}

@Test
@SuppressLogger(PeriodicMetricReader.class)
void forceflush_callsFlush() {
MetricExporter metricExporter = mock(MetricExporter.class);
when(metricExporter.export(any()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public final class ParentBasedSamplerBuilder {
@Nullable private Sampler localParentNotSampled;

ParentBasedSamplerBuilder(Sampler root) {
maybeLogTraceIdSamplerWarning(root, "root");
this.root = root;
}

Expand All @@ -30,12 +31,7 @@ public final class ParentBasedSamplerBuilder {
* @return this Builder
*/
public ParentBasedSamplerBuilder setRemoteParentSampled(Sampler remoteParentSampled) {
if (remoteParentSampled instanceof TraceIdRatioBasedSampler) {
logger.warning(
"TraceIdRatioBasedSampler is being used as a child sampler (remoteParentSampled). "
+ "This configuration is discouraged per the OpenTelemetry specification "
+ "and may lead to unexpected sampling behavior.");
}
maybeLogTraceIdSamplerWarning(remoteParentSampled, "remoteParentSampled");
this.remoteParentSampled = remoteParentSampled;
return this;
}
Expand All @@ -47,12 +43,7 @@ public ParentBasedSamplerBuilder setRemoteParentSampled(Sampler remoteParentSamp
* @return this Builder
*/
public ParentBasedSamplerBuilder setRemoteParentNotSampled(Sampler remoteParentNotSampled) {
if (remoteParentNotSampled instanceof TraceIdRatioBasedSampler) {
logger.warning(
"TraceIdRatioBasedSampler is being used as a child sampler (remoteParentNotSampled). "
+ "This configuration is discouraged per the OpenTelemetry specification "
+ "and may lead to unexpected sampling behavior.");
}
maybeLogTraceIdSamplerWarning(remoteParentNotSampled, "remoteParentNotSampled");
this.remoteParentNotSampled = remoteParentNotSampled;
return this;
}
Expand All @@ -64,12 +55,7 @@ public ParentBasedSamplerBuilder setRemoteParentNotSampled(Sampler remoteParentN
* @return this Builder
*/
public ParentBasedSamplerBuilder setLocalParentSampled(Sampler localParentSampled) {
if (localParentSampled instanceof TraceIdRatioBasedSampler) {
logger.warning(
"TraceIdRatioBasedSampler is being used as a child sampler (localParentSampled). "
+ "This configuration is discouraged per the OpenTelemetry specification "
+ "and may lead to unexpected sampling behavior.");
}
maybeLogTraceIdSamplerWarning(localParentSampled, "localParentSampled");
this.localParentSampled = localParentSampled;
return this;
}
Expand All @@ -81,14 +67,20 @@ public ParentBasedSamplerBuilder setLocalParentSampled(Sampler localParentSample
* @return this Builder
*/
public ParentBasedSamplerBuilder setLocalParentNotSampled(Sampler localParentNotSampled) {
if (localParentNotSampled instanceof TraceIdRatioBasedSampler) {
maybeLogTraceIdSamplerWarning(localParentNotSampled, "localParentNotSampled");
this.localParentNotSampled = localParentNotSampled;
return this;
}

private static void maybeLogTraceIdSamplerWarning(Sampler sampler, String field) {
if (sampler instanceof TraceIdRatioBasedSampler) {
logger.warning(
"TraceIdRatioBasedSampler is being used as a child sampler (localParentNotSampled). "
"TraceIdRatioBasedSampler is being used as a child sampler ("
+ field
+ "). "
+ "This configuration is discouraged per the OpenTelemetry specification "
+ "and may lead to unexpected sampling behavior.");
}
this.localParentNotSampled = localParentNotSampled;
return this;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,7 @@ void batch() throws Exception {
BatchSpanProcessor processor =
BatchSpanProcessor.builder(mockExporter)
.setMaxQueueSize(1)
.setMaxExportBatchSize(1)
// Manually flush
.setScheduleDelay(Duration.ofDays(1))
.setInternalTelemetryVersion(InternalTelemetryVersion.LATEST)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ void builderInvalidConfig() {
}

@Test
@SuppressLogger(BatchSpanProcessorBuilder.class)
void builderAdjustMaxBatchSize() {
SpanExporter dummyExporter = new CompletableSpanExporter();

Expand All @@ -142,6 +143,7 @@ void builderAdjustMaxBatchSize() {
}

@Test
@SuppressLogger(BatchSpanProcessorBuilder.class)
void maxExportBatchSizeExceedsQueueSize() throws InterruptedException {
// Given a processor configured with a maxExportBatchSize > maxQueueSize, ensure that after n =
// maxQueueSize spans are ended, export is triggered and that the queue is fully drained and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,82 +5,42 @@

package io.opentelemetry.sdk.trace.samplers;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import io.github.netmikey.logunit.api.LogCapturer;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

class ParentBasedSamplerBuilderTest {

@Test
void emitsWarningWhenTraceIdRatioBasedUsedAsChildSampler() {
Logger logger = Logger.getLogger(ParentBasedSamplerBuilder.class.getName());
TestLogHandler handler = new TestLogHandler();
logger.addHandler(handler);

try {
Sampler ratioSampler = Sampler.traceIdRatioBased(0.5);
ParentBasedSamplerBuilder builder = Sampler.parentBasedBuilder(Sampler.alwaysOn());

builder.setRemoteParentSampled(ratioSampler);
builder.setRemoteParentSampled(ratioSampler);
builder.build();

assertTrue(handler.warnings.stream().anyMatch(msg -> msg.contains("remoteParentSampled")));
} finally {
logger.removeHandler(handler);
}
}
@RegisterExtension
LogCapturer logs = LogCapturer.create().captureForType(ParentBasedSamplerBuilder.class);

@Test
@SuppressLogger(ParentBasedSamplerBuilder.class)
void emitsWarningForAllChildSamplerSetters() {
Logger logger = Logger.getLogger(ParentBasedSamplerBuilder.class.getName());
TestLogHandler handler = new TestLogHandler();
logger.addHandler(handler);

try {
Sampler ratioSampler = Sampler.traceIdRatioBased(0.5);
ParentBasedSamplerBuilder builder = Sampler.parentBasedBuilder(Sampler.alwaysOn());

builder.setRemoteParentNotSampled(ratioSampler);
builder.setRemoteParentNotSampled(ratioSampler);

builder.setLocalParentSampled(ratioSampler);
builder.setLocalParentSampled(ratioSampler);

builder.setLocalParentNotSampled(ratioSampler);
builder.setLocalParentNotSampled(ratioSampler);

builder.build();

assertTrue(handler.warnings.stream().anyMatch(msg -> msg.contains("remoteParentNotSampled")));
assertTrue(handler.warnings.stream().anyMatch(msg -> msg.contains("localParentSampled")));
assertTrue(handler.warnings.stream().anyMatch(msg -> msg.contains("localParentNotSampled")));
} finally {
logger.removeHandler(handler);
}
}

static final class TestLogHandler extends Handler {

final List<String> warnings = new ArrayList<>();

@Override
public void publish(LogRecord record) {
if (Level.WARNING.equals(record.getLevel())) {
warnings.add(record.getMessage());
}
}

@Override
public void flush() {}

@Override
public void close() {}
Sampler ratioSampler = Sampler.traceIdRatioBased(0.5);
Sampler.parentBasedBuilder(ratioSampler)
.setRemoteParentNotSampled(ratioSampler)
.setRemoteParentSampled(ratioSampler)
.setLocalParentSampled(ratioSampler)
.setLocalParentNotSampled(ratioSampler)
.build();

assertThat(logs.getEvents()).hasSize(5);
assertThat(logs.getEvents().get(0).getMessage())
.contains("TraceIdRatioBasedSampler is being used as a child sampler (root)");
assertThat(logs.getEvents().get(1).getMessage())
.contains(
"TraceIdRatioBasedSampler is being used as a child sampler (remoteParentNotSampled)");
assertThat(logs.getEvents().get(2).getMessage())
.contains(
"TraceIdRatioBasedSampler is being used as a child sampler (remoteParentSampled)");
assertThat(logs.getEvents().get(3).getMessage())
.contains("TraceIdRatioBasedSampler is being used as a child sampler (localParentSampled)");
assertThat(logs.getEvents().get(4).getMessage())
.contains(
"TraceIdRatioBasedSampler is being used as a child sampler (localParentNotSampled)");
}
}
Loading
Loading