relay_profiling/
extract_from_transaction.rs1use std::collections::BTreeMap;
2
3use chrono::SecondsFormat;
4
5use relay_event_schema::protocol::{AppContext, AsPair, Event, SpanStatus, TraceContext};
6
7pub fn extract_transaction_metadata(event: &Event) -> BTreeMap<String, String> {
8 let mut tags = BTreeMap::new();
9
10 if let Some(release) = event.release.as_str() {
11 tags.insert("release".to_owned(), release.to_owned());
12 }
13 if let Some(dist) = event.dist.as_str() {
14 tags.insert("dist".to_owned(), dist.to_owned());
15 }
16 if let Some(environment) = event.environment.as_str() {
17 tags.insert("environment".to_owned(), environment.to_owned());
18 }
19
20 if let Some(transaction) = event.transaction.as_str() {
21 tags.insert("transaction".to_owned(), transaction.to_owned());
22 }
23
24 if let Some(trace_context) = event.context::<TraceContext>() {
25 let status = extract_transaction_status(trace_context);
26 tags.insert("transaction.status".to_owned(), status.to_string());
27
28 if let Some(op) = trace_context.op.value() {
29 tags.insert("transaction.op".to_owned(), op.to_owned());
30 }
31
32 if let Some(segment_id) = trace_context.span_id.value() {
33 tags.insert("segment_id".to_owned(), segment_id.to_string());
34 }
35 }
36
37 if let Some(http_method) = extract_http_method(event) {
38 tags.insert("http.method".to_owned(), http_method);
39 }
40
41 if let Some(timestamp) = event.start_timestamp.value() {
42 tags.insert(
43 "transaction.start".to_owned(),
44 timestamp
45 .into_inner()
46 .to_rfc3339_opts(SecondsFormat::Nanos, false),
47 );
48 }
49
50 if let Some(timestamp) = event.timestamp.value() {
51 tags.insert(
52 "transaction.end".to_owned(),
53 timestamp
54 .into_inner()
55 .to_rfc3339_opts(SecondsFormat::Nanos, false),
56 );
57 }
58
59 if let Some(app_context) = event.context::<AppContext>() {
60 if let Some(app_identifier) = app_context.app_identifier.value() {
61 tags.insert("app.identifier".to_owned(), app_identifier.to_owned());
62 }
63 }
64
65 if let Some(client_sdk) = event.client_sdk.value() {
66 if let Some(sdk_name) = client_sdk.name.value() {
67 tags.insert("client_sdk.name".to_owned(), sdk_name.to_owned());
68 }
69 if let Some(sdk_version) = client_sdk.version.value() {
70 tags.insert("client_sdk.version".to_owned(), sdk_version.to_owned());
71 }
72 }
73
74 tags
75}
76
77pub fn extract_transaction_tags(event: &Event) -> BTreeMap<String, String> {
78 let mut tags = BTreeMap::new();
79
80 if let Some(event_tags) = event.tags.value() {
82 for tag_entry in &**event_tags {
83 if let Some(entry) = tag_entry.value() {
84 let (key, value) = entry.as_pair();
85 if let (Some(key), Some(value)) = (key.as_str(), value.as_str()) {
86 tags.insert(key.to_owned(), value.to_owned());
87 }
88 }
89 }
90 }
91
92 tags
93}
94
95fn extract_transaction_status(trace_context: &TraceContext) -> SpanStatus {
99 *trace_context.status.value().unwrap_or(&SpanStatus::Unknown)
100}
101
102fn extract_http_method(transaction: &Event) -> Option<String> {
105 let request = transaction.request.value()?;
106 let method = request.method.value()?;
107 Some(method.clone())
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use relay_protocol::FromValue;
114
115 #[test]
116 fn test_extract_transaction_metadata() {
117 let event = Event::from_value(
118 serde_json::json!({
119 "release": "myrelease",
120 "dist": "mydist",
121 "environment": "myenvironment",
122 "transaction": "mytransaction",
123 "contexts": {
124 "app": {
125 "app_identifier": "io.sentry.myexample",
126 },
127 "trace": {
128 "status": "ok",
129 "op": "myop",
130 },
131 },
132 "request": {
133 "method": "GET",
134 },
135 "timestamp": "2011-05-02T17:41:36Z",
136 "start_timestamp": "2011-05-02T17:40:36Z",
137 "sdk": {
138 "name": "sentry.python",
139 "version": "2.10.7",
140 },
141 })
142 .into(),
143 );
144
145 let metadata = extract_transaction_metadata(&event.0.unwrap());
146 insta::assert_debug_snapshot!(metadata, @r###"
147 {
148 "app.identifier": "io.sentry.myexample",
149 "client_sdk.name": "sentry.python",
150 "client_sdk.version": "2.10.7",
151 "dist": "mydist",
152 "environment": "myenvironment",
153 "http.method": "GET",
154 "release": "myrelease",
155 "transaction": "mytransaction",
156 "transaction.end": "2011-05-02T17:41:36.000000000+00:00",
157 "transaction.op": "myop",
158 "transaction.start": "2011-05-02T17:40:36.000000000+00:00",
159 "transaction.status": "ok",
160 }
161 "###);
162 }
163}