Skip to content

Commit 5949535

Browse files
committed
sentry-core: support custom user data in TransactionContext
1 parent 15fc5c1 commit 5949535

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
**Features**
66

77
- Allow `traces_sampler` to inspect well known properties of `TransactionContext` ([#514](https://github.com/getsentry/sentry-rust/pull/514))
8+
- Users of `TransactionContext` may now add `custom` context to it. This may be used by `traces_sampler` to decide sampling rates on a per-transaction basis. ([#512](https://github.com/getsentry/sentry-rust/pull/512))
89

910
## 0.28.0
1011

sentry-core/src/performance.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ impl Hub {
5151

5252
// "Context" Types:
5353

54+
/// Arbitrary data passed by the caller, when starting a transaction.
55+
///
56+
/// May be inspected by the user in the `traces_sampler` callback, if set.
57+
///
58+
/// Represents arbitrary JSON data, the top level of which must be a map.
59+
pub type CustomTransactionContext = serde_json::Map<String, serde_json::Value>;
60+
5461
/// The Transaction Context used to start a new Performance Monitoring Transaction.
5562
///
5663
/// The Transaction Context defines the metadata for a Performance Monitoring
@@ -63,6 +70,7 @@ pub struct TransactionContext {
6370
trace_id: protocol::TraceId,
6471
parent_span_id: Option<protocol::SpanId>,
6572
sampled: Option<bool>,
73+
custom: Option<CustomTransactionContext>,
6674
}
6775

6876
impl TransactionContext {
@@ -108,6 +116,7 @@ impl TransactionContext {
108116
trace_id,
109117
parent_span_id,
110118
sampled,
119+
custom: None,
111120
}
112121
}
113122

@@ -144,6 +153,7 @@ impl TransactionContext {
144153
trace_id,
145154
parent_span_id: Some(parent_span_id),
146155
sampled,
156+
custom: None,
147157
}
148158
}
149159

@@ -169,6 +179,41 @@ impl TransactionContext {
169179
pub fn operation(&self) -> &str {
170180
&self.op
171181
}
182+
183+
/// Get the custom context of this Transaction.
184+
pub fn custom(&self) -> Option<&CustomTransactionContext> {
185+
self.custom.as_ref()
186+
}
187+
188+
/// Update the custom context of this Transaction.
189+
///
190+
/// For simply adding a key, use the `custom_insert` method.
191+
pub fn custom_mut(&mut self) -> &mut Option<CustomTransactionContext> {
192+
&mut self.custom
193+
}
194+
195+
/// Inserts a key-value pair into the custom context.
196+
///
197+
/// If the context did not have this key present, None is returned.
198+
///
199+
/// If the context did have this key present, the value is updated, and the old value is returned.
200+
pub fn custom_insert(
201+
&mut self,
202+
key: String,
203+
value: serde_json::Value,
204+
) -> Option<serde_json::Value> {
205+
// Get the custom context
206+
let mut custom = None;
207+
std::mem::swap(&mut self.custom, &mut custom);
208+
209+
// Initialise the context, if not used yet
210+
let mut custom = custom.unwrap_or_default();
211+
212+
// And set our key
213+
let existing_value = custom.insert(key, value);
214+
std::mem::swap(&mut self.custom, &mut Some(custom));
215+
existing_value
216+
}
172217
}
173218

174219
/// A function to be run for each new transaction, to determine the rate at which
@@ -772,5 +817,31 @@ mod tests {
772817
assert_eq!(transaction_sample_rate(Some(&sampler), &ctx, 0.3), 0.8);
773818
ctx.set_sampled(None);
774819
assert_eq!(transaction_sample_rate(Some(&sampler), &ctx, 0.3), 0.6);
820+
821+
// Can use first-class and custom attributes of the context.
822+
let sampler = |ctx: &TransactionContext| {
823+
if ctx.name() == "must-name" || ctx.operation() == "must-operation" {
824+
return 1.0;
825+
}
826+
827+
if let Some(custom) = ctx.custom() {
828+
if let Some(rate) = custom.get("rate") {
829+
if let Some(rate) = rate.as_f64() {
830+
return rate as f32;
831+
}
832+
}
833+
}
834+
835+
0.1
836+
};
837+
// First class attributes
838+
let ctx = TransactionContext::new("noop", "must-operation");
839+
assert_eq!(transaction_sample_rate(Some(&sampler), &ctx, 0.3), 1.0);
840+
let ctx = TransactionContext::new("must-name", "noop");
841+
assert_eq!(transaction_sample_rate(Some(&sampler), &ctx, 0.3), 1.0);
842+
// Custom data payload
843+
let mut ctx = TransactionContext::new("noop", "noop");
844+
ctx.custom_insert("rate".to_owned(), serde_json::json!(0.7));
845+
assert_eq!(transaction_sample_rate(Some(&sampler), &ctx, 0.3), 0.7);
775846
}
776847
}

0 commit comments

Comments
 (0)