Skip to content
This repository was archived by the owner on May 31, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 57 additions & 45 deletions yunomi/core/metrics_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def dump_metrics(self):
timer = _global_registry.timer
dump_metrics = _global_registry.dump_metrics

def count_calls(fn):
def count_calls(prefix=None):
"""
Decorator to track the number of times a function is called.

Expand All @@ -182,16 +182,19 @@ def count_calls(fn):
@return: the decorated function
@rtype: C{func}
"""
@wraps(fn)
def wrapper(*args):
counter("%s_calls" % fn.__name__).inc()
try:
return fn(*args)
except:
raise
return wrapper

def meter_calls(fn):
def decorator(fn):
@wraps(fn)
def wrapper(*args):
n = "%s_calls" if prefix is None else "%s_%%s_calls" % prefix
counter(n % fn.__name__).inc()
try:
return fn(*args)
except:
raise
return wrapper
return decorator

def meter_calls(prefix=None):
"""
Decorator to the rate at which a function is called.

Expand All @@ -201,16 +204,19 @@ def meter_calls(fn):
@return: the decorated function
@rtype: C{func}
"""
@wraps(fn)
def wrapper(*args):
meter("%s_calls" % fn.__name__).mark()
try:
return fn(*args)
except:
raise
return wrapper

def hist_calls(fn):
def decorator(fn):
@wraps(fn)
def wrapper(*args):
n = "%s_calls" if prefix is None else "%s_%%s_calls" % prefix
meter(n % fn.__name__).mark()
try:
return fn(*args)
except:
raise
return wrapper
return decorator

def hist_calls(prefix=None):
"""
Decorator to check the distribution of return values of a function.

Expand All @@ -220,19 +226,22 @@ def hist_calls(fn):
@return: the decorated function
@rtype: C{func}
"""
@wraps(fn)
def wrapper(*args):
_histogram = histogram("%s_calls" % fn.__name__)
try:
rtn = fn(*args)
if type(rtn) in (int, float):
_histogram.update(rtn)
return rtn
except:
raise
return wrapper

def time_calls(fn):
def decorator(fn):
@wraps(fn)
def wrapper(*args):
n = "%s_calls" if prefix is None else "%s_%%s_calls" % prefix
_histogram = histogram(n % fn.__name__)
try:
rtn = fn(*args)
if type(rtn) in (int, float):
_histogram.update(rtn)
return rtn
except:
raise
return wrapper
return decorator

def time_calls(prefix=None):
"""
Decorator to time the execution of the function.

Expand All @@ -242,14 +251,17 @@ def time_calls(fn):
@return: the decorated function
@rtype: C{func}
"""
@wraps(fn)
def wrapper(*args):
_timer = timer("%s_calls" % fn.__name__)
start = time()
try:
return fn(*args)
except:
raise
finally:
_timer.update(time() - start)
return wrapper
def decorator(fn):
@wraps(fn)
def wrapper(*args):
n = "%s_calls" if prefix is None else "%s_%%s_calls" % prefix
_timer = timer(n % fn.__name__)
start = time()
try:
return fn(*args)
except:
raise
finally:
_timer.update(time() - start)
return wrapper
return decorator
51 changes: 34 additions & 17 deletions yunomi/tests/test_metrics_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,18 @@ def test_getters_create_metrics(self):
self.assertEqual(stat["value"], 0)

def test_count_calls_decorator(self):
@count_calls
@count_calls("namespace")
def test():
pass

for i in xrange(10):
test()
self.assertEqual(counter("test_calls").get_count(), 10)
self.assertEqual(counter("namespace_test_calls").get_count(), 10)

@mock.patch("yunomi.core.meter.time")
def test_meter_calls_decorator(self, time_mock):
time_mock.return_value = 0
@meter_calls
@meter_calls()
def test():
pass

Expand All @@ -65,7 +65,7 @@ def test():


def test_hist_calls_decorator(self):
@hist_calls
@hist_calls()
def test(n):
return n

Expand All @@ -87,7 +87,7 @@ def test(n):
@mock.patch("yunomi.core.metrics_registry.time")
def test_time_calls_decorator(self, time_mock):
time_mock.return_value = 0.0
@time_calls
@time_calls()
def test():
time_mock.return_value += 1.0

Expand All @@ -105,73 +105,90 @@ def test():
self.assertAlmostEqual(snapshot.get_999th_percentile(), 1.0)

def test_count_calls_decorator_returns_original_return_value(self):
@count_calls
@count_calls()
def test():
return 1
self.assertEqual(test(), 1)

def test_meter_calls_decorator_returns_original_return_value(self):
@meter_calls
@meter_calls()
def test():
return 1
self.assertEqual(test(), 1)

def test_hist_calls_decorator_returns_original_return_value(self):
@hist_calls
@hist_calls()
def test():
return 1
self.assertEqual(test(), 1)

def test_time_calls_decorator_returns_original_return_value(self):
@time_calls
@time_calls()
def test():
return 1
self.assertEqual(test(), 1)

def test_count_calls_decorator_keeps_function_name(self):
@count_calls
@count_calls()
def test():
pass
self.assertEqual(test.__name__, 'test')

def test_meter_calls_decorator_keeps_function_name(self):
@meter_calls
@meter_calls()
def test():
pass
self.assertEqual(test.__name__, 'test')

def test_hist_calls_decorator_keeps_function_name(self):
@hist_calls
@hist_calls()
def test():
pass
self.assertEqual(test.__name__, 'test')

def test_time_calls_decorator_keeps_function_name(self):
@time_calls
@time_calls()
def test():
pass
self.assertEqual(test.__name__, 'test')

def test_count_calls_decorator_propagates_errors(self):
@count_calls
@count_calls()
def test():
raise Exception('what')
self.assertRaises(Exception, test)

def test_meter_calls_decorator_propagates_errors(self):
@meter_calls
@meter_calls()
def test():
raise Exception('what')
self.assertRaises(Exception, test)

def test_hist_calls_decorator_propagates_errors(self):
@hist_calls
@hist_calls()
def test():
raise Exception('what')
self.assertRaises(Exception, test)

def test_time_calls_decorator_propagates_errors(self):
@time_calls
@time_calls()
def test():
raise Exception('what')
self.assertRaises(Exception, test)

def test_decorator_does_not_shadow_functions_with_same_name(self):
class Foo(object):
@count_calls("foo")
def test(self):
return 1

class Bar(object):
@count_calls("bar")
def test(self):
return 1

Foo().test()
Bar().test()

self.assertEqual(counter("foo_test_calls").get_count(), 1)
self.assertEqual(counter("bar_test_calls").get_count(), 1)