Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.microsoft.applicationinsights.agent.internal.profiler.Profiler;
import com.microsoft.applicationinsights.agent.internal.profiler.ProfilerControl;
import com.microsoft.applicationinsights.agent.internal.profiler.upload.ServiceProfilerIndex;
import com.microsoft.applicationinsights.agent.internal.sampling.SamplerUtil;
import com.microsoft.applicationinsights.agent.internal.telemetry.TelemetryClient;
import com.microsoft.applicationinsights.agent.internal.telemetry.TelemetryObservers;
import com.microsoft.applicationinsights.alerting.AlertingSubsystem;
Expand Down Expand Up @@ -149,6 +150,7 @@ private static void sendServiceProfilerIndex(
EventTelemetryBuilder telemetryBuilder = telemetryClient.newEventTelemetryBuilder();

telemetryBuilder.setName("ServiceProfilerIndex");
telemetryBuilder.setSampleRate((float) SamplerUtil.SAMPLE_RATE_TO_DISABLE_INGESTION_SAMPLING);

for (Map.Entry<String, String> entry : serviceProfilerIndex.getProperties().entrySet()) {
telemetryBuilder.addProperty(entry.getKey(), entry.getValue());
Expand All @@ -170,6 +172,7 @@ private static void sendMessageTelemetry(TelemetryClient telemetryClient, String
MessageTelemetryBuilder telemetryBuilder = telemetryClient.newMessageTelemetryBuilder();

telemetryBuilder.setMessage(message);
telemetryBuilder.setSampleRate((float) SamplerUtil.SAMPLE_RATE_TO_DISABLE_INGESTION_SAMPLING);
telemetryBuilder.setTime(FormattedTime.offSetDateTimeFromNow());

telemetryClient.trackAsync(telemetryBuilder.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.azure.monitor.opentelemetry.autoconfigure.implementation.utils.FormattedTime;
import com.microsoft.applicationinsights.agent.internal.configuration.GcReportingLevel;
import com.microsoft.applicationinsights.agent.internal.profiler.util.ServiceLoaderUtil;
import com.microsoft.applicationinsights.agent.internal.sampling.SamplerUtil;
import com.microsoft.applicationinsights.agent.internal.telemetry.TelemetryClient;
import com.microsoft.applicationinsights.alerting.AlertingSubsystem;
import com.microsoft.applicationinsights.alerting.config.AlertMetricType;
Expand Down Expand Up @@ -125,6 +126,7 @@ private static void emitGcEvent(
EventTelemetryBuilder telemetryBuilder = telemetryClient.newEventTelemetryBuilder();

telemetryBuilder.setName("GcEvent");
telemetryBuilder.setSampleRate((float) SamplerUtil.SAMPLE_RATE_TO_DISABLE_INGESTION_SAMPLING);

telemetryBuilder.addProperty("collector", event.getCollector().getName());
telemetryBuilder.addProperty("type", event.getGcCause());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

public class SamplerUtil {

private static final double SAMPLE_RATE_TO_DISABLE_INGESTION_SAMPLING = 99.99;
public static final double SAMPLE_RATE_TO_DISABLE_INGESTION_SAMPLING = 99.99;

private static final Cache<Double, SamplingResult> recordAndSampleWithSampleRateMap =
Cache.bounded(100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@

import static org.assertj.core.api.Assertions.assertThat;

import com.azure.monitor.opentelemetry.autoconfigure.implementation.builders.EventTelemetryBuilder;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.models.TelemetryItem;
import com.microsoft.applicationinsights.agent.internal.configuration.GcReportingLevel;
import com.microsoft.applicationinsights.agent.internal.profiler.testutil.TestTimeSource;
import com.microsoft.applicationinsights.agent.internal.sampling.SamplerUtil;
import com.microsoft.applicationinsights.agent.internal.telemetry.TelemetryClient;
import com.microsoft.applicationinsights.alerting.AlertingSubsystem;
import com.microsoft.applicationinsights.alerting.alert.AlertBreach;
Expand All @@ -29,10 +32,59 @@
import java.util.concurrent.TimeoutException;
import javax.management.MBeanServerConnection;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

class GcEventInitTest {

@Test
void gcEventIsEmittedWithSampleRateThatBypassesIngestionSampling() {

TelemetryClient telemetryClient = Mockito.mock(TelemetryClient.class);
Mockito.when(telemetryClient.newEventTelemetryBuilder())
.thenReturn(EventTelemetryBuilder.create());

CompletableFuture<AlertBreach> alertFuture = new CompletableFuture<>();
TestTimeSource timeSource = new TestTimeSource();
AlertingSubsystem alertingSubsystem = getAlertingSubsystem(alertFuture, timeSource);

GcMonitorFactory factory =
new GcMonitorFactory() {
@Override
public MemoryManagement monitorSelf(
ExecutorService executorService, GcEventConsumer consumer) {
consumer.accept(fullyMockedGcEvent());
return null;
}

@Override
public MemoryManagement monitor(
MBeanServerConnection connection,
ExecutorService executorService,
GcEventConsumer consumer) {
return null;
}
};

ExecutorService executorService = Executors.newSingleThreadExecutor();
try {
GcEventInit.init(
alertingSubsystem,
telemetryClient,
executorService,
new GcEventInit.GcEventMonitorConfiguration(GcReportingLevel.ALL),
factory);

ArgumentCaptor<TelemetryItem> captor = ArgumentCaptor.forClass(TelemetryItem.class);
Mockito.verify(telemetryClient).trackAsync(captor.capture());

assertThat(captor.getValue().getSampleRate())
.isEqualTo((float) SamplerUtil.SAMPLE_RATE_TO_DISABLE_INGESTION_SAMPLING);
} finally {
executorService.shutdownNow();
}
}

@Test
void endToEndAlertIsTriggered()
throws ExecutionException, InterruptedException, TimeoutException {
Expand Down Expand Up @@ -102,4 +154,25 @@ private static GcCollectionEvent mockGcEvent() {
.thenReturn(new MemoryUsage(1, 9, 10, 10));
return event;
}

private static GcCollectionEvent fullyMockedGcEvent() {
GcCollectionEvent event = Mockito.mock(GcCollectionEvent.class);
GarbageCollector collector = Mockito.mock(GarbageCollector.class);
MemoryPool tenuredPool = Mockito.mock(MemoryPool.class);
MemoryUsage memoryUsage = new MemoryUsage(1, 9, 10, 10);

Mockito.when(collector.isTenuredCollector()).thenReturn(true);
Mockito.when(collector.getName()).thenReturn("test-collector");
Mockito.when(event.getCollector()).thenReturn(collector);
Mockito.when(event.getGcCause()).thenReturn("test-cause");
Mockito.when(event.getGcAction()).thenReturn("test-action");
Mockito.when(event.getTenuredPool()).thenReturn(Optional.of(tenuredPool));
Mockito.when(event.getMemoryUsageBeforeGc(Mockito.any(MemoryPool.class)))
.thenReturn(memoryUsage);
Mockito.when(event.getMemoryUsageAfterGc(Mockito.any(MemoryPool.class)))
.thenReturn(memoryUsage);
Mockito.when(event.getMemoryUsageBeforeGc(Mockito.anyList())).thenReturn(memoryUsage);
Mockito.when(event.getMemoryUsageAfterGc(Mockito.anyList())).thenReturn(memoryUsage);
return event;
}
}