From ec7cd14f83526395afccb0e4075ae25d04514623 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Tue, 4 Nov 2025 15:06:46 +0100 Subject: [PATCH 1/2] feat: non-experimental option --- sentry_sdk/consts.py | 1 + sentry_sdk/utils.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 33900acd50..b25c5d96b3 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -1005,6 +1005,7 @@ def __init__( enable_logs=False, # type: bool before_send_log=None, # type: Optional[Callable[[Log, Hint], Optional[Log]]] trace_ignore_status_codes=frozenset(), # type: AbstractSet[int] + before_send_metric=None, # type: Optional[Callable[[Metric, Hint], Optional[Metric]]] ): # type: (...) -> None """Initialize the Sentry SDK with the given parameters. All parameters described here can be used in a call to `sentry_sdk.init()`. diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 93c35cee8a..7a7ce9b55e 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -2052,4 +2052,6 @@ def get_before_send_metric(options): if options is None: return None - return options["_experiments"].get("before_send_metric") + return options.get("before_send_metric") or options["_experiments"].get( + "before_send_metric" + ) From da58464cf46bd04e0f2c936b260d3bc709481206 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 5 Nov 2025 08:54:31 +0100 Subject: [PATCH 2/2] add test --- tests/test_metrics.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 29b139c184..0ce3d0f2b8 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -168,6 +168,45 @@ def test_metrics_tracing_without_performance(sentry_init, capture_envelopes): def test_metrics_before_send(sentry_init, capture_envelopes): before_metric_called = False + def _before_metric(record, hint): + nonlocal before_metric_called + + assert set(record.keys()) == { + "timestamp", + "trace_id", + "span_id", + "name", + "type", + "value", + "unit", + "attributes", + } + + if record["name"] == "test.skip": + return None + + before_metric_called = True + return record + + sentry_init( + before_send_metric=_before_metric, + ) + envelopes = capture_envelopes() + + sentry_sdk.metrics.count("test.skip", 1) + sentry_sdk.metrics.count("test.keep", 1) + + get_client().flush() + + metrics = envelopes_to_metrics(envelopes) + assert len(metrics) == 1 + assert metrics[0]["name"] == "test.keep" + assert before_metric_called + + +def test_metrics_experimental_before_send(sentry_init, capture_envelopes): + before_metric_called = False + def _before_metric(record, hint): nonlocal before_metric_called