Skip to content

Commit 1c35d48

Browse files
Fix: Duration in Celery Beat tasks monitoring (#2087)
* Using epoch in Celery task check-ins --------- Co-authored-by: Ivana Kellyerova <[email protected]>
1 parent 9457282 commit 1c35d48

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

sentry_sdk/integrations/celery.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import absolute_import
22

33
import sys
4+
import time
45

56
from sentry_sdk.consts import OP
67
from sentry_sdk._compat import reraise
@@ -15,7 +16,6 @@
1516
capture_internal_exceptions,
1617
event_from_exception,
1718
logger,
18-
now,
1919
)
2020

2121
if TYPE_CHECKING:
@@ -114,6 +114,16 @@ def sentry_build_tracer(name, task, *args, **kwargs):
114114
ignore_logger("celery.redirected")
115115

116116

117+
def _now_seconds_since_epoch():
118+
# type: () -> float
119+
# We cannot use `time.perf_counter()` when dealing with the duration
120+
# of a Celery task, because the start of a Celery task and
121+
# the end are recorded in different processes.
122+
# Start happens in the Celery Beat process,
123+
# the end in a Celery Worker process.
124+
return time.time()
125+
126+
117127
def _wrap_apply_async(f):
118128
# type: (F) -> F
119129
@wraps(f)
@@ -130,7 +140,8 @@ def apply_async(*args, **kwargs):
130140
if integration.monitor_beat_tasks:
131141
headers.update(
132142
{
133-
"sentry-monitor-start-timestamp-s": "%.9f" % now(),
143+
"sentry-monitor-start-timestamp-s": "%.9f"
144+
% _now_seconds_since_epoch(),
134145
}
135146
)
136147

@@ -449,7 +460,7 @@ def crons_task_success(sender, **kwargs):
449460
monitor_slug=headers["sentry-monitor-slug"],
450461
monitor_config=monitor_config,
451462
check_in_id=headers["sentry-monitor-check-in-id"],
452-
duration=now() - start_timestamp_s,
463+
duration=_now_seconds_since_epoch() - start_timestamp_s,
453464
status=MonitorStatus.OK,
454465
)
455466

@@ -470,7 +481,7 @@ def crons_task_failure(sender, **kwargs):
470481
monitor_slug=headers["sentry-monitor-slug"],
471482
monitor_config=monitor_config,
472483
check_in_id=headers["sentry-monitor-check-in-id"],
473-
duration=now() - start_timestamp_s,
484+
duration=_now_seconds_since_epoch() - start_timestamp_s,
474485
status=MonitorStatus.ERROR,
475486
)
476487

@@ -491,6 +502,6 @@ def crons_task_retry(sender, **kwargs):
491502
monitor_slug=headers["sentry-monitor-slug"],
492503
monitor_config=monitor_config,
493504
check_in_id=headers["sentry-monitor-check-in-id"],
494-
duration=now() - start_timestamp_s,
505+
duration=_now_seconds_since_epoch() - start_timestamp_s,
495506
status=MonitorStatus.ERROR,
496507
)

tests/integrations/celery/test_celery_beat_crons.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ def test_crons_task_success():
8989
with mock.patch(
9090
"sentry_sdk.integrations.celery.capture_checkin"
9191
) as mock_capture_checkin:
92-
with mock.patch("sentry_sdk.integrations.celery.now", return_value=500.5):
92+
with mock.patch(
93+
"sentry_sdk.integrations.celery._now_seconds_since_epoch",
94+
return_value=500.5,
95+
):
9396
crons_task_success(fake_task)
9497

9598
mock_capture_checkin.assert_called_once_with(
@@ -130,7 +133,10 @@ def test_crons_task_failure():
130133
with mock.patch(
131134
"sentry_sdk.integrations.celery.capture_checkin"
132135
) as mock_capture_checkin:
133-
with mock.patch("sentry_sdk.integrations.celery.now", return_value=500.5):
136+
with mock.patch(
137+
"sentry_sdk.integrations.celery._now_seconds_since_epoch",
138+
return_value=500.5,
139+
):
134140
crons_task_failure(fake_task)
135141

136142
mock_capture_checkin.assert_called_once_with(
@@ -171,7 +177,10 @@ def test_crons_task_retry():
171177
with mock.patch(
172178
"sentry_sdk.integrations.celery.capture_checkin"
173179
) as mock_capture_checkin:
174-
with mock.patch("sentry_sdk.integrations.celery.now", return_value=500.5):
180+
with mock.patch(
181+
"sentry_sdk.integrations.celery._now_seconds_since_epoch",
182+
return_value=500.5,
183+
):
175184
crons_task_retry(fake_task)
176185

177186
mock_capture_checkin.assert_called_once_with(

0 commit comments

Comments
 (0)