relay_server/managed/
counted.rs1use relay_event_schema::protocol::{
2 CompatSpan, OurLog, SessionAggregateItem, SessionAggregates, SessionUpdate, Span, SpanV2,
3};
4use relay_protocol::Annotated;
5use relay_quotas::DataCategory;
6use smallvec::SmallVec;
7
8use crate::envelope::{Item, SourceQuantities, WithHeader};
9use crate::metrics_extraction::transactions::ExtractedMetrics;
10use crate::utils::EnvelopeSummary;
11use crate::{Envelope, metrics, processing};
12
13pub type Quantities = SmallVec<[(DataCategory, usize); 1]>;
15
16pub trait Counted {
20 fn quantities(&self) -> Quantities;
24}
25
26impl Counted for () {
27 fn quantities(&self) -> Quantities {
28 Quantities::new()
29 }
30}
31
32impl Counted for Item {
33 fn quantities(&self) -> Quantities {
34 self.quantities()
35 }
36}
37
38impl Counted for Box<Envelope> {
39 fn quantities(&self) -> Quantities {
40 let mut quantities = Quantities::new();
41
42 let summary = EnvelopeSummary::compute(self);
44 if let Some(category) = summary.event_category {
45 quantities.push((category, 1));
46 if let Some(category) = category.index_category() {
47 quantities.push((category, 1));
48 }
49 }
50
51 let data = [
52 (DataCategory::Attachment, summary.attachment_quantity),
53 (DataCategory::Profile, summary.profile_quantity),
54 (DataCategory::ProfileIndexed, summary.profile_quantity),
55 (DataCategory::Span, summary.span_quantity),
56 (DataCategory::SpanIndexed, summary.span_quantity),
57 (
58 DataCategory::Transaction,
59 summary.secondary_transaction_quantity,
60 ),
61 (DataCategory::Span, summary.secondary_span_quantity),
62 (DataCategory::Replay, summary.replay_quantity),
63 (DataCategory::ProfileChunk, summary.profile_chunk_quantity),
64 (
65 DataCategory::ProfileChunkUi,
66 summary.profile_chunk_ui_quantity,
67 ),
68 (DataCategory::LogItem, summary.log_item_quantity),
69 (DataCategory::LogByte, summary.log_byte_quantity),
70 (DataCategory::Monitor, summary.monitor_quantity),
71 (DataCategory::Session, summary.session_quantity),
72 ];
73
74 for (category, quantity) in data {
75 if quantity > 0 {
76 quantities.push((category, quantity));
77 }
78 }
79
80 quantities
81 }
82}
83
84impl Counted for WithHeader<OurLog> {
85 fn quantities(&self) -> Quantities {
86 smallvec::smallvec![
87 (DataCategory::LogItem, 1),
88 (
89 DataCategory::LogByte,
90 processing::logs::get_calculated_byte_size(self)
91 )
92 ]
93 }
94}
95
96impl Counted for WithHeader<SpanV2> {
97 fn quantities(&self) -> Quantities {
98 smallvec::smallvec![(DataCategory::Span, 1), (DataCategory::SpanIndexed, 1)]
99 }
100}
101
102impl Counted for Annotated<Span> {
103 fn quantities(&self) -> Quantities {
104 smallvec::smallvec![(DataCategory::Span, 1), (DataCategory::SpanIndexed, 1)]
105 }
106}
107
108impl Counted for Annotated<CompatSpan> {
109 fn quantities(&self) -> Quantities {
110 smallvec::smallvec![(DataCategory::Span, 1), (DataCategory::SpanIndexed, 1)]
111 }
112}
113
114impl Counted for ExtractedMetrics {
115 fn quantities(&self) -> Quantities {
116 let SourceQuantities {
119 transactions,
120 spans,
121 profiles,
122 buckets,
123 } = metrics::extract_quantities(&self.project_metrics);
124
125 [
126 (DataCategory::Transaction, transactions),
127 (DataCategory::Span, spans),
128 (DataCategory::Profile, profiles),
129 (DataCategory::MetricBucket, buckets),
130 ]
131 .into_iter()
132 .filter(|(_, q)| *q > 0)
133 .collect()
134 }
135}
136
137impl Counted for SessionUpdate {
138 fn quantities(&self) -> Quantities {
139 smallvec::smallvec![(DataCategory::Session, 1)]
140 }
141}
142
143impl Counted for SessionAggregates {
144 fn quantities(&self) -> Quantities {
145 smallvec::smallvec![(DataCategory::Session, self.aggregates.len())]
146 }
147}
148impl Counted for SessionAggregateItem {
149 fn quantities(&self) -> Quantities {
150 smallvec::smallvec![(DataCategory::Session, 1)]
151 }
152}
153
154impl<T> Counted for &T
155where
156 T: Counted,
157{
158 fn quantities(&self) -> Quantities {
159 (*self).quantities()
160 }
161}