diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/configuration/Configuration.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/configuration/Configuration.java index 40f0aa10467..870a1285dc6 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/configuration/Configuration.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/configuration/Configuration.java @@ -159,13 +159,19 @@ public static class Role { public static class Sampling { - // fixed percentage of requests - @Nullable public Double percentage; - // default is 5 requests per second (set in ConfigurationBuilder if neither percentage nor // requestsPerSecond was configured) @Nullable public Double requestsPerSecond; + // fixed percentage of requests + @Nullable public Double percentage; + + // in the future it would be nice for ingestion sampling to be an independent option + // from percentage (and to default to false), but currently ingestion sampling is enabled + // when percentage is set to 100, and this can be used to disable ingestion sampling even + // in that case (when percentage is 100) + @Nullable public Boolean ingestion; + // this config option only existed in one BETA release (3.4.0-BETA) @Deprecated @Nullable public Double limitPerSecond; diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/configuration/ConfigurationBuilder.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/configuration/ConfigurationBuilder.java index bf42d478ae5..ba8a358c9f9 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/configuration/ConfigurationBuilder.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/configuration/ConfigurationBuilder.java @@ -269,12 +269,18 @@ private static void logConfigurationWarnings(Configuration config) { + "If you're on premise, you can use APPLICATIONINSIGHTS_AUTHENTICATION_STRING environment variable to pass the client ID and secret, " + "e.g. APPLICATIONINSIGHTS_AUTHENTICATION_STRING=Authorization=AAD;ClientId={CLIENT_ID};ClientSecret={CLIENT_SECRET}."); } - if (config.sampling.percentage != null && config.sampling.requestsPerSecond != null) { + if (config.sampling.requestsPerSecond != null && config.sampling.percentage != null) { configurationLogger.warn( "Sampling \"requestsPerSecond\" and \"percentage\" should not be used at the same time." + " Please remove one of them."); config.sampling.percentage = null; // requestsPerSecond takes priority } + if (config.sampling.requestsPerSecond != null && config.sampling.ingestion != null) { + configurationLogger.warn( + "Sampling \"requestsPerSecond\" and \"ingestion\" should not be used at the same time." + + " Please remove one of them."); + config.sampling.ingestion = null; // requestsPerSecond takes priority + } logWarningIfUsingInternalAttributes(config); } diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/sampling/Samplers.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/sampling/Samplers.java index 2eb3fde8cd3..aec818a1bb4 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/sampling/Samplers.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/sampling/Samplers.java @@ -21,12 +21,15 @@ public static Sampler getSampler( sampler = new AiSampler(requestSamplingPercentage, parentlessDependencySamplingPercentage); } else if (sampling.percentage != null) { SamplingPercentage samplingPercentage; - if (sampling.percentage == 100) { + if (sampling.percentage == 100 && !Boolean.FALSE.equals(sampling.ingestion)) { samplingPercentage = SamplingPercentage.useIngestionSampling(); } else { samplingPercentage = SamplingPercentage.fixed(sampling.percentage); } sampler = new AiSampler(samplingPercentage, samplingPercentage); + } else if (Boolean.TRUE.equals(sampling.ingestion)) { + SamplingPercentage samplingPercentage = SamplingPercentage.useIngestionSampling(); + sampler = new AiSampler(samplingPercentage, samplingPercentage); } else { throw new AssertionError("ConfigurationBuilder should have set the default sampling"); } diff --git a/smoke-tests/apps/Sampling/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleSamplingServlet.java b/smoke-tests/apps/Sampling/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleSamplingServlet.java deleted file mode 100644 index 1fb821574ac..00000000000 --- a/smoke-tests/apps/Sampling/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleSamplingServlet.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -package com.microsoft.applicationinsights.smoketestapp; - -import com.microsoft.applicationinsights.TelemetryClient; -import com.microsoft.applicationinsights.telemetry.EventTelemetry; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -@WebServlet("/sampling") -public class SimpleSamplingServlet extends HttpServlet { - - private static final Logger logger = Logger.getLogger(SimpleSamplingServlet.class.getName()); - - private final TelemetryClient client = new TelemetryClient(); - - private final AtomicInteger count = new AtomicInteger(); - - protected void doGet(HttpServletRequest request, HttpServletResponse response) { - client.trackEvent(new EventTelemetry("Event Test " + count.getAndIncrement())); - logger.log(Level.WARNING, "test"); - } -} diff --git a/smoke-tests/apps/Sampling/src/main/java/com/microsoft/applicationinsights/smoketestapp/NoSamplingServlet.java b/smoke-tests/apps/Sampling/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleServlet.java similarity index 84% rename from smoke-tests/apps/Sampling/src/main/java/com/microsoft/applicationinsights/smoketestapp/NoSamplingServlet.java rename to smoke-tests/apps/Sampling/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleServlet.java index 8ffdac69c8c..9cbc0ebecd5 100644 --- a/smoke-tests/apps/Sampling/src/main/java/com/microsoft/applicationinsights/smoketestapp/NoSamplingServlet.java +++ b/smoke-tests/apps/Sampling/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleServlet.java @@ -13,10 +13,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -@WebServlet("/no-sampling") -public class NoSamplingServlet extends HttpServlet { +@WebServlet("/simple") +public class SimpleServlet extends HttpServlet { - private static final Logger logger = Logger.getLogger(NoSamplingServlet.class.getName()); + private static final Logger logger = Logger.getLogger(SimpleServlet.class.getName()); private final TelemetryClient client = new TelemetryClient(); diff --git a/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/IngestionSamplingTest.java b/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/IngestionSamplingTest.java index c297379b9ca..269ba1d4a0c 100644 --- a/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/IngestionSamplingTest.java +++ b/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/IngestionSamplingTest.java @@ -27,25 +27,25 @@ abstract class IngestionSamplingTest { @RegisterExtension static final SmokeTestExtension testing = SmokeTestExtension.create(); @Test - @TargetUri(value = "/no-sampling", callCount = 1000) - void testNoSampling() throws Exception { + @TargetUri(value = "/simple", callCount = 100) + void testIngestionSampling() throws Exception { long start = System.nanoTime(); - while (testing.mockedIngestion.getCountForType("RequestData") < 1000 + while (testing.mockedIngestion.getCountForType("RequestData") < 100 && NANOSECONDS.toSeconds(System.nanoTime() - start) < 10) { // just wait and do nothing } Thread.sleep(SECONDS.toMillis(10)); - assertThat(testing.mockedIngestion.getCountForType("RequestData")).isEqualTo(1000); + assertThat(testing.mockedIngestion.getCountForType("RequestData")).isEqualTo(100); List requestEnvelopes = testing.mockedIngestion.getItemsEnvelopeDataType("RequestData"); - assertThat(requestEnvelopes.size()).isEqualTo(1000); + assertThat(requestEnvelopes.size()).isEqualTo(100); List eventEnvelopes = testing.mockedIngestion.getItemsEnvelopeDataType("EventData"); - assertThat(eventEnvelopes.size()).isEqualTo(1000); + assertThat(eventEnvelopes.size()).isEqualTo(100); List messageEnvelopes = testing.mockedIngestion.getItemsEnvelopeDataType("MessageData"); - assertThat(messageEnvelopes.size()).isEqualTo(1000); + assertThat(messageEnvelopes.size()).isEqualTo(100); for (Envelope requestEnvelope : requestEnvelopes) { assertThat(requestEnvelope.getSampleRate()).isNull(); diff --git a/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/NoIngestionSamplingTest.java b/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/NoIngestionSamplingTest.java new file mode 100644 index 00000000000..eef18952d23 --- /dev/null +++ b/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/NoIngestionSamplingTest.java @@ -0,0 +1,87 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.microsoft.applicationinsights.smoketest; + +import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.TOMCAT_8_JAVA_11; +import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.TOMCAT_8_JAVA_11_OPENJ9; +import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.TOMCAT_8_JAVA_17; +import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.TOMCAT_8_JAVA_21; +import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.TOMCAT_8_JAVA_21_OPENJ9; +import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.TOMCAT_8_JAVA_8; +import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.TOMCAT_8_JAVA_8_OPENJ9; +import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.WILDFLY_13_JAVA_8; +import static com.microsoft.applicationinsights.smoketest.EnvironmentValue.WILDFLY_13_JAVA_8_OPENJ9; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.assertj.core.api.Assertions.assertThat; + +import com.microsoft.applicationinsights.smoketest.schemav2.Envelope; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +@UseAgent("applicationinsights-no-ingestion-sampling.json") +abstract class NoIngestionSamplingTest { + + @RegisterExtension static final SmokeTestExtension testing = SmokeTestExtension.create(); + + @Test + @TargetUri(value = "/simple", callCount = 100) + void testNoIngestionSampling() throws Exception { + long start = System.nanoTime(); + while (testing.mockedIngestion.getCountForType("RequestData") < 100 + && NANOSECONDS.toSeconds(System.nanoTime() - start) < 10) { + // just wait and do nothing + } + Thread.sleep(SECONDS.toMillis(10)); + + assertThat(testing.mockedIngestion.getCountForType("RequestData")).isEqualTo(100); + + List requestEnvelopes = + testing.mockedIngestion.getItemsEnvelopeDataType("RequestData"); + assertThat(requestEnvelopes.size()).isEqualTo(100); + List eventEnvelopes = testing.mockedIngestion.getItemsEnvelopeDataType("EventData"); + assertThat(eventEnvelopes.size()).isEqualTo(100); + List messageEnvelopes = + testing.mockedIngestion.getItemsEnvelopeDataType("MessageData"); + assertThat(messageEnvelopes.size()).isEqualTo(100); + + for (Envelope requestEnvelope : requestEnvelopes) { + assertThat(requestEnvelope.getSampleRate()).isEqualTo(100); + } + for (Envelope eventEnvelope : eventEnvelopes) { + assertThat(eventEnvelope.getSampleRate()).isEqualTo(100); + } + for (Envelope messageEnvelope : messageEnvelopes) { + assertThat(messageEnvelope.getSampleRate()).isEqualTo(100); + } + } + + @Environment(TOMCAT_8_JAVA_8) + static class Tomcat8Java8Test extends NoIngestionSamplingTest {} + + @Environment(TOMCAT_8_JAVA_8_OPENJ9) + static class Tomcat8Java8OpenJ9Test extends NoIngestionSamplingTest {} + + @Environment(TOMCAT_8_JAVA_11) + static class Tomcat8Java11Test extends NoIngestionSamplingTest {} + + @Environment(TOMCAT_8_JAVA_11_OPENJ9) + static class Tomcat8Java11OpenJ9Test extends NoIngestionSamplingTest {} + + @Environment(TOMCAT_8_JAVA_17) + static class Tomcat8Java17Test extends NoIngestionSamplingTest {} + + @Environment(TOMCAT_8_JAVA_21) + static class Tomcat8Java21Test extends NoIngestionSamplingTest {} + + @Environment(TOMCAT_8_JAVA_21_OPENJ9) + static class Tomcat8Java21OpenJ9Test extends NoIngestionSamplingTest {} + + @Environment(WILDFLY_13_JAVA_8) + static class Wildfly13Java8Test extends NoIngestionSamplingTest {} + + @Environment(WILDFLY_13_JAVA_8_OPENJ9) + static class Wildfly13Java8OpenJ9Test extends NoIngestionSamplingTest {} +} diff --git a/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/SamplingTest.java b/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/SamplingTest.java index 38c47f67d78..abf2dc639b5 100644 --- a/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/SamplingTest.java +++ b/smoke-tests/apps/Sampling/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/SamplingTest.java @@ -27,7 +27,7 @@ abstract class SamplingTest { @RegisterExtension static final SmokeTestExtension testing = SmokeTestExtension.create(); @Test - @TargetUri(value = "/sampling", callCount = 100) + @TargetUri(value = "/simple", callCount = 100) void testSampling() throws Exception { // super super low chance that number of sampled requests is less than 25 long start = System.nanoTime(); diff --git a/smoke-tests/apps/Sampling/src/smokeTest/resources/applicationinsights-no-ingestion-sampling.json b/smoke-tests/apps/Sampling/src/smokeTest/resources/applicationinsights-no-ingestion-sampling.json new file mode 100644 index 00000000000..a3fca99282e --- /dev/null +++ b/smoke-tests/apps/Sampling/src/smokeTest/resources/applicationinsights-no-ingestion-sampling.json @@ -0,0 +1,10 @@ +{ + "role": { + "name": "testrolename", + "instance": "testroleinstance" + }, + "sampling": { + "percentage": 100, + "ingestion": false + } +}