1
1
use std:: sync:: Arc ;
2
2
use std:: sync:: Mutex ;
3
3
4
- use crate :: { protocol, Client , Hub } ;
4
+ use crate :: { protocol, Hub } ;
5
5
6
+ #[ cfg( feature = "client" ) ]
7
+ use crate :: Client ;
8
+
9
+ #[ cfg( feature = "client" ) ]
6
10
const MAX_SPANS : usize = 1_000 ;
7
11
8
12
// global API:
@@ -14,8 +18,15 @@ const MAX_SPANS: usize = 1_000;
14
18
/// The transaction itself also represents the root span in the span hierarchy.
15
19
/// Child spans can be started with the [`Transaction::start_child`] method.
16
20
pub fn start_transaction ( ctx : TransactionContext ) -> Transaction {
17
- let client = Hub :: with_active ( |hub| hub. client ( ) ) ;
18
- Transaction :: new ( client, ctx)
21
+ #[ cfg( feature = "client" ) ]
22
+ {
23
+ let client = Hub :: with_active ( |hub| hub. client ( ) ) ;
24
+ Transaction :: new ( client, ctx)
25
+ }
26
+ #[ cfg( not( feature = "client" ) ) ]
27
+ {
28
+ Transaction :: new_noop ( ctx)
29
+ }
19
30
}
20
31
21
32
// Hub API:
@@ -25,7 +36,14 @@ impl Hub {
25
36
///
26
37
/// See the global [`start_transaction`] for more documentation.
27
38
pub fn start_transaction ( & self , ctx : TransactionContext ) -> Transaction {
28
- Transaction :: new ( self . client ( ) , ctx)
39
+ #[ cfg( feature = "client" ) ]
40
+ {
41
+ Transaction :: new ( self . client ( ) , ctx)
42
+ }
43
+ #[ cfg( not( feature = "client" ) ) ]
44
+ {
45
+ Transaction :: new_noop ( ctx)
46
+ }
29
47
}
30
48
}
31
49
@@ -37,6 +55,7 @@ impl Hub {
37
55
/// Transaction, and also the connection point for distributed tracing.
38
56
#[ derive( Debug ) ]
39
57
pub struct TransactionContext {
58
+ #[ cfg_attr( not( feature = "client" ) , allow( dead_code) ) ]
40
59
name : String ,
41
60
op : String ,
42
61
trace_id : protocol:: TraceId ,
@@ -203,6 +222,7 @@ impl TransactionOrSpan {
203
222
}
204
223
}
205
224
225
+ #[ cfg( feature = "client" ) ]
206
226
pub ( crate ) fn apply_to_event ( & self , event : & mut protocol:: Event < ' _ > ) {
207
227
if event. contexts . contains_key ( "trace" ) {
208
228
return ;
@@ -238,6 +258,7 @@ impl TransactionOrSpan {
238
258
239
259
#[ derive( Debug ) ]
240
260
struct TransactionInner {
261
+ #[ cfg( feature = "client" ) ]
241
262
client : Option < Arc < Client > > ,
242
263
sampled : bool ,
243
264
context : protocol:: TraceContext ,
@@ -257,6 +278,7 @@ pub struct Transaction {
257
278
}
258
279
259
280
impl Transaction {
281
+ #[ cfg( feature = "client" ) ]
260
282
fn new ( mut client : Option < Arc < Client > > , ctx : TransactionContext ) -> Self {
261
283
let context = protocol:: TraceContext {
262
284
trace_id : ctx. trace_id ,
@@ -294,6 +316,25 @@ impl Transaction {
294
316
}
295
317
}
296
318
319
+ #[ cfg( not( feature = "client" ) ) ]
320
+ fn new_noop ( ctx : TransactionContext ) -> Self {
321
+ let context = protocol:: TraceContext {
322
+ trace_id : ctx. trace_id ,
323
+ parent_span_id : ctx. parent_span_id ,
324
+ op : Some ( ctx. op ) ,
325
+ ..Default :: default ( )
326
+ } ;
327
+ let sampled = ctx. sampled . unwrap_or ( false ) ;
328
+
329
+ Self {
330
+ inner : Arc :: new ( Mutex :: new ( TransactionInner {
331
+ sampled,
332
+ context,
333
+ transaction : None ,
334
+ } ) ) ,
335
+ }
336
+ }
337
+
297
338
/// Set some extra information to be sent with this Transaction.
298
339
pub fn set_data ( & self , key : & str , value : protocol:: Value ) {
299
340
let mut inner = self . inner . lock ( ) . unwrap ( ) ;
@@ -332,26 +373,28 @@ impl Transaction {
332
373
/// This records the end timestamp and sends the transaction together with
333
374
/// all finished child spans to Sentry.
334
375
pub fn finish ( self ) {
335
- let mut inner = self . inner . lock ( ) . unwrap ( ) ;
336
- if let Some ( mut transaction) = inner. transaction . take ( ) {
337
- if let Some ( client) = inner. client . take ( ) {
338
- transaction. finish ( ) ;
339
- transaction
340
- . contexts
341
- . insert ( "trace" . into ( ) , inner. context . clone ( ) . into ( ) ) ;
342
-
343
- // TODO: apply the scope to the transaction, whatever that means
344
- let opts = client. options ( ) ;
345
- transaction. release = opts. release . clone ( ) ;
346
- transaction. environment = opts. environment . clone ( ) ;
347
- transaction. sdk = Some ( std:: borrow:: Cow :: Owned ( client. sdk_info . clone ( ) ) ) ;
348
-
349
- let mut envelope = protocol:: Envelope :: new ( ) ;
350
- envelope. add_item ( transaction) ;
351
-
352
- client. send_envelope ( envelope)
376
+ with_client_impl ! { {
377
+ let mut inner = self . inner. lock( ) . unwrap( ) ;
378
+ if let Some ( mut transaction) = inner. transaction. take( ) {
379
+ if let Some ( client) = inner. client. take( ) {
380
+ transaction. finish( ) ;
381
+ transaction
382
+ . contexts
383
+ . insert( "trace" . into( ) , inner. context. clone( ) . into( ) ) ;
384
+
385
+ // TODO: apply the scope to the transaction, whatever that means
386
+ let opts = client. options( ) ;
387
+ transaction. release = opts. release. clone( ) ;
388
+ transaction. environment = opts. environment. clone( ) ;
389
+ transaction. sdk = Some ( std:: borrow:: Cow :: Owned ( client. sdk_info. clone( ) ) ) ;
390
+
391
+ let mut envelope = protocol:: Envelope :: new( ) ;
392
+ envelope. add_item( transaction) ;
393
+
394
+ client. send_envelope( envelope)
395
+ }
353
396
}
354
- }
397
+ } }
355
398
}
356
399
357
400
/// Starts a new child Span with the given `op` and `description`.
@@ -425,18 +468,20 @@ impl Span {
425
468
/// This will record the end timestamp and add the span to the transaction
426
469
/// in which it was started.
427
470
pub fn finish ( self ) {
428
- let mut span = self . span . lock ( ) . unwrap ( ) ;
429
- if span. timestamp . is_some ( ) {
430
- // the span was already finished
431
- return ;
432
- }
433
- span. finish ( ) ;
434
- let mut inner = self . transaction . lock ( ) . unwrap ( ) ;
435
- if let Some ( transaction) = inner. transaction . as_mut ( ) {
436
- if transaction. spans . len ( ) <= MAX_SPANS {
437
- transaction. spans . push ( span. clone ( ) ) ;
471
+ with_client_impl ! { {
472
+ let mut span = self . span. lock( ) . unwrap( ) ;
473
+ if span. timestamp. is_some( ) {
474
+ // the span was already finished
475
+ return ;
438
476
}
439
- }
477
+ span. finish( ) ;
478
+ let mut inner = self . transaction. lock( ) . unwrap( ) ;
479
+ if let Some ( transaction) = inner. transaction. as_mut( ) {
480
+ if transaction. spans. len( ) <= MAX_SPANS {
481
+ transaction. spans. push( span. clone( ) ) ;
482
+ }
483
+ }
484
+ } }
440
485
}
441
486
442
487
/// Starts a new child Span with the given `op` and `description`.
@@ -510,11 +555,12 @@ impl std::fmt::Display for SentryTrace {
510
555
511
556
#[ cfg( test) ]
512
557
mod tests {
558
+ use std:: str:: FromStr ;
559
+
513
560
use super :: * ;
514
561
515
562
#[ test]
516
563
fn parses_sentry_trace ( ) {
517
- use std:: str:: FromStr ;
518
564
let trace_id = protocol:: TraceId :: from_str ( "09e04486820349518ac7b5d2adbf6ba5" ) . unwrap ( ) ;
519
565
let parent_trace_id = protocol:: SpanId :: from_str ( "9cf635fa5b870b3a" ) . unwrap ( ) ;
520
566
@@ -528,4 +574,22 @@ mod tests {
528
574
let parsed = parse_sentry_trace ( & format ! ( "{}" , trace) ) ;
529
575
assert_eq ! ( parsed, Some ( trace) ) ;
530
576
}
577
+
578
+ #[ test]
579
+ fn disabled_forwards_trace_id ( ) {
580
+ let headers = [ (
581
+ "SenTrY-TRAce" ,
582
+ "09e04486820349518ac7b5d2adbf6ba5-9cf635fa5b870b3a-1" ,
583
+ ) ] ;
584
+ let ctx = TransactionContext :: continue_from_headers ( "noop" , "noop" , headers) ;
585
+ let trx = start_transaction ( ctx) ;
586
+
587
+ let span = trx. start_child ( "noop" , "noop" ) ;
588
+
589
+ let header = span. iter_headers ( ) . next ( ) . unwrap ( ) . 1 ;
590
+ let parsed = parse_sentry_trace ( & header) . unwrap ( ) ;
591
+
592
+ assert_eq ! ( & parsed. 0 . to_string( ) , "09e04486820349518ac7b5d2adbf6ba5" ) ;
593
+ assert_eq ! ( parsed. 2 , Some ( true ) ) ;
594
+ }
531
595
}
0 commit comments