@@ -7,13 +7,16 @@ use relay_config::Config;
7
7
use relay_dynamic_config:: ErrorBoundary ;
8
8
use relay_event_schema:: protocol:: { Contexts , Event , TraceContext } ;
9
9
use relay_protocol:: { Annotated , Empty } ;
10
+ use relay_quotas:: DataCategory ;
10
11
use relay_sampling:: config:: RuleType ;
11
12
use relay_sampling:: evaluation:: { ReservoirEvaluator , SamplingEvaluator } ;
12
13
use relay_sampling:: { DynamicSamplingContext , SamplingConfig } ;
13
14
14
15
use crate :: envelope:: { CountFor , ItemType } ;
15
16
use crate :: services:: outcome:: Outcome ;
16
- use crate :: services:: processor:: { event_category, EventProcessing , Sampling , TransactionGroup } ;
17
+ use crate :: services:: processor:: {
18
+ event_category, EventProcessing , Sampling , SpansExtracted , TransactionGroup ,
19
+ } ;
17
20
use crate :: services:: projects:: project:: ProjectInfo ;
18
21
use crate :: utils:: { self , SamplingResult , TypedEnvelope } ;
19
22
@@ -112,6 +115,7 @@ pub fn drop_unsampled_items(
112
115
managed_envelope : & mut TypedEnvelope < TransactionGroup > ,
113
116
event : Annotated < Event > ,
114
117
outcome : Outcome ,
118
+ spans_extracted : SpansExtracted ,
115
119
) {
116
120
// Remove all items from the envelope which need to be dropped due to dynamic sampling.
117
121
let dropped_items = managed_envelope
@@ -136,6 +140,23 @@ pub fn drop_unsampled_items(
136
140
item. set_sampled ( false ) ;
137
141
}
138
142
143
+ // Another 'hack' to emit outcomes from the container item for the contained items (spans).
144
+ //
145
+ // The entire tracking outcomes for contained elements is not handled in a systematic way
146
+ // and whenever an event/transaction is discarded, contained elements are tracked in a 'best
147
+ // effort' basis (basically in all the cases where someone figured out this is a problem).
148
+ //
149
+ // This is yet another case, when the spans have not yet been separated from the transaction
150
+ // also emit dynamic sampling outcomes for the contained spans.
151
+ if !spans_extracted. 0 {
152
+ let spans = event. value ( ) . and_then ( |e| e. spans . value ( ) ) ;
153
+ let span_count = spans. map_or ( 0 , |s| s. len ( ) ) ;
154
+
155
+ // Track the amount of contained spans + 1 segment span (the transaction itself which would
156
+ // be converted to a span).
157
+ managed_envelope. track_outcome ( outcome. clone ( ) , DataCategory :: SpanIndexed , span_count + 1 ) ;
158
+ }
159
+
139
160
// All items have been dropped, now make sure the event is also handled and dropped.
140
161
if let Some ( category) = event_category ( & event) {
141
162
let category = category. index_category ( ) . unwrap_or ( category) ;
0 commit comments