@@ -4,6 +4,7 @@ if Code.ensure_loaded?(:otel_sampler) do
44
55 alias OpenTelemetry . { Span , Tracer }
66 alias Sentry.ClientReport
7+ alias SamplingContext
78
89 @ behaviour :otel_sampler
910
@@ -24,27 +25,47 @@ if Code.ensure_loaded?(:otel_sampler) do
2425 @ impl true
2526 def should_sample (
2627 ctx ,
27- _trace_id ,
28+ trace_id ,
2829 _links ,
2930 span_name ,
30- _span_kind ,
31- _attributes ,
31+ span_kind ,
32+ attributes ,
3233 config
3334 ) do
3435 result =
3536 if span_name in config [ :drop ] do
3637 { :drop , [ ] , [ ] }
3738 else
38- sample_rate = Sentry.Config . traces_sample_rate ( )
39+ traces_sampler = Sentry.Config . traces_sampler ( )
40+ traces_sample_rate = Sentry.Config . traces_sample_rate ( )
3941
4042 case get_trace_sampling_decision ( ctx ) do
4143 { :inherit , trace_sampled , tracestate } ->
42- decision = if trace_sampled , do: :record_and_sample , else: :drop
43-
44- { decision , [ ] , tracestate }
44+ if traces_sampler do
45+ sampling_context =
46+ build_sampling_context (
47+ trace_sampled ,
48+ span_name ,
49+ span_kind ,
50+ attributes ,
51+ trace_id
52+ )
53+
54+ make_sampler_decision ( traces_sampler , sampling_context , tracestate )
55+ else
56+ decision = if trace_sampled , do: :record_and_sample , else: :drop
57+ { decision , [ ] , tracestate }
58+ end
4559
4660 :no_trace ->
47- make_sampling_decision ( sample_rate )
61+ if traces_sampler do
62+ sampling_context =
63+ build_sampling_context ( nil , span_name , span_kind , attributes , trace_id )
64+
65+ make_sampler_decision ( traces_sampler , sampling_context , [ ] )
66+ else
67+ make_sampling_decision ( traces_sample_rate )
68+ end
4869 end
4970 end
5071
@@ -121,6 +142,72 @@ if Code.ensure_loaded?(:otel_sampler) do
121142 end
122143 end
123144
145+ defp build_sampling_context ( parent_sampled , span_name , _span_kind , attributes , trace_id ) do
146+ transaction_context = % {
147+ name: span_name ,
148+ op: span_name ,
149+ trace_id: trace_id ,
150+ attributes: attributes
151+ }
152+
153+ sampling_context = % SamplingContext {
154+ transaction_context: transaction_context ,
155+ parent_sampled: parent_sampled
156+ }
157+
158+ if attributes && map_size ( attributes ) > 0 do
159+ Map . merge ( sampling_context , attributes )
160+ else
161+ sampling_context
162+ end
163+ end
164+
165+ defp make_sampler_decision ( traces_sampler , sampling_context , _existing_tracestate ) do
166+ try do
167+ result = call_traces_sampler ( traces_sampler , sampling_context )
168+ sample_rate = normalize_sampler_result ( result )
169+
170+ cond do
171+ sample_rate == 0.0 ->
172+ tracestate = build_tracestate ( 0.0 , 1.0 , false )
173+ { :drop , [ ] , tracestate }
174+
175+ sample_rate == 1.0 ->
176+ tracestate = build_tracestate ( 1.0 , 0.0 , true )
177+ { :record_and_sample , [ ] , tracestate }
178+
179+ is_float ( sample_rate ) and sample_rate > 0.0 and sample_rate < 1.0 ->
180+ random_value = :rand . uniform ( )
181+ sampled = random_value < sample_rate
182+ tracestate = build_tracestate ( sample_rate , random_value , sampled )
183+ decision = if sampled , do: :record_and_sample , else: :drop
184+ { decision , [ ] , tracestate }
185+
186+ true ->
187+ tracestate = build_tracestate ( 0.0 , 1.0 , false )
188+ { :drop , [ ] , tracestate }
189+ end
190+ rescue
191+ error ->
192+ require Logger
193+ Logger . warning ( "traces_sampler function failed: #{ inspect ( error ) } " )
194+ tracestate = build_tracestate ( 0.0 , 1.0 , false )
195+ { :drop , [ ] , tracestate }
196+ end
197+ end
198+
199+ defp call_traces_sampler ( fun , sampling_context ) when is_function ( fun , 1 ) do
200+ fun . ( sampling_context )
201+ end
202+
203+ defp call_traces_sampler ( { module , function } , sampling_context ) do
204+ apply ( module , function , [ sampling_context ] )
205+ end
206+
207+ defp normalize_sampler_result ( true ) , do: 1.0
208+ defp normalize_sampler_result ( false ) , do: 0.0
209+ defp normalize_sampler_result ( rate ) when is_float ( rate ) , do: rate
210+
124211 defp record_discarded_transaction ( ) do
125212 ClientReport.Sender . record_discarded_events ( :sample_rate , "transaction" )
126213 end
0 commit comments