1111import com .azure .monitor .opentelemetry .autoconfigure .implementation .AzureMonitorLogRecordExporterProvider ;
1212import com .azure .monitor .opentelemetry .autoconfigure .implementation .AzureMonitorMetricExporterProvider ;
1313import com .azure .monitor .opentelemetry .autoconfigure .implementation .AzureMonitorSpanExporterProvider ;
14+ import com .azure .monitor .opentelemetry .autoconfigure .implementation .LiveMetricsSpanProcessor ;
1415import com .azure .monitor .opentelemetry .autoconfigure .implementation .LogDataMapper ;
1516import com .azure .monitor .opentelemetry .autoconfigure .implementation .MetricDataMapper ;
1617import 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 :
0 commit comments