2015-08-17 16:03:49 +00:00
|
|
|
import datetime
|
2015-08-11 20:52:05 +00:00
|
|
|
import logging
|
2015-08-12 15:58:04 +00:00
|
|
|
import time
|
2015-08-11 20:52:05 +00:00
|
|
|
|
2015-08-12 15:58:04 +00:00
|
|
|
from functools import wraps
|
2015-08-11 20:52:05 +00:00
|
|
|
from Queue import Queue, Full
|
|
|
|
|
2015-08-12 15:58:04 +00:00
|
|
|
from flask import g, request
|
|
|
|
|
2015-08-11 20:52:05 +00:00
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
2015-08-11 20:39:33 +00:00
|
|
|
|
|
|
|
class MetricQueue(object):
|
|
|
|
def __init__(self):
|
2015-08-12 19:14:09 +00:00
|
|
|
self._queue = None
|
|
|
|
|
|
|
|
def enable(self, maxsize=10000):
|
|
|
|
self._queue = Queue(maxsize)
|
2015-08-11 20:39:33 +00:00
|
|
|
|
2015-08-17 16:03:49 +00:00
|
|
|
def put(self, name, value, **kwargs):
|
2015-08-12 19:14:09 +00:00
|
|
|
if self._queue is None:
|
2015-08-17 20:26:20 +00:00
|
|
|
logger.debug('No metric queue %s %s %s', name, value, kwargs)
|
2015-08-12 19:14:09 +00:00
|
|
|
return
|
2015-08-12 20:31:01 +00:00
|
|
|
|
2015-08-11 20:52:05 +00:00
|
|
|
try:
|
2015-08-17 16:03:49 +00:00
|
|
|
kwargs.setdefault('timestamp', datetime.datetime.now())
|
|
|
|
kwargs.setdefault('dimensions', {})
|
|
|
|
self._queue.put_nowait((name, value, kwargs))
|
2015-08-11 20:52:05 +00:00
|
|
|
except Full:
|
|
|
|
logger.error('Metric queue full')
|
2015-08-11 20:39:33 +00:00
|
|
|
|
|
|
|
def get(self):
|
2015-08-12 20:31:01 +00:00
|
|
|
return self._queue.get()
|
2015-08-12 15:58:04 +00:00
|
|
|
|
2015-08-17 16:03:49 +00:00
|
|
|
def get_nowait(self):
|
|
|
|
return self._queue.get_nowait()
|
|
|
|
|
2015-08-12 15:58:04 +00:00
|
|
|
def time_blueprint(bp, metric_queue):
|
|
|
|
bp.before_request(time_before_request)
|
|
|
|
bp.after_request(time_after_request(bp.name, metric_queue))
|
|
|
|
|
|
|
|
def time_before_request():
|
2015-08-12 20:31:01 +00:00
|
|
|
g._request_start_time = time.time()
|
2015-08-12 15:58:04 +00:00
|
|
|
|
|
|
|
def time_after_request(name, metric_queue):
|
|
|
|
def f(r):
|
2015-08-12 20:31:01 +00:00
|
|
|
start = getattr(g, '_request_start_time', None)
|
2015-08-12 15:58:04 +00:00
|
|
|
if start is None:
|
|
|
|
return r
|
2015-08-17 20:26:20 +00:00
|
|
|
|
2015-08-12 15:58:04 +00:00
|
|
|
dur = time.time() - start
|
2015-08-12 20:31:01 +00:00
|
|
|
dims = {'endpoint': request.endpoint}
|
2015-08-17 20:26:20 +00:00
|
|
|
|
2015-08-12 15:58:04 +00:00
|
|
|
metric_queue.put('ResponseTime', dur, dimensions=dims, unit='Seconds')
|
|
|
|
metric_queue.put('ResponseCode', r.status_code, dimensions=dims)
|
2015-12-16 18:52:08 +00:00
|
|
|
|
|
|
|
if r.status_code >= 500:
|
|
|
|
metric_queue.put('5XXResponse', 1, dimensions={'name': name})
|
|
|
|
elif r.status_code < 200 or r.status_code >= 300:
|
2015-08-12 15:58:04 +00:00
|
|
|
metric_queue.put('Non200Response', 1, dimensions={'name': name})
|
2015-08-17 20:26:20 +00:00
|
|
|
|
2015-08-12 15:58:04 +00:00
|
|
|
return r
|
|
|
|
return f
|
|
|
|
|
|
|
|
def time_decorator(name, metric_queue):
|
|
|
|
after = time_after_request(name, metric_queue)
|
|
|
|
def decorator(func):
|
|
|
|
@wraps(func)
|
|
|
|
def wrapper(*args, **kwargs):
|
|
|
|
time_before_request()
|
|
|
|
rv = func(*args, **kwargs)
|
|
|
|
after(rv)
|
|
|
|
return rv
|
|
|
|
return wrapper
|
|
|
|
return decorator
|