-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from claws/decorators
add decorators
- Loading branch information
Showing
13 changed files
with
450 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
|
||
from .collectors import ( | ||
Collector, Counter, Gauge, Summary, Histogram) | ||
from .decorators import count_exceptions, inprogress, timer | ||
from .formats import (BinaryFormatter, TextFormatter) | ||
from .pusher import Pusher | ||
from .registry import Registry, CollectorRegistry | ||
from .service import Service | ||
|
||
__version__ = "16.07.31" | ||
__version__ = "16.08.03" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
''' | ||
This module provides metrics decorators | ||
''' | ||
|
||
import asyncio | ||
import time | ||
|
||
from .collectors import Counter, Gauge, Summary | ||
from functools import wraps | ||
from typing import Any, Callable, Dict | ||
|
||
|
||
def timer(metric: Summary, | ||
labels: Dict[str, str] = None) -> Callable[..., Any]: | ||
''' | ||
This decorator provides a way for users to time code in seconds. | ||
This decorator function wraps a function with code to calculate how long | ||
the wrapped function takes to execute and updates the metric with the | ||
duration. | ||
:param metric: a metric to update with the calculated function duration. | ||
The metric object being updated is expected to be a Summary metric | ||
object. | ||
:param labels: a dict of extra labels to associate with the metric. | ||
:return: a coroutine function that wraps the decortated function | ||
''' | ||
if not isinstance(metric, Summary): | ||
raise Exception( | ||
'time decorator expects a Summary metric but got: {}'.format( | ||
metric)) | ||
|
||
def measure(func): | ||
''' | ||
This function wraps a decorated function with timing and metric | ||
updating logic. | ||
:param func: the callable to be timed. | ||
:returns: the return value from the decorated callable. | ||
''' | ||
@wraps(func) | ||
async def func_wrapper(*args, **kwds): | ||
start_time = time.time() | ||
rv = func(*args, **kwds) | ||
if isinstance(rv, asyncio.Future) or asyncio.iscoroutine(rv): | ||
rv = await rv | ||
metric.add(labels, time.time() - start_time) | ||
return rv | ||
|
||
return func_wrapper | ||
|
||
return measure | ||
|
||
|
||
def inprogress(metric: Gauge, | ||
labels: Dict[str, str] = None) -> Callable[..., Any]: | ||
''' | ||
This decorator provides a way for users to track in-progress requests | ||
(or other things) in some piece of code/function. | ||
This decorator function wraps a function with code to track how many | ||
of the measured items are in progress. | ||
The metric is incremented before calling the wrapped function and | ||
decremented when the wrapped function is complete. | ||
:param metric: a metric to increment and decrement. The metric object | ||
being updated is expected to be a Gauge metric object. | ||
:param labels: a dict of extra labels to associate with the metric. | ||
:return: a coroutine function that wraps the decortated function | ||
''' | ||
if not isinstance(metric, Gauge): | ||
raise Exception( | ||
'inprogess decorator expects a Gauge metric but got: {}'.format( | ||
metric)) | ||
|
||
def track(func): | ||
''' | ||
This function wraps a decorated function with metric incremeting | ||
and decrementing logic. | ||
:param func: the callable to be tracked. | ||
:returns: the return value from the decorated callable. | ||
''' | ||
@wraps(func) | ||
async def func_wrapper(*args, **kwds): | ||
metric.inc(labels) | ||
rv = func(*args, **kwds) | ||
if isinstance(rv, asyncio.Future) or asyncio.iscoroutine(rv): | ||
rv = await rv | ||
metric.dec(labels) | ||
return rv | ||
|
||
return func_wrapper | ||
|
||
return track | ||
|
||
|
||
def count_exceptions(metric: Counter, | ||
labels: Dict[str, str] = None) -> Callable[..., Any]: | ||
''' | ||
This decorator provides a way for users to track in-progress requests | ||
(or other things) in some piece of code/function. | ||
This decorator function wraps a function with code to track how many | ||
exceptions occur. | ||
:param metric: a metric to increment when an exception is caught. The | ||
metric object being updated is expected to be a Counter metric object. | ||
:param labels: a dict of extra labels to associate with the metric. | ||
:return: a coroutine function that wraps the decortated function | ||
''' | ||
if not isinstance(metric, Counter): | ||
raise Exception( | ||
'inprogess decorator expects a Counter metric but got: {}'.format( | ||
metric)) | ||
|
||
def track(func): | ||
''' | ||
This function wraps a decorated function with metric incremeting | ||
logic. | ||
:param func: the callable to be tracked. | ||
:returns: the return value from the decorated callable. | ||
''' | ||
@wraps(func) | ||
async def func_wrapper(*args, **kwds): | ||
try: | ||
rv = func(*args, **kwds) | ||
if isinstance(rv, asyncio.Future) or asyncio.iscoroutine(rv): | ||
rv = await rv | ||
except: | ||
metric.inc(labels) | ||
raise | ||
return rv | ||
|
||
return func_wrapper | ||
|
||
return track |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.