Skip to content

Commit

Permalink
Introduce explicit option for disabling ingestion sampling
Browse files Browse the repository at this point in the history
  • Loading branch information
trask committed May 21, 2024
1 parent dac7666 commit e7f0df0
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Envelope> requestEnvelopes =
testing.mockedIngestion.getItemsEnvelopeDataType("RequestData");
assertThat(requestEnvelopes.size()).isEqualTo(1000);
assertThat(requestEnvelopes.size()).isEqualTo(100);
List<Envelope> eventEnvelopes = testing.mockedIngestion.getItemsEnvelopeDataType("EventData");
assertThat(eventEnvelopes.size()).isEqualTo(1000);
assertThat(eventEnvelopes.size()).isEqualTo(100);
List<Envelope> messageEnvelopes =
testing.mockedIngestion.getItemsEnvelopeDataType("MessageData");
assertThat(messageEnvelopes.size()).isEqualTo(1000);
assertThat(messageEnvelopes.size()).isEqualTo(100);

for (Envelope requestEnvelope : requestEnvelopes) {
assertThat(requestEnvelope.getSampleRate()).isNull();
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Envelope> requestEnvelopes =
testing.mockedIngestion.getItemsEnvelopeDataType("RequestData");
assertThat(requestEnvelopes.size()).isEqualTo(100);
List<Envelope> eventEnvelopes = testing.mockedIngestion.getItemsEnvelopeDataType("EventData");
assertThat(eventEnvelopes.size()).isEqualTo(100);
List<Envelope> 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 {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"role": {
"name": "testrolename",
"instance": "testroleinstance"
},
"sampling": {
"percentage": 100,
"ingestion": false
}
}

0 comments on commit e7f0df0

Please sign in to comment.