<s> """<STR_LIT>""" <EOL> from contextlib import contextmanager <EOL> import functools <EOL> import threading <EOL> import time <EOL> from . exceptions import DuplicateMetricError , InvalidMetricError <EOL> from . import histogram , simple_metrics , meter , py3comp <EOL> REGISTRY = { } <EOL> TAGS = { } <EOL> LOCK = threading . Lock ( ) <EOL> def new_metric ( name , class_ , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> with LOCK : <EOL> try : <EOL> item = REGISTRY [ name ] <EOL> except KeyError : <EOL> item = REGISTRY [ name ] = class_ ( * args , ** kwargs ) <EOL> return item <EOL> raise DuplicateMetricError ( "<STR_LIT>" . format ( name , type ( item ) . __name__ ) ) <EOL> def delete_metric ( name ) : <EOL> """<STR_LIT>""" <EOL> with LOCK : <EOL> old_metric = REGISTRY . pop ( name , None ) <EOL> for _ , tags in py3comp . iteritems ( TAGS ) : <EOL> if name in tags : <EOL> tags . remove ( name ) <EOL> return old_metric <EOL> def metric ( name ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return REGISTRY [ name ] <EOL> except KeyError as e : <EOL> raise InvalidMetricError ( "<STR_LIT>" . format ( e ) ) <EOL> def metrics ( ) : <EOL> """<STR_LIT>""" <EOL> return sorted ( REGISTRY . keys ( ) ) <EOL> def get ( name ) : <EOL> """<STR_LIT>""" <EOL> return metric ( name ) . get ( ) <EOL> def notify ( name , value ) : <EOL> """<STR_LIT>""" <EOL> return metric ( name ) . notify ( value ) <EOL> def new_histogram ( name , reservoir = None ) : <EOL> """<STR_LIT>""" <EOL> if reservoir is None : <EOL> reservoir = histogram . UniformReservoir ( histogram . DEFAULT_UNIFORM_RESERVOIR_SIZE ) <EOL> return new_metric ( name , histogram . Histogram , reservoir ) <EOL> def new_counter ( name ) : <EOL> """<STR_LIT>""" <EOL> return new_metric ( name , simple_metrics . Counter ) <EOL> def new_gauge ( name ) : <EOL> """<STR_LIT>""" <EOL> return new_metric ( name , simple_metrics . Gauge ) <EOL> def new_meter ( name , tick_interval = <NUM_LIT:5> ) : <EOL> """<STR_LIT>""" <EOL> return new_metric ( name , meter . Meter , tick_interval ) <EOL> def new_histogram_with_implicit_reservoir ( name , reservoir_type = '<STR_LIT>' , * reservoir_args , ** reservoir_kwargs ) : <EOL> """<STR_LIT>""" <EOL> reservoir = new_reservoir ( reservoir_type , * reservoir_args , ** reservoir_kwargs ) <EOL> return new_histogram ( name , reservoir ) <EOL> def new_reservoir ( reservoir_type = '<STR_LIT>' , * reservoir_args , ** reservoir_kwargs ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> reservoir_cls = RESERVOIR_TYPES [ reservoir_type ] <EOL> except KeyError : <EOL> raise InvalidMetricError ( "<STR_LIT>" . format ( reservoir_type ) ) <EOL> return reservoir_cls ( * reservoir_args , ** reservoir_kwargs ) <EOL> def get_or_create_histogram ( name , reservoir_type , * reservoir_args , ** reservoir_kwargs ) : <EOL> """<STR_LIT>""" <EOL> reservoir = new_reservoir ( reservoir_type , * reservoir_args , ** reservoir_kwargs ) <EOL> try : <EOL> hmetric = new_histogram ( name , reservoir ) <EOL> except DuplicateMetricError : <EOL> hmetric = metric ( name ) <EOL> if not isinstance ( hmetric , histogram . Histogram ) : <EOL> raise DuplicateMetricError ( <EOL> "<STR_LIT>" . format ( name , type ( hmetric ) . __name__ ) ) <EOL> if not hmetric . reservoir . same_kind ( reservoir ) : <EOL> raise DuplicateMetricError ( <EOL> "<STR_LIT>" . format ( name , hmetric . reservoir ) ) <EOL> return hmetric <EOL> def with_histogram ( name , reservoir_type = "<STR_LIT>" , * reservoir_args , ** reservoir_kwargs ) : <EOL> """<STR_LIT>""" <EOL> hmetric = get_or_create_histogram ( name , reservoir_type , * reservoir_args , ** reservoir_kwargs ) <EOL> def wrapper ( f ) : <EOL> @ functools . wraps ( f ) <EOL> def fun ( * args , ** kwargs ) : <EOL> t1 = time . time ( ) <EOL> res = f ( * args , ** kwargs ) <EOL> t2 = time . time ( ) <EOL> hmetric . notify ( t2 - t1 ) <EOL> return res <EOL> return fun <EOL> return wrapper <EOL> def with_meter ( name , tick_interval = meter . DEFAULT_TICK_INTERVAL ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> mmetric = new_meter ( name , tick_interval ) <EOL> except DuplicateMetricError as e : <EOL> mmetric = metric ( name ) <EOL> if not isinstance ( mmetric , meter . Meter ) : <EOL> raise DuplicateMetricError ( "<STR_LIT>" . format ( name , type ( mmetric ) . __name__ ) ) <EOL> if tick_interval != mmetric . tick_interval : <EOL> raise DuplicateMetricError ( "<STR_LIT>" . format ( name , mmetric ) ) <EOL> def wrapper ( f ) : <EOL> @ functools . wraps ( f ) <EOL> def fun ( * args , ** kwargs ) : <EOL> res = f ( * args , ** kwargs ) <EOL> mmetric . notify ( <NUM_LIT:1> ) <EOL> return res <EOL> return fun <EOL> return wrapper <EOL> @ contextmanager <EOL> def timer ( name , reservoir_type = "<STR_LIT>" , * reservoir_args , ** reservoir_kwargs ) : <EOL> """<STR_LIT>""" <EOL> hmetric = get_or_create_histogram ( name , reservoir_type , * reservoir_args , ** reservoir_kwargs ) <EOL> t1 = time . time ( ) <EOL> yield <EOL> t2 = time . time ( ) <EOL> hmetric . notify ( t2 - t1 ) <EOL> def tag ( name , tag_name ) : <EOL> """<STR_LIT>""" <EOL> with LOCK : <EOL> metric ( name ) <EOL> TAGS . setdefault ( tag_name , set ( ) ) . add ( name ) <EOL> def tags ( ) : <EOL> """<STR_LIT>""" <EOL> return TAGS . copy ( ) <EOL> def metrics_by_tag ( tag_name ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> names = TAGS [ tag_name ] <EOL> except KeyError : <EOL> return { } <EOL> return metrics_by_name_list ( names ) <EOL> def untag ( name , tag_name ) : <EOL> """<STR_LIT>""" <EOL> with LOCK : <EOL> by_tag = TAGS . get ( tag_name , None ) <EOL> if not by_tag : <EOL> return False <EOL> try : <EOL> by_tag . remove ( name ) <EOL> if not by_tag : <EOL> TAGS . pop ( tag_name ) <EOL> return True <EOL> except KeyError : <EOL> return False <EOL> def metrics_by_name_list ( names ) : <EOL> """<STR_LIT>""" <EOL> results = { } <EOL> for name in names : <EOL> try : <EOL> results [ name ] = get ( name ) <EOL> except InvalidMetricError : <EOL> continue <EOL> return results <EOL> RESERVOIR_TYPES = { <EOL> '<STR_LIT>' : histogram . UniformReservoir , <EOL> '<STR_LIT>' : histogram . SlidingWindowReservoir , <EOL> '<STR_LIT>' : histogram . SlidingTimeWindowReservoir , <EOL> '<STR_LIT>' : histogram . ExponentialDecayingReservoir , <EOL> } <EOL> METRIC_TYPES = { <EOL> '<STR_LIT>' : new_histogram_with_implicit_reservoir , <EOL> '<STR_LIT>' : new_gauge , <EOL> '<STR_LIT>' : new_counter , <EOL> '<STR_LIT>' : new_meter , <EOL> } </s>
