Skip to content

Commit

Permalink
otel metric verification
Browse files Browse the repository at this point in the history
  • Loading branch information
trask committed Jan 11, 2024
1 parent 7ece0fd commit 36adcbf
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import io.opentelemetry.sdk.metrics.Aggregation;
import io.opentelemetry.sdk.metrics.InstrumentSelector;
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
import io.opentelemetry.sdk.metrics.View;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import io.opentelemetry.sdk.metrics.internal.view.AiViewRegistry;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
Expand Down Expand Up @@ -704,12 +707,25 @@ private static List<ProcessorConfig> getLogProcessorConfigs(Configuration config
private static SdkMeterProviderBuilder configureMetrics(
SdkMeterProviderBuilder builder, Configuration configuration) {

// drop internal OpenTelemetry SDK metrics
drop(builder, "io.opentelemetry.sdk.trace", "queueSize");
drop(builder, "io.opentelemetry.sdk.trace", "processedSpans");
drop(builder, "io.opentelemetry.sdk.logs", "queueSize");
drop(builder, "io.opentelemetry.sdk.logs", "processedLogs");

if (configuration.internal.preAggregatedStandardMetrics.enabled) {
AiViewRegistry.registerViews(builder);
}
return builder;
}

private static void drop(
SdkMeterProviderBuilder builder, String meterName, String processedSpans) {
builder.registerView(
InstrumentSelector.builder().setMeterName(meterName).setName(processedSpans).build(),
View.builder().setAggregation(Aggregation.drop()).build());
}

@Override
public void afterAutoConfigure(OpenTelemetrySdk sdk) {
Runtime.getRuntime()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@
import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.WILDFLY_13_JAVA_8_OPENJ9;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import com.microsoft.applicationinsights.smoketest.schemav2.Data;
import com.microsoft.applicationinsights.smoketest.schemav2.Envelope;
import com.microsoft.applicationinsights.smoketest.schemav2.MetricData;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

Expand All @@ -23,17 +31,65 @@ abstract class DetectUnexpectedOtelMetricsTest {

@RegisterExtension static final SmokeTestExtension testing = SmokeTestExtension.create();

private static final List<String> EXPECTED_METRIC_NAMES = new ArrayList<>();

static {
EXPECTED_METRIC_NAMES.add("_OTELRESOURCE_");
EXPECTED_METRIC_NAMES.add("Loaded Class Count");
EXPECTED_METRIC_NAMES.add("Current Thread Count");
EXPECTED_METRIC_NAMES.add("\\Process(??APP_WIN32_PROC??)\\% Processor Time");
EXPECTED_METRIC_NAMES.add("\\Process(??APP_WIN32_PROC??)\\% Processor Time Normalized");
EXPECTED_METRIC_NAMES.add("\\Process(??APP_WIN32_PROC??)\\Private Bytes");
EXPECTED_METRIC_NAMES.add("\\Memory\\Available Bytes");
EXPECTED_METRIC_NAMES.add("\\Process(??APP_WIN32_PROC??)\\IO Data Bytes/sec");
EXPECTED_METRIC_NAMES.add("\\Processor(_Total)\\% Processor Time");
EXPECTED_METRIC_NAMES.add("Suspected Deadlocked Threads");
EXPECTED_METRIC_NAMES.add("Heap Memory Used (MB)");
EXPECTED_METRIC_NAMES.add("% Of Max Heap Memory Used");
EXPECTED_METRIC_NAMES.add("GC Total Count");
EXPECTED_METRIC_NAMES.add("GC Total Time");
}

@Test
@TargetUri("/app")
void testApp() throws Exception {
// verify no unexpected otel metrics, expect an TimeoutException being thrown
assertThatThrownBy(
() ->
testing.mockedIngestion.waitForItemsUnexpectedOtelMetric(
"MetricData", envelope -> true))
testing.mockedIngestion.waitForItems(
"MetricData",
envelope -> {
MetricData md = (MetricData) ((Data<?>) envelope.getData()).getBaseData();
return !EXPECTED_METRIC_NAMES.contains(md.getMetrics().get(0).getName())
&& !md.getProperties().containsKey("_MS.MetricId");
},
1))
.isInstanceOf(TimeoutException.class);
}

// wait for at least one unexpected otel metrics for failure case or timeout for success
public List<Envelope> waitForItemsUnexpectedOtelMetric(String type, Predicate<Envelope> condition)
throws InterruptedException, ExecutionException, TimeoutException {
return testing.mockedIngestion.waitForItems(
new Predicate<Envelope>() {
@Override
public boolean test(Envelope input) {
if (!input.getData().getBaseType().equals(type)) {
return false;
}
MetricData md = (MetricData) ((Data<?>) input.getData()).getBaseData();
if ("_OTELRESOURCE_".equals(md.getMetrics().get(0).getName())
|| md.getProperties().containsKey("_MS.MetricId")) {
return false;
}
return condition.test(input);
}
},
1,
10,
TimeUnit.SECONDS);
}

@Environment(TOMCAT_8_JAVA_8)
static class Tomcat8Java8Test extends DetectUnexpectedOtelMetricsTest {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.microsoft.applicationinsights.smoketest.schemav2.Data;
import com.microsoft.applicationinsights.smoketest.schemav2.Domain;
import com.microsoft.applicationinsights.smoketest.schemav2.Envelope;
import com.microsoft.applicationinsights.smoketest.schemav2.MetricData;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -249,29 +248,6 @@ public List<Envelope> waitForItemsInOperation(
return waitForItems(type, numItems, operationId, condition);
}

// wait for at least one unexpected otel metrics for failure case or timeout for success
public List<Envelope> waitForItemsUnexpectedOtelMetric(String type, Predicate<Envelope> condition)
throws InterruptedException, ExecutionException, TimeoutException {
return waitForItems(
new Predicate<Envelope>() {
@Override
public boolean test(Envelope input) {
if (!input.getData().getBaseType().equals(type)) {
return false;
}
MetricData md = (MetricData) ((Data<?>) input.getData()).getBaseData();
if ("_OTELRESOURCE_".equals(md.getMetrics().get(0).getName())
|| md.getProperties().containsKey("_MS.MetricId")) {
return false;
}
return condition.test(input);
}
},
1,
10,
TimeUnit.SECONDS);
}

// this is used to filter out some sporadic messages that are captured via java.util.logging
// instrumentation
public List<Envelope> waitForMessageItemsInRequest(int numItems, String operationId)
Expand Down

0 comments on commit 36adcbf

Please sign in to comment.