55
66import com .azure .monitor .opentelemetry .autoconfigure .implementation .AiSemanticAttributes ;
77import com .azure .monitor .opentelemetry .autoconfigure .implementation .RequestChecker ;
8- import com .azure .monitor .opentelemetry .autoconfigure .implementation .SamplingScoreGeneratorV2 ;
98import io .opentelemetry .api .common .Attributes ;
109import io .opentelemetry .api .trace .Span ;
1110import io .opentelemetry .api .trace .SpanContext ;
1211import io .opentelemetry .api .trace .SpanKind ;
1312import io .opentelemetry .context .Context ;
14- import io .opentelemetry .instrumentation .api .internal .cache .Cache ;
1513import io .opentelemetry .sdk .trace .ReadableSpan ;
1614import io .opentelemetry .sdk .trace .data .LinkData ;
1715import io .opentelemetry .sdk .trace .samplers .Sampler ;
18- import io .opentelemetry .sdk .trace .samplers .SamplingDecision ;
1916import io .opentelemetry .sdk .trace .samplers .SamplingResult ;
2017import java .util .List ;
2118import javax .annotation .Nullable ;
2724// * adds item count to span attribute if it is sampled
2825public class AiSampler implements Sampler {
2926
30- private static final double SAMPLE_RATE_TO_DISABLE_INGESTION_SAMPLING = 99.99 ;
31-
3227 private final SamplingPercentage requestSamplingPercentage ;
3328 private final SamplingPercentage parentlessDependencySamplingPercentage ;
3429 private final boolean ingestionSamplingEnabled ;
35- private final boolean override ;
36-
37- private final Cache <Double , SamplingResult > recordAndSampleWithSampleRateMap = Cache .bounded (100 );
3830
3931 public static AiSampler create (
4032 SamplingPercentage requestSamplingPercentage ,
@@ -43,26 +35,16 @@ public static AiSampler create(
4335 return new AiSampler (
4436 requestSamplingPercentage ,
4537 parentlessDependencySamplingPercentage ,
46- ingestionSamplingEnabled ,
47- false );
48- }
49-
50- public static AiSampler createSamplingOverride (
51- SamplingPercentage samplingPercentage ,
52- boolean sampleWhenLocalParentSampled ,
53- boolean dropWhenLocalParentDropped ) {
54- return new AiSampler (samplingPercentage , samplingPercentage , false , true );
38+ ingestionSamplingEnabled );
5539 }
5640
5741 private AiSampler (
5842 SamplingPercentage requestSamplingPercentage ,
5943 SamplingPercentage parentlessDependencySamplingPercentage ,
60- boolean ingestionSamplingEnabled ,
61- boolean override ) {
44+ boolean ingestionSamplingEnabled ) {
6245 this .requestSamplingPercentage = requestSamplingPercentage ;
6346 this .parentlessDependencySamplingPercentage = parentlessDependencySamplingPercentage ;
6447 this .ingestionSamplingEnabled = ingestionSamplingEnabled ;
65- this .override = override ;
6648 }
6749
6850 @ Override
@@ -82,30 +64,6 @@ public SamplingResult shouldSample(
8264 ((ReadableSpan ) parentSpan ).getAttribute (AiSemanticAttributes .SAMPLE_RATE );
8365 }
8466
85- return internalShouldSample (
86- parentSpanContext , parentSpanSampleRate , traceId , spanKind , attributes );
87- }
88-
89- public SamplingResult shouldSampleLog (SpanContext spanContext , @ Nullable Double spanSampleRate ) {
90- return internalShouldSample (
91- spanContext ,
92- spanSampleRate ,
93- spanContext .getTraceId (),
94- SpanKind .INTERNAL , // unused
95- Attributes .empty ());
96- }
97-
98- public SamplingPercentage getParentlessDependencySamplingPercentage () {
99- return parentlessDependencySamplingPercentage ;
100- }
101-
102- private SamplingResult internalShouldSample (
103- SpanContext parentSpanContext ,
104- @ Nullable Double parentSpanSampleRate ,
105- String traceId ,
106- SpanKind spanKind ,
107- Attributes attributes ) {
108-
10967 SamplingResult samplingResult =
11068 useLocalParentDecisionIfPossible (parentSpanContext , parentSpanSampleRate );
11169 if (samplingResult != null ) {
@@ -124,35 +82,15 @@ private SamplingResult internalShouldSample(
12482 : parentlessDependencySamplingPercentage .get ();
12583 }
12684
127- if (sp == 0 ) {
128- return SamplingResult .drop ();
129- }
130-
131- if (sp != 100 && !shouldRecordAndSample (traceId , sp )) {
132- return SamplingResult .drop ();
133- }
134-
13585 if (sp == 100 && ingestionSamplingEnabled ) {
13686 return SamplingResult .recordAndSample ();
13787 }
13888
139- if (sp == 100 ) {
140- // ingestion sampling is applied when sample rate is 100 (or missing)
141- // so we set it to 99.99 which will bypass ingestion sampling
142- // (and will still be stored as item count 1)
143- sp = SAMPLE_RATE_TO_DISABLE_INGESTION_SAMPLING ;
144- }
145-
146- samplingResult = recordAndSampleWithSampleRateMap .get (sp );
147- if (samplingResult == null ) {
148- samplingResult = new RecordAndSampleWithItemCount (sp );
149- recordAndSampleWithSampleRateMap .put (sp , samplingResult );
150- }
151- return samplingResult ;
89+ return SamplerUtil .shouldSample (traceId , sp );
15290 }
15391
15492 @ Nullable
155- private SamplingResult useLocalParentDecisionIfPossible (
93+ private static SamplingResult useLocalParentDecisionIfPossible (
15694 SpanContext parentSpanContext , @ Nullable Double parentSpanSampleRate ) {
15795
15896 // remote parent-based sampling messes up item counts since item count is not propagated in
@@ -163,77 +101,17 @@ private SamplingResult useLocalParentDecisionIfPossible(
163101 return null ;
164102 }
165103
166- if (!override ) {
167- if (!parentSpanContext .isSampled ()) {
168- return SamplingResult .drop ();
169- }
170- if (parentSpanSampleRate == null ) {
171- return null ;
172- }
173- return new RecordAndSampleWithItemCount (parentSpanSampleRate );
174- }
175-
176- // override case:
177-
178- // note: in the override case, requestSamplingPercentage and
179- // parentlessDependencySamplingPercentage are always the same (and fixed)
180- double sp = parentlessDependencySamplingPercentage .get ();
181-
182104 if (!parentSpanContext .isSampled ()) {
183- if (sp < 100 ) {
184- // only 100% sampling override will override an unsampled parent!!
185- return SamplingResult .drop ();
186- } else {
187- // falls back in this case to sp
188- return null ;
189- }
105+ return SamplingResult .drop ();
190106 }
191-
192107 if (parentSpanSampleRate == null ) {
193108 return null ;
194109 }
195-
196- if (sp < parentSpanSampleRate || sp == 100 ) {
197- // falls back in this case to sp
198- return null ;
199- }
200- // don't sample more dependencies than parent in this case
201- return new RecordAndSampleWithItemCount (parentSpanSampleRate );
202- }
203-
204- public static boolean shouldRecordAndSample (String traceId , double percentage ) {
205- if (percentage == 100 ) {
206- // optimization, no need to calculate score
207- return true ;
208- }
209- if (percentage == 0 ) {
210- // optimization, no need to calculate score
211- return false ;
212- }
213- return SamplingScoreGeneratorV2 .getSamplingScore (traceId ) < percentage ;
110+ return new SamplerUtil .RecordAndSampleWithItemCount (parentSpanSampleRate );
214111 }
215112
216113 @ Override
217114 public String getDescription () {
218115 return "AiSampler" ;
219116 }
220-
221- private static class RecordAndSampleWithItemCount implements SamplingResult {
222-
223- private final Attributes attributes ;
224-
225- RecordAndSampleWithItemCount (double sampleRate ) {
226- attributes = Attributes .builder ().put (AiSemanticAttributes .SAMPLE_RATE , sampleRate ).build ();
227- }
228-
229- @ Override
230- public SamplingDecision getDecision () {
231- return SamplingDecision .RECORD_AND_SAMPLE ;
232- }
233-
234- @ Override
235- public Attributes getAttributes () {
236- return attributes ;
237- }
238- }
239117}
0 commit comments