Skip to content
This repository has been archived by the owner on Mar 28, 2021. It is now read-only.

Commit

Permalink
move context manager from Histogram class to metrics module
Browse files Browse the repository at this point in the history
  • Loading branch information
trehn committed Jun 23, 2015
1 parent fdc5baf commit edba4a4
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 18 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ and let's see the results::
>>> metrics.get("test")
{'arithmetic_mean': 0.41326093673706055, 'kind': 'histogram', 'skewness': 0.2739718270714368, 'harmonic_mean': 0.14326954591313346, 'min': 0.0613858699798584, 'standard_deviation': 0.4319169569113129, 'median': 0.2831099033355713, 'histogram': [(1.0613858699798584, 3), (2.0613858699798584, 0)], 'percentile': [(50, 0.2831099033355713), (75, 0.2831099033355713), (90, 0.895287036895752), (95, 0.895287036895752), (99, 0.895287036895752), (99.9, 0.895287036895752)], 'n': 3, 'max': 0.895287036895752, 'variance': 0.18655225766752892, 'geometric_mean': 0.24964828731906127, 'kurtosis': -2.3333333333333335}

It is also possible to time specific sections of the code by using the ``time`` context manager::
It is also possible to time specific sections of the code by using the ``timer`` context manager::

>>> import time, random
... def my_worker():
... with metrics.metric("test").time():
... with metrics.timer("test"):
... time.sleep(random.random())
...

Expand Down
9 changes: 0 additions & 9 deletions appmetrics/histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import time
import operator
import math
from contextlib import contextmanager

from . import statistics, exceptions, py3comp

Expand Down Expand Up @@ -350,14 +349,6 @@ def raw_data(self):

return self.reservoir.values

@contextmanager
def time(self):
"""A context manager which times execution of a piece of code"""
t1 = time.time()
yield
t2 = time.time()
self.notify(t2 - t1)

def get(self):
"""Return the computed statistics over the gathered data"""

Expand Down
16 changes: 16 additions & 0 deletions appmetrics/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
Main interface module
"""

from contextlib import contextmanager
import functools
import threading
import time
Expand Down Expand Up @@ -240,6 +241,21 @@ def fun(*args, **kwargs):
return wrapper


@contextmanager
def timer(name, reservoir_type="uniform", *reservoir_args, **reservoir_kwargs):
"""
Time-measuring context manager: the time spent in the wrapped block
if measured and added to the named metric.
"""

hmetric = get_or_create_histogram(name, reservoir_type, *reservoir_args, **reservoir_kwargs)

t1 = time.time()
yield
t2 = time.time()
hmetric.notify(t2 - t1)


def tag(name, tag_name):
"""
Tag the named metric with the given tag.
Expand Down
7 changes: 0 additions & 7 deletions appmetrics/tests/test_histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,13 +361,6 @@ def test_notify(self):
[mock.call(1.2)])
nt.assert_equal(result, self.reservoir.add.return_value)

def test_time(self):
self.histogram.notify = mock.Mock()
with self.histogram.time():
pass

nt.assert_equal(self.histogram.notify.call_count, 1)

def test_raw_data(self):
result = self.histogram.raw_data()
nt.assert_equal(result, self.reservoir.values)
Expand Down
32 changes: 32 additions & 0 deletions appmetrics/tests/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,38 @@ def f2(v1, v2):

return v1*v2

@mock.patch('appmetrics.histogram.Histogram.notify')
def test_timer(self, notify):
with mm.timer("test"):
pass

assert_equal(notify.call_count, 1)

@mock.patch('appmetrics.histogram.Histogram.notify')
def test_timer_multiple(self, notify):
with mm.timer("test"):
pass

with mm.timer("test"):
pass

assert_equal(notify.call_count, 2)

@raises(exceptions.DuplicateMetricError)
def test_timer_multiple_different_reservoir(self):
with mm.timer("test", reservoir_type="sliding_window"):
pass

with mm.timer("test"):
pass

@raises(exceptions.DuplicateMetricError)
def test_timer_multiple_different_type(self):
mm.new_gauge("test")

with mm.timer("test"):
pass

@raises(exceptions.InvalidMetricError)
def test_tag_invalid_name(self):
mm.tag("test", "test")
Expand Down

0 comments on commit edba4a4

Please sign in to comment.