# Path: tapes/local/meter.py
# class Meter(Stat):
#     def __init__(self):
#         self.last_tick = time()
#         self.count = 0
#         self.m1 = EWMA.one()
#         self.m5 = EWMA.five()
#         self.m15 = EWMA.fifteen()
# 
#     def mark(self, n=1):
#         self._tick_if_needed()
#         self.count += n
#         self.m1.update(n)
#         self.m5.update(n)
#         self.m15.update(n)
# 
#     def _get_one_minute(self):
#         self._tick_if_needed()
#         return self.m1.get_rate()
# 
#     def _get_five_minute(self):
#         self._tick_if_needed()
#         return self.m5.get_rate()
# 
#     def _get_fifteen_minute(self):
#         self._tick_if_needed()
#         return self.m15.get_rate()
# 
#     def _tick_if_needed(self):
#         old_tick = self.last_tick
#         new_tick = time()
#         age = new_tick - old_tick
#         if age > _INTERVAL:
#             new_interval_start_tick = new_tick - age % _INTERVAL
#             self.last_tick = new_interval_start_tick
#             required_ticks = int(age // _INTERVAL)
#             for _ in range(required_ticks):
#                 self.m1.tick()
#                 self.m5.tick()
#                 self.m15.tick()
# 
#     def get_values(self):
#         return {
#             'count': self.count,
#             'm1': self._get_one_minute(),
#             'm5': self._get_five_minute(),
#             'm15': self._get_fifteen_minute(),
#         }
# 
# Path: tapes/local/counter.py
# class Counter(Stat):
#     def __init__(self):
#         self.count = 0
# 
#     def get_values(self):
#         return {
#             'value': self.count
#         }
# 
#     def increment(self, n=1):
#         self.count += n
# 
#     def decrement(self, n=1):
#         self.count -= n
# 
# Path: tapes/local/gauge.py
# class Gauge(Stat):
#     def __init__(self, producer):
#         self.producer = producer
# 
#     def get_values(self):
#         return {
#             'value': self.producer()
#         }
# 
# Path: tapes/local/histogram.py
# class Histogram(Stat):
#     def __init__(self):
#         self.count = 0
#         self.reservoir = ExponentiallyDecayingReservoir()
# 
#     def update(self, value):
#         self.count += 1
#         self.reservoir.update(value)
# 
#     def get_values(self):
#         snapshot = self.reservoir.get_snapshot()
#         return {
#             'count': self.count,
#             'min': snapshot.get_min(),
#             'max': snapshot.get_max(),
#             'mean': snapshot.get_mean(),
#             'stddev': snapshot.get_sd(),
#             'q50': snapshot.get_quantile(0.5),
#             'q75': snapshot.get_quantile(0.75),
#             'q95': snapshot.get_quantile(0.95),
#             'q98': snapshot.get_quantile(0.98),
#             'q99': snapshot.get_quantile(0.99),
#             'q999': snapshot.get_quantile(0.999),
#         }
# 
# Path: tapes/local/timer.py
# class Timer(Stat):
#     def __init__(self):
#         self.count = 0
#         self.meter = Meter()
#         self.histogram = Histogram()
#         super(Timer, self).__init__()
# 
#     @contextlib.contextmanager
#     def time(self):
#         start_time = time()
#         try:
#             yield
#         finally:
#             self.update(time() - start_time)
# 
#     def update(self, value):
#         self.meter.mark()
#         self.histogram.update(value)
# 
#     def get_values(self):
#         values = self.meter.get_values()
#         values.update(self.histogram.get_values())
#         return values


import functools
import abc
import six
from addict import Dict
from .local.meter import Meter
from .local.counter import Counter
from .local.gauge import Gauge
from .local.histogram import Histogram
from .local.timer import Timer

    @abc.abstractmethod
    def counter(self, name):
        raise NotImplementedError()

    @abc.abstractmethod
    def histogram(self, name):
        raise NotImplementedError()


class Registry(BaseRegistry):
    """Factory and storage location for all metrics stuff.

    Use producer methods to create metrics. Metrics are hierarchical, the names are split on '.'.
    """

    def meter(self, name):
        """Creates or gets an existing meter.

        :param name: The name
        :return: The created or existing meter for the given name
        """
        return self._get_or_add_stat(name, Meter)

    def timer(self, name):
        """Creates or gets an existing timer.

        :param name: The name
        :return: The created or existing timer for the given name
        """

# Path: tapes/local/meter.py
# class Meter(Stat):
#     def __init__(self):
#         self.last_tick = time()
#         self.count = 0
#         self.m1 = EWMA.one()
#         self.m5 = EWMA.five()
#         self.m15 = EWMA.fifteen()
# 
#     def mark(self, n=1):
#         self._tick_if_needed()
#         self.count += n
#         self.m1.update(n)
#         self.m5.update(n)
#         self.m15.update(n)
# 
#     def _get_one_minute(self):
#         self._tick_if_needed()
#         return self.m1.get_rate()
# 
#     def _get_five_minute(self):
#         self._tick_if_needed()
#         return self.m5.get_rate()
# 
#     def _get_fifteen_minute(self):
#         self._tick_if_needed()
#         return self.m15.get_rate()
# 
#     def _tick_if_needed(self):
#         old_tick = self.last_tick
#         new_tick = time()
#         age = new_tick - old_tick
#         if age > _INTERVAL:
#             new_interval_start_tick = new_tick - age % _INTERVAL
#             self.last_tick = new_interval_start_tick
#             required_ticks = int(age // _INTERVAL)
#             for _ in range(required_ticks):
#                 self.m1.tick()
#                 self.m5.tick()
#                 self.m15.tick()
# 
#     def get_values(self):
#         return {
#             'count': self.count,
#             'm1': self._get_one_minute(),
#             'm5': self._get_five_minute(),
#             'm15': self._get_fifteen_minute(),
#         }
# 
# Path: tapes/local/counter.py
# class Counter(Stat):
#     def __init__(self):
#         self.count = 0
# 
#     def get_values(self):
#         return {
#             'value': self.count
#         }
# 
#     def increment(self, n=1):
#         self.count += n
# 
#     def decrement(self, n=1):
#         self.count -= n
# 
# Path: tapes/local/gauge.py
# class Gauge(Stat):
#     def __init__(self, producer):
#         self.producer = producer
# 
#     def get_values(self):
#         return {
#             'value': self.producer()
#         }
# 
# Path: tapes/local/histogram.py
# class Histogram(Stat):
#     def __init__(self):
#         self.count = 0
#         self.reservoir = ExponentiallyDecayingReservoir()
# 
#     def update(self, value):
#         self.count += 1
#         self.reservoir.update(value)
# 
#     def get_values(self):
#         snapshot = self.reservoir.get_snapshot()
#         return {
#             'count': self.count,
#             'min': snapshot.get_min(),
#             'max': snapshot.get_max(),
#             'mean': snapshot.get_mean(),
#             'stddev': snapshot.get_sd(),
#             'q50': snapshot.get_quantile(0.5),
#             'q75': snapshot.get_quantile(0.75),
#             'q95': snapshot.get_quantile(0.95),
#             'q98': snapshot.get_quantile(0.98),
#             'q99': snapshot.get_quantile(0.99),
#             'q999': snapshot.get_quantile(0.999),
#         }
# 
# Path: tapes/local/timer.py
# class Timer(Stat):
#     def __init__(self):
#         self.count = 0
#         self.meter = Meter()
#         self.histogram = Histogram()
#         super(Timer, self).__init__()
# 
#     @contextlib.contextmanager
#     def time(self):
#         start_time = time()
#         try:
#             yield
#         finally:
#             self.update(time() - start_time)
# 
#     def update(self, value):
#         self.meter.mark()
#         self.histogram.update(value)
# 
#     def get_values(self):
#         values = self.meter.get_values()
#         values.update(self.histogram.get_values())
#         return values


# Path: tapes/registry.py
import functools
import abc
import six
from addict import Dict
from .local.meter import Meter
from .local.counter import Counter
from .local.gauge import Gauge
from .local.histogram import Histogram
from .local.timer import Timer


    @abc.abstractmethod
    def counter(self, name):
        raise NotImplementedError()

    @abc.abstractmethod
    def histogram(self, name):
        raise NotImplementedError()


class Registry(BaseRegistry):
    """Factory and storage location for all metrics stuff.

    Use producer methods to create metrics. Metrics are hierarchical, the names are split on '.'.
    """

    def meter(self, name):
        """Creates or gets an existing meter.

        :param name: The name
        :return: The created or existing meter for the given name
        """
        return self._get_or_add_stat(name, Meter)

    def timer(self, name):
        """Creates or gets an existing timer.

        :param name: The name
        :return: The created or existing timer for the given name
        """

        return self._get_or_add_stat(name, Timer)