-
Notifications
You must be signed in to change notification settings - Fork 536
/
Copy pathcrons.py
123 lines (97 loc) · 3.43 KB
/
crons.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from functools import wraps
import sys
import uuid
from sentry_sdk import Hub
from sentry_sdk._compat import reraise
from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.utils import nanosecond_time
if TYPE_CHECKING:
from typing import Any, Callable, Dict, Optional
class MonitorStatus:
IN_PROGRESS = "in_progress"
OK = "ok"
ERROR = "error"
def _create_checkin_event(
monitor_slug=None, check_in_id=None, status=None, duration=None
):
# type: (Optional[str], Optional[str], Optional[str], Optional[float]) -> Dict[str, Any]
options = Hub.current.client.options if Hub.current.client else {}
check_in_id = check_in_id or uuid.uuid4().hex # type: str
# convert nanosecond to millisecond
duration = int(duration * 0.000001) if duration is not None else duration
checkin = {
"type": "check_in",
"monitor_slug": monitor_slug,
# TODO: Add schedule and schedule_type to monitor config
# "monitor_config": {
# "schedule": "*/10 0 0 0 0",
# "schedule_type": "cron",
# },
"check_in_id": check_in_id,
"status": status,
"duration": duration,
"environment": options["environment"],
"release": options["release"],
}
return checkin
def capture_checkin(monitor_slug=None, check_in_id=None, status=None, duration=None):
# type: (Optional[str], Optional[str], Optional[str], Optional[float]) -> str
hub = Hub.current
check_in_id = check_in_id or uuid.uuid4().hex
checkin_event = _create_checkin_event(
monitor_slug=monitor_slug,
check_in_id=check_in_id,
status=status,
duration=duration,
)
hub.capture_event(checkin_event)
return checkin_event["check_in_id"]
def monitor(monitor_slug=None, app=None):
# type: (Optional[str], Any) -> Callable[..., Any]
"""
Decorator to capture checkin events for a monitor.
Usage:
```
import sentry_sdk
app = Celery()
@app.task
@sentry_sdk.monitor(monitor_slug='my-fancy-slug')
def test(arg):
print(arg)
```
This does not have to be used with Celery, but if you do use it with celery,
put the `@sentry_sdk.monitor` decorator below Celery's `@app.task` decorator.
"""
def decorate(func):
# type: (Callable[..., Any]) -> Callable[..., Any]
if not monitor_slug:
return func
@wraps(func)
def wrapper(*args, **kwargs):
# type: (*Any, **Any) -> Any
start_timestamp = nanosecond_time()
check_in_id = capture_checkin(
monitor_slug=monitor_slug, status=MonitorStatus.IN_PROGRESS
)
try:
result = func(*args, **kwargs)
except Exception:
duration = nanosecond_time() - start_timestamp
capture_checkin(
monitor_slug=monitor_slug,
check_in_id=check_in_id,
status=MonitorStatus.ERROR,
duration=duration,
)
exc_info = sys.exc_info()
reraise(*exc_info)
duration = nanosecond_time() - start_timestamp
capture_checkin(
monitor_slug=monitor_slug,
check_in_id=check_in_id,
status=MonitorStatus.OK,
duration=duration,
)
return result
return wrapper
return decorate