""" StatsD connector. Statsd and Graphite allows to graph data based on a specific key. This feature is handy when you need to keep track of performance, number of times an endpoint is fetched and more. For local environments (unless the STATSD_CLIENT, STATSDPORT, and STATSD_PREFIX is specified), no metrics are sent to our report server (this is meant so none of our production metrics are polluted.) Please: do not enable this on `api-dev`. """ import time import statsd from analytics import config connection = None if config.STATSD_CLIENT and config.STATSD_PORT and config.STATSD_PREFIX: connection = statsd.StatsClient( host=config.STATSD_CLIENT, port=config.STATSD_PORT, prefix=config.STATSD_PREFIX) def metric(metric_key, count=1): """Define a decorator for metrics. Args: key (str): the metric key name. count (int): the count to add. Returns: callable: The decorator. """ def decorator(fn): def wrapper(*args, **kwargs): response = fn(*args, **kwargs) send_metric(key(metric_key).format(key=key), count=count) return response return wrapper return decorator def timing(metric_key): """Time an execution. Performance profiling is important: it allows to know how much time is spent on specific endpoints or methods. Args: metric_key: the metric key name. Returns: callable: the decorator """ def decorator(fn): def wrapper(*args, **kwargs): start_time = time.time() * 1000 response = fn(*args, **kwargs) end_time = time.time() * 1000 send_timer( key(metric_key), delta=end_time - start_time) return response return wrapper return decorator def key(metric_key): """Create a namespaced key for grass. Args: metric_key (str): the metric key. Returns: str: the key. """ return 'ows.analytics.{metric_key}'.format(metric_key=metric_key) def send_metric(key, count=1): """Sent metric to graphite. Calling this method, the metric is immediately sent to graphite. Args: key (str): the metric key name. count (int): the number to add to the metric. """ if not connection: return assert key.startswith('ows.analytics.') connection.incr(key, count=count) def send_timer(key, delta): """Send a timer to statsd. Add information on how long a process took. Args: key (str): the metric key name. delta (int): the time difference (in ms) """ if not connection: return assert key.startswith('ows.analytics.') connection.timing(key, delta=delta)