Skip to content

Commit dbad687

Browse files
committed
refactor: metrics
refactor metric to simplify use
1 parent 526ed94 commit dbad687

File tree

2 files changed

+40
-31
lines changed

2 files changed

+40
-31
lines changed

sentry_dynamic_sampling_lib/sampler.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
def on_exit(*args, **kwargs):
2424
ts = TraceSampler()
2525
ts.kill()
26+
LOGGER.debug("ControllerClient Killed")
2627
raise KeyboardInterrupt
2728

2829

@@ -89,20 +90,11 @@ def update_config(self):
8990
self.metrics.set_mode(MetricType.WSGI, data["wsgi_collect_metrics"])
9091

9192
def update_metrics(self):
92-
for metric_type in MetricType:
93-
# check if metric is enable
94-
mode = self.metrics.get_mode(metric_type)
95-
if not mode:
96-
LOGGER.debug("Metric %s disabled", metric_type.value)
97-
continue
98-
99-
counter = self.metrics.get_and_reset(metric_type)
100-
if len(counter) == 0:
101-
return
93+
for metric_type, data in self.metrics:
10294
data = {
10395
"app": self.app_key,
10496
"type": metric_type.value,
105-
"data": dict(counter.most_common(10)),
97+
"data": dict(data.most_common(10)),
10698
}
10799
try:
108100
self.session.post(
@@ -112,7 +104,7 @@ def update_metrics(self):
112104
LOGGER.debug("Metric %s pushed", metric_type.value)
113105
except RequestException as err:
114106
LOGGER.warning("Metric Request Failed: %s", err)
115-
return
107+
continue
116108

117109

118110
class TraceSampler(metaclass=Singleton):

sentry_dynamic_sampling_lib/shared.py

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
from collections import Counter
23
from enum import Enum
34
from threading import RLock
@@ -9,6 +10,8 @@
910
)
1011
from sentry_dynamic_sampling_lib.utils import synchronized
1112

13+
LOGGER = logging.getLogger("SentryWrapper")
14+
1215

1316
class Config:
1417
def __init__(self) -> None:
@@ -62,33 +65,47 @@ class MetricType(Enum):
6265
class Metric:
6366
def __init__(self) -> None:
6467
self._lock = RLock()
65-
self._activate = {
66-
MetricType.WSGI: False,
67-
MetricType.CELERY: False,
68-
}
69-
self._counters = {
70-
MetricType.WSGI: Counter(),
71-
MetricType.CELERY: Counter(),
68+
self._metrics = {
69+
MetricType.WSGI: {"activated": False, "data": Counter()},
70+
MetricType.CELERY: {"activated": False, "data": Counter()},
7271
}
7372

7473
def set_mode(self, _type, mode):
75-
self._activate[_type] = mode
74+
self._metrics[_type]["activated"] = mode
7675

7776
def get_mode(self, _type):
78-
return self._activate[_type]
77+
return self._metrics[_type]["activated"]
7978

8079
@synchronized
8180
def count_path(self, path):
82-
if self._activate[MetricType.WSGI]:
83-
self._counters[MetricType.WSGI][path] += 1
81+
metric = self._metrics[MetricType.WSGI]
82+
if metric["activated"]:
83+
metric["data"][path] += 1
8484

8585
@synchronized
8686
def count_task(self, path):
87-
if self._activate[MetricType.CELERY]:
88-
self._counters[MetricType.CELERY][path] += 1
89-
90-
@synchronized
91-
def get_and_reset(self, _type):
92-
counter = self._counters[_type]
93-
self._counters[_type] = Counter()
94-
return counter
87+
metric = self._metrics[MetricType.CELERY]
88+
if metric["activated"]:
89+
metric["data"][path] += 1
90+
91+
def __iter__(self):
92+
"""
93+
List activated non-empty metrics
94+
95+
Yields:
96+
Tuple(MetricType, Counter): the activated non-empty metrics
97+
"""
98+
for metric_type, metric in self._metrics.items():
99+
# check if metric is activated
100+
if not metric["activated"]:
101+
LOGGER.debug("Metric %s disabled", metric_type.value)
102+
with self._lock:
103+
# check im metric is empty
104+
if len(metric["data"]) == 0:
105+
LOGGER.debug("Metric %s is empty", metric_type.value)
106+
continue
107+
data = metric["data"]
108+
metric["data"] = Counter()
109+
110+
# yield outside of the lock to not block write while callee execute
111+
yield metric_type, data

0 commit comments

Comments
 (0)