@@ -284,10 +284,12 @@ def test_metrics_sample_rate_basic(sentry_init, capture_envelopes):
284284 assert len (metrics ) == 3
285285
286286 assert metrics [0 ]["name" ] == "test.counter"
287- assert metrics [0 ]["attributes" ]["sentry.client_sample_rate" ] == 0.5
287+ # No sentry.client_sample_rate when there's no trace context
288+ assert "sentry.client_sample_rate" not in metrics [0 ]["attributes" ]
288289
289290 assert metrics [1 ]["name" ] == "test.gauge"
290- assert metrics [1 ]["attributes" ]["sentry.client_sample_rate" ] == 0.8
291+ # No sentry.client_sample_rate when there's no trace context
292+ assert "sentry.client_sample_rate" not in metrics [1 ]["attributes" ]
291293
292294 assert metrics [2 ]["name" ] == "test.distribution"
293295 assert "sentry.client_sample_rate" not in metrics [2 ]["attributes" ]
@@ -316,7 +318,8 @@ def record_lost_event(reason, data_category, quantity):
316318
317319 assert len (metrics ) == 2
318320
319- assert metrics [0 ]["attributes" ]["sentry.client_sample_rate" ] == 0.5
321+ # No sentry.client_sample_rate when there's no trace context
322+ assert "sentry.client_sample_rate" not in metrics [0 ]["attributes" ]
320323 assert (
321324 "sentry.client_sample_rate" not in metrics [1 ]["attributes" ]
322325 ) # 1.0 does not need a sample rate, it's implied to be 1.0
@@ -341,6 +344,56 @@ def test_metrics_no_sample_rate(sentry_init, capture_envelopes):
341344 assert "sentry.client_sample_rate" not in metrics [0 ]["attributes" ]
342345
343346
347+ def test_metrics_sample_rate_no_trace_context (sentry_init , capture_envelopes ):
348+ """Test sentry.client_sample_rate not set when there's no trace context."""
349+ sentry_init ()
350+ envelopes = capture_envelopes ()
351+
352+ # Send metrics with sample_rate but without any active transaction/span
353+ sentry_sdk .metrics .count ("test.counter" , 1 , sample_rate = 0.5 )
354+ sentry_sdk .metrics .gauge ("test.gauge" , 42 , sample_rate = 0.8 )
355+
356+ get_client ().flush ()
357+ metrics = envelopes_to_metrics (envelopes )
358+
359+ assert len (metrics ) == 2
360+
361+ # When there's no trace context, no sampling is performed,
362+ # so sentry.client_sample_rate should not be set
363+ assert "sentry.client_sample_rate" not in metrics [0 ]["attributes" ]
364+ assert "sentry.client_sample_rate" not in metrics [1 ]["attributes" ]
365+
366+
367+ def test_metrics_sample_rate_with_trace_context (
368+ sentry_init , capture_envelopes , monkeypatch
369+ ):
370+ """Test sentry.client_sample_rate is set when there's a trace context."""
371+ sentry_init (traces_sample_rate = 1.0 )
372+ envelopes = capture_envelopes ()
373+
374+ # Mock the random sampling to ensure all metrics are included
375+ with mock .patch (
376+ "sentry_sdk.tracing_utils.Random.randrange" ,
377+ return_value = 0 , # Always sample (0 < any positive sample_rate)
378+ ):
379+ # Send metrics with sample_rate within an active transaction
380+ with sentry_sdk .start_transaction () as _ :
381+ sentry_sdk .metrics .count ("test.counter" , 1 , sample_rate = 0.5 )
382+ sentry_sdk .metrics .gauge ("test.gauge" , 42 , sample_rate = 0.8 )
383+ sentry_sdk .metrics .distribution ("test.distribution" , 200 , sample_rate = 1.0 )
384+
385+ get_client ().flush ()
386+ metrics = envelopes_to_metrics (envelopes )
387+
388+ assert len (metrics ) == 3
389+
390+ # When there's a trace context and sample_rate < 1.0, set attribute
391+ assert metrics [0 ]["attributes" ]["sentry.client_sample_rate" ] == 0.5
392+ assert metrics [1 ]["attributes" ]["sentry.client_sample_rate" ] == 0.8
393+ # sample_rate=1.0 doesn't need the attribute
394+ assert "sentry.client_sample_rate" not in metrics [2 ]["attributes" ]
395+
396+
344397@pytest .mark .parametrize ("sample_rand" , (0.0 , 0.25 , 0.5 , 0.75 ))
345398@pytest .mark .parametrize ("sample_rate" , (0.0 , 0.25 , 0.5 , 0.75 , 1.0 ))
346399def test_metrics_sampling_decision (
@@ -361,7 +414,7 @@ def record_lost_event(reason, data_category, quantity):
361414 "sentry_sdk.tracing_utils.Random.randrange" ,
362415 return_value = int (sample_rand * 1000000 ),
363416 ):
364- with sentry_sdk .start_transaction () as transaction :
417+ with sentry_sdk .start_transaction () as _ :
365418 sentry_sdk .metrics .count ("test.counter" , 1 , sample_rate = sample_rate )
366419
367420 get_client ().flush ()
0 commit comments