Skip to content

Commit 814f134

Browse files
committed
logging statements and some sampler changes and live metrics span processor
1 parent 2476624 commit 814f134

File tree

10 files changed

+168
-71
lines changed

10 files changed

+168
-71
lines changed

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/exporter/AgentLogExporter.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ public AgentLogExporter(
6161
telemetryItemConsumer =
6262
telemetryItem -> {
6363
if (quickPulse != null) {
64+
try {
65+
logger.info("quickpulse.add from Log telemetryItemConsumer for {}", telemetryItem.getData().toJsonString());
66+
} catch (Exception e) {
67+
logger.error("failed to log telemetry item ", e);
68+
}
69+
6470
quickPulse.add(telemetryItem);
6571
}
6672
TelemetryObservers.INSTANCE
@@ -136,6 +142,7 @@ private void internalExport(LogRecordData log) {
136142
if (hasSamplingOverride) {
137143
SamplingResult samplingResult = sampler.shouldSampleLog(spanContext, parentSpanSampleRate);
138144
if (samplingResult.getDecision() != SamplingDecision.RECORD_AND_SAMPLE) {
145+
logger.info("Sampling out log: {}", log.getBodyValue().asString());
139146
return;
140147
}
141148
sampleRate = samplingResult.getAttributes().get(AiSemanticAttributes.SAMPLE_RATE);

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/exporter/AgentSpanExporter.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,10 @@ public final class AgentSpanExporter implements SpanExporter {
3434

3535
public AgentSpanExporter(
3636
SpanDataMapper mapper,
37-
@Nullable QuickPulse quickPulse,
3837
BatchItemProcessor batchItemProcessor) {
3938
this.mapper = mapper;
4039
telemetryItemConsumer =
4140
telemetryItem -> {
42-
if (quickPulse != null) {
43-
quickPulse.add(telemetryItem);
44-
}
4541
TelemetryObservers.INSTANCE
4642
.getObservers()
4743
.forEach(consumer -> consumer.accept(telemetryItem));

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/RuntimeConfigurator.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import ch.qos.logback.classic.LoggerContext;
99
import com.azure.monitor.opentelemetry.autoconfigure.implementation.heartbeat.HeartbeatExporter;
1010
import com.azure.monitor.opentelemetry.autoconfigure.implementation.models.TelemetryItem;
11+
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.QuickPulse;
1112
import com.azure.monitor.opentelemetry.autoconfigure.implementation.utils.Strings;
1213
import com.microsoft.applicationinsights.agent.internal.classicsdk.BytecodeUtilImpl;
1314
import com.microsoft.applicationinsights.agent.internal.configuration.Configuration;
@@ -198,15 +199,17 @@ static void updatePropagation(
198199
static void updateSampling(
199200
boolean enabled,
200201
Configuration.Sampling sampling,
201-
Configuration.SamplingPreview samplingPreview) {
202+
Configuration.SamplingPreview samplingPreview,
203+
QuickPulse quickPulse) {
202204

203205
if (!enabled) {
204206
DelegatingSampler.getInstance().reset();
205207
BytecodeUtilImpl.samplingPercentage = 0;
206208
return;
207209
}
208210

209-
DelegatingSampler.getInstance().setDelegate(Samplers.getSampler(sampling, samplingPreview));
211+
DelegatingSampler.getInstance().setDelegate(Samplers.getSampler(sampling, samplingPreview, quickPulse));
212+
// call setQuickPulse method here in delegate
210213
if (sampling.percentage != null) {
211214
BytecodeUtilImpl.samplingPercentage = sampling.percentage.floatValue();
212215
} else {

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/SecondEntryPoint.java

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.azure.monitor.opentelemetry.autoconfigure.implementation.AzureMonitorLogRecordExporterProvider;
1212
import com.azure.monitor.opentelemetry.autoconfigure.implementation.AzureMonitorMetricExporterProvider;
1313
import com.azure.monitor.opentelemetry.autoconfigure.implementation.AzureMonitorSpanExporterProvider;
14+
import com.azure.monitor.opentelemetry.autoconfigure.implementation.LiveMetricsSpanProcessor;
1415
import com.azure.monitor.opentelemetry.autoconfigure.implementation.LogDataMapper;
1516
import com.azure.monitor.opentelemetry.autoconfigure.implementation.MetricDataMapper;
1617
import com.azure.monitor.opentelemetry.autoconfigure.implementation.SpanDataMapper;
@@ -240,6 +241,13 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) {
240241

241242
AtomicBoolean firstLogRecordProcessor = new AtomicBoolean(true);
242243

244+
245+
List<Configuration.SamplingOverride> exceptionSamplingOverrides =
246+
configuration.preview.sampling.overrides.stream()
247+
.filter(override -> override.telemetryType == SamplingTelemetryType.EXCEPTION)
248+
.collect(Collectors.toList());
249+
SpanDataMapper mapper = createSpanDataMapper(telemetryClient, configuration.preview.captureHttpServer4xxAsError, new SamplingOverrides(exceptionSamplingOverrides));
250+
243251
autoConfiguration
244252
.addPropertiesSupplier(
245253
() -> {
@@ -279,7 +287,7 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) {
279287
.addSpanExporterCustomizer(
280288
(spanExporter, configProperties) -> {
281289
if (spanExporter instanceof AzureMonitorSpanExporterProvider.MarkerSpanExporter) {
282-
return buildTraceExporter(configuration, telemetryClient, quickPulse);
290+
return buildTraceExporter(configuration, telemetryClient, mapper);
283291
}
284292
return wrapSpanExporter(spanExporter, configuration);
285293
})
@@ -302,7 +310,7 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) {
302310
}
303311
})
304312
.addTracerProviderCustomizer(
305-
(builder, otelConfig) -> configureTracing(builder, configuration))
313+
(builder, otelConfig) -> configureTracing(builder, configuration, quickPulse, mapper))
306314
.addMeterProviderCustomizer(
307315
(builder, otelConfig) -> configureMetrics(builder, configuration));
308316

@@ -320,17 +328,12 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) {
320328
}
321329

322330
private static SpanExporter buildTraceExporter(
323-
Configuration configuration, TelemetryClient telemetryClient, QuickPulse quickPulse) {
324-
List<Configuration.SamplingOverride> exceptionSamplingOverrides =
325-
configuration.preview.sampling.overrides.stream()
326-
.filter(override -> override.telemetryType == SamplingTelemetryType.EXCEPTION)
327-
.collect(Collectors.toList());
331+
Configuration configuration, TelemetryClient telemetryClient, SpanDataMapper mapper) {
332+
startupLogger.info("calling createSpanExporter");
328333
SpanExporter spanExporter =
329334
createSpanExporter(
330335
telemetryClient,
331-
quickPulse,
332-
configuration.preview.captureHttpServer4xxAsError,
333-
new SamplingOverrides(exceptionSamplingOverrides));
336+
mapper);
334337

335338
return wrapSpanExporter(spanExporter, configuration);
336339
}
@@ -519,15 +522,15 @@ private static Set<Feature> initStatsbeatFeatureSet(Configuration config) {
519522
}
520523

521524
private static SdkTracerProviderBuilder configureTracing(
522-
SdkTracerProviderBuilder tracerProvider, Configuration configuration) {
525+
SdkTracerProviderBuilder tracerProvider, Configuration configuration, QuickPulse quickPulse, SpanDataMapper mapper) {
523526

524527
boolean enabled = !Strings.isNullOrEmpty(configuration.connectionString);
525528
RuntimeConfigurator.updatePropagation(
526529
!configuration.preview.disablePropagation && enabled,
527530
configuration.preview.additionalPropagators,
528531
configuration.preview.legacyRequestIdPropagation.enabled);
529532
RuntimeConfigurator.updateSampling(
530-
enabled, configuration.sampling, configuration.preview.sampling);
533+
enabled, configuration.sampling, configuration.preview.sampling, quickPulse);
531534

532535
tracerProvider.addSpanProcessor(new AzureMonitorSpanProcessor());
533536
if (!configuration.preview.inheritedAttributes.isEmpty()) {
@@ -551,51 +554,60 @@ private static SdkTracerProviderBuilder configureTracing(
551554
tracerProvider.addSpanProcessor(new AiLegacyHeaderSpanProcessor());
552555
}
553556

557+
if (quickPulse != null) {
558+
tracerProvider.addSpanProcessor(new LiveMetricsSpanProcessor(quickPulse, mapper));
559+
}
560+
554561
return tracerProvider;
555562
}
556563

557-
private static SpanExporter createSpanExporter(
564+
private static SpanDataMapper createSpanDataMapper(
558565
TelemetryClient telemetryClient,
559-
@Nullable QuickPulse quickPulse,
560566
boolean captureHttpServer4xxAsError,
561567
SamplingOverrides exceptionSamplingOverrides) {
568+
return new SpanDataMapper(
569+
captureHttpServer4xxAsError,
570+
telemetryClient::populateDefaults,
571+
(event, instrumentationName) -> {
572+
boolean lettuce51 = instrumentationName.equals("io.opentelemetry.lettuce-5.1");
573+
if (lettuce51 && event.getName().startsWith("redis.encode.")) {
574+
// special case as these are noisy and come from the underlying library itself
575+
return true;
576+
}
577+
boolean grpc16 = instrumentationName.equals("io.opentelemetry.grpc-1.6");
578+
if (grpc16 && event.getName().equals("message")) {
579+
// OpenTelemetry semantic conventions define semi-noisy grpc events
580+
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/rpc.md#events
581+
//
582+
// we want to suppress these (at least by default)
583+
return true;
584+
}
585+
return false;
586+
},
587+
(span, event) -> {
588+
AiFixedPercentageSampler sampler =
589+
exceptionSamplingOverrides.getOverride(event.getAttributes());
590+
startupLogger.info("Calling span sampling function with span id {}, event name {}, is sampler null {}, sampler decision {}",
591+
span.getSpanContext().getSpanId(), event.getName(), sampler != null);
592+
return sampler != null
593+
&& sampler
594+
.shouldSampleLog(
595+
span.getSpanContext(),
596+
span.getAttributes().get(AiSemanticAttributes.SAMPLE_RATE))
597+
.getDecision()
598+
== SamplingDecision.DROP;
599+
});
600+
}
562601

563-
SpanDataMapper mapper =
564-
new SpanDataMapper(
565-
captureHttpServer4xxAsError,
566-
telemetryClient::populateDefaults,
567-
(event, instrumentationName) -> {
568-
boolean lettuce51 = instrumentationName.equals("io.opentelemetry.lettuce-5.1");
569-
if (lettuce51 && event.getName().startsWith("redis.encode.")) {
570-
// special case as these are noisy and come from the underlying library itself
571-
return true;
572-
}
573-
boolean grpc16 = instrumentationName.equals("io.opentelemetry.grpc-1.6");
574-
if (grpc16 && event.getName().equals("message")) {
575-
// OpenTelemetry semantic conventions define semi-noisy grpc events
576-
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/rpc.md#events
577-
//
578-
// we want to suppress these (at least by default)
579-
return true;
580-
}
581-
return false;
582-
},
583-
(span, event) -> {
584-
AiFixedPercentageSampler sampler =
585-
exceptionSamplingOverrides.getOverride(event.getAttributes());
586-
return sampler != null
587-
&& sampler
588-
.shouldSampleLog(
589-
span.getSpanContext(),
590-
span.getAttributes().get(AiSemanticAttributes.SAMPLE_RATE))
591-
.getDecision()
592-
== SamplingDecision.DROP;
593-
});
594602

595-
BatchItemProcessor batchItemProcessor = telemetryClient.getGeneralBatchItemProcessor();
603+
private static SpanExporter createSpanExporter(
604+
TelemetryClient telemetryClient,
605+
SpanDataMapper mapper) {
596606

607+
BatchItemProcessor batchItemProcessor = telemetryClient.getGeneralBatchItemProcessor();
608+
startupLogger.info("Create agentSpanExporter for statsbeat");
597609
return new StatsbeatSpanExporter(
598-
new AgentSpanExporter(mapper, quickPulse, batchItemProcessor),
610+
new AgentSpanExporter(mapper, batchItemProcessor),
599611
telemetryClient.getStatsbeatModule());
600612
}
601613

@@ -611,9 +623,11 @@ private static SpanExporter wrapSpanExporter(
611623
for (ProcessorConfig processorConfig : processorConfigs) {
612624
switch (processorConfig.type) {
613625
case ATTRIBUTE:
626+
startupLogger.info("Adding attribute processor to span exporter");
614627
spanExporter = new SpanExporterWithAttributeProcessor(processorConfig, spanExporter);
615628
break;
616629
case SPAN:
630+
startupLogger.info("Adding span processor to span exporter");
617631
spanExporter = new ExporterWithSpanProcessor(processorConfig, spanExporter);
618632
break;
619633
default:

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/sampling/AiFixedPercentageSampler.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
package com.microsoft.applicationinsights.agent.internal.sampling;
55

6+
import com.azure.core.util.logging.ClientLogger;
67
import com.azure.monitor.opentelemetry.autoconfigure.implementation.AiSemanticAttributes;
8+
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.QuickPulse;
79
import io.opentelemetry.api.common.Attributes;
810
import io.opentelemetry.api.trace.Span;
911
import io.opentelemetry.api.trace.SpanContext;
@@ -20,12 +22,17 @@ public class AiFixedPercentageSampler implements Sampler {
2022

2123
private final double percentage;
2224

23-
public static AiFixedPercentageSampler create(double percentage) {
24-
return new AiFixedPercentageSampler(percentage);
25+
private static final ClientLogger logger = new ClientLogger(AiFixedPercentageSampler.class);
26+
27+
private final QuickPulse quickPulse;
28+
29+
public static AiFixedPercentageSampler create(double percentage, QuickPulse quickPulse) {
30+
return new AiFixedPercentageSampler(percentage, quickPulse);
2531
}
2632

27-
private AiFixedPercentageSampler(double percentage) {
33+
private AiFixedPercentageSampler(double percentage, QuickPulse quickPulse) {
2834
this.percentage = percentage;
35+
this.quickPulse = quickPulse;
2936
}
3037

3138
@Override
@@ -37,18 +44,26 @@ public SamplingResult shouldSample(
3744
Attributes attributes,
3845
List<LinkData> parentLinks) {
3946

47+
String spanId = "";
48+
if (!parentLinks.isEmpty()) {
49+
spanId = parentLinks.get(0).getSpanContext().getSpanId();
50+
}
51+
logger.info("shouldSample called with traceId {}, name {}, a span id {}",
52+
traceId, name, spanId);
4053
Span parentSpan = Span.fromContext(parentContext);
4154
SpanContext parentSpanContext = parentSpan.getSpanContext();
4255
Double parentSpanSampleRate = null;
4356
if (parentSpan instanceof ReadableSpan) {
4457
parentSpanSampleRate =
4558
((ReadableSpan) parentSpan).getAttribute(AiSemanticAttributes.SAMPLE_RATE);
4659
}
47-
60+
logger.info("caliing internalShouldSample from shouldSample with traceId {}, name {}, spanid {}",
61+
traceId, name, spanId);
4862
return internalShouldSample(parentSpanContext, parentSpanSampleRate, traceId);
4963
}
5064

5165
public SamplingResult shouldSampleLog(SpanContext spanContext, @Nullable Double spanSampleRate) {
66+
logger.info("Calling internalShouldSample from shouldSampleLog with traceId {} and spanId {}", spanContext.getTraceId(), spanContext.getSpanId());
5267
return internalShouldSample(spanContext, spanSampleRate, spanContext.getTraceId());
5368
}
5469

@@ -58,10 +73,12 @@ private SamplingResult internalShouldSample(
5873
SamplingResult samplingResult =
5974
useLocalParentDecisionIfPossible(parentSpanContext, parentSpanSampleRate);
6075
if (samplingResult != null) {
76+
logger.info("sampling result: {}", samplingResult.getDecision().toString());
6177
return samplingResult;
6278
}
63-
64-
return SamplerUtil.shouldSample(traceId, percentage);
79+
samplingResult = SamplerUtil.shouldSample(traceId, percentage);
80+
logger.info("sampling result: {}", samplingResult.getDecision().toString());
81+
return samplingResult;//SamplerUtil.shouldSample(traceId, percentage);
6582
}
6683

6784
@Nullable
@@ -78,6 +95,9 @@ private SamplingResult useLocalParentDecisionIfPossible(
7895

7996
if (!parentSpanContext.isSampled()) {
8097
if (percentage < 100) {
98+
if (quickPulse != null && quickPulse.isEnabled()) {
99+
return SamplingResult.recordOnly();
100+
}
81101
// only 100% sampling override will override an unsampled parent!!
82102
return SamplingResult.drop();
83103
} else {

0 commit comments

Comments
 (0)