Skip to content

Commit 1b445c6

Browse files
authored
feat(metrics): Make a consistent noop flush behavior (#2428)
1 parent 44ae06e commit 1b445c6

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

sentry_sdk/metrics.py

+4-11
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ def _encode_metrics(flushable_buckets):
304304
class MetricsAggregator(object):
305305
ROLLUP_IN_SECONDS = 10.0
306306
MAX_WEIGHT = 100000
307+
FLUSHER_SLEEP_TIME = 5.0
307308

308309
def __init__(
309310
self,
@@ -350,7 +351,7 @@ def _flush_loop(self):
350351
while self._running or self._force_flush:
351352
self._flush()
352353
if self._running:
353-
self._flush_event.wait(5.0)
354+
self._flush_event.wait(self.FLUSHER_SLEEP_TIME)
354355

355356
def _flush(self):
356357
# type: (...) -> None
@@ -442,6 +443,7 @@ def kill(self):
442443
self._flusher.join()
443444
self._flusher = None
444445

446+
@metrics_noop
445447
def flush(self):
446448
# type: (...) -> None
447449
self._force_flush = True
@@ -463,16 +465,7 @@ def _emit(
463465
encoded_metrics = _encode_metrics(flushable_buckets)
464466
metric_item = Item(payload=encoded_metrics, type="statsd")
465467
envelope = Envelope(items=[metric_item])
466-
467-
# A malfunctioning transport might create a forever loop of metric
468-
# emission when it emits a metric in capture_envelope. We still
469-
# allow the capture to take place, but interior metric incr calls
470-
# or similar will be disabled. In the background thread this can
471-
# never happen, but in the force flush case which happens in the
472-
# foreground we might make it here unprotected.
473-
with recursion_protection():
474-
self._capture_func(envelope)
475-
468+
self._capture_func(envelope)
476469
return envelope
477470

478471
def _serialize_tags(

tests/test_metrics.py

+32
Original file line numberDiff line numberDiff line change
@@ -532,3 +532,35 @@ def bad_capture_envelope(*args, **kwargs):
532532
m = parse_metrics(envelope.items[0].payload.get_bytes())
533533
assert len(m) == 1
534534
assert m[0][1] == "counter@none"
535+
536+
537+
def test_flush_recursion_protection_background_flush(
538+
sentry_init, capture_envelopes, monkeypatch
539+
):
540+
monkeypatch.setattr(metrics.MetricsAggregator, "FLUSHER_SLEEP_TIME", 0.1)
541+
sentry_init(
542+
release="fun-release",
543+
environment="not-fun-env",
544+
_experiments={"enable_metrics": True},
545+
)
546+
envelopes = capture_envelopes()
547+
test_client = Hub.current.client
548+
549+
real_capture_envelope = test_client.transport.capture_envelope
550+
551+
def bad_capture_envelope(*args, **kwargs):
552+
metrics.incr("bad-metric")
553+
return real_capture_envelope(*args, **kwargs)
554+
555+
monkeypatch.setattr(test_client.transport, "capture_envelope", bad_capture_envelope)
556+
557+
metrics.incr("counter")
558+
559+
# flush via sleep and flag
560+
Hub.current.client.metrics_aggregator._force_flush = True
561+
time.sleep(0.5)
562+
563+
(envelope,) = envelopes
564+
m = parse_metrics(envelope.items[0].payload.get_bytes())
565+
assert len(m) == 1
566+
assert m[0][1] == "counter@none"

0 commit comments

Comments
 (0)