diff --git a/swh/core/statsd.py b/swh/core/statsd.py --- a/swh/core/statsd.py +++ b/swh/core/statsd.py @@ -73,9 +73,13 @@ Attributes: elapsed (float): the elapsed time at the point of completion """ - def __init__(self, statsd, metric=None, tags=None, sample_rate=1): + def __init__(self, statsd, metric=None, error_metric=None, + tags=None, sample_rate=1): self.statsd = statsd self.metric = metric + self.error_metric = error_metric + if self.error_metric is None: + self.error_metric = self.metric + '_error_count' self.tags = tags self.sample_rate = sample_rate self.elapsed = None @@ -97,8 +101,13 @@ try: result = await func(*args, **kwargs) return result + except: # noqa + self._send_error() + start = None + raise finally: - self._send(start) + if start is not None: + self._send(start) return wrapped_co # Others @@ -107,8 +116,13 @@ start = monotonic() try: return func(*args, **kwargs) + except: # noqa + self._send_error() + start = None + raise finally: - self._send(start) + if start is not None: + self._send(start) return wrapped def __enter__(self): @@ -118,14 +132,21 @@ return self def __exit__(self, type, value, traceback): - # Report the elapsed time of the context manager. - self._send(self._start) + # Report the elapsed time of the context manager if no error. + if type is None: + self._send(self._start) + else: + self._send_error() def _send(self, start): elapsed = (monotonic() - start) * 1000 - self.statsd.timing(self.metric, elapsed, self.tags, self.sample_rate) + self.statsd.timing(self.metric, int(elapsed), + tags=self.tags, sample_rate=self.sample_rate) self.elapsed = elapsed + def _send_error(self): + self.statsd.increment(self.error_metric, tags=self.tags) + def start(self): """Start the timer""" self.__enter__() @@ -192,7 +213,6 @@ UserWarning, ) continue - print(tag) k, v = tag.split(':', 1) self.constant_tags[k] = v @@ -262,7 +282,7 @@ """ self._report(metric, 'ms', value, tags, sample_rate) - def timed(self, metric=None, tags=None, sample_rate=1): + def timed(self, metric=None, error_metric=None, tags=None, sample_rate=1): """ A decorator or context manager that will measure the distribution of a function's/context's run time. Optionally specify a list of tags or a @@ -288,7 +308,10 @@ finally: statsd.timing('user.query.time', time.monotonic() - start) """ - return TimedContextManagerDecorator(self, metric, tags, sample_rate) + return TimedContextManagerDecorator( + statsd=self, metric=metric, + error_metric=error_metric, + tags=tags, sample_rate=sample_rate) def set(self, metric, value, tags=None, sample_rate=1): """ @@ -369,7 +392,6 @@ for (k, v) in sorted(tags.items()) )) if tags else "", ) - # Send it self._send(payload)