mirror of
https://github.com/sprockets/sprockets.mixins.metrics.git
synced 2024-11-22 03:00:25 +00:00
commit
1d6c2b7597
13 changed files with 83 additions and 12 deletions
10
.travis.yml
10
.travis.yml
|
@ -13,3 +13,13 @@ script: nosetests --with-coverage
|
|||
after_success:
|
||||
- codecov
|
||||
sudo: false
|
||||
deploy:
|
||||
provider: pypi
|
||||
user: sprockets
|
||||
password:
|
||||
secure: EMA/RMTwgN452CnnJxf34KIkUEY4ehiPe7kgF35i11iGti3AR/i4yxi78lD/9010rfynoRZL6eKMg+RiG1uxEQckkbu/HKcjz1VlY+Sz4KYPzY9xAcyf6kLZ4CxglfhXr+Fz0nGjsfNoM5vKVShXOVH1lJBTSjnNqHV0pt1U6R0dPhyDObfsJg/0Pax+Cyld8XaFXRGs5VcYvhkzn+L3bpTUD7EfVIsdEPO9hmz1tH9xgsVtw6Qacgpub6Zns3ODX4hj/rYS7jmQSlWBQHH2UyhQOSZ1hF9JoECMjBOAHLQknnTIGeVdT/ma20Snk3IaaCK0qEmfMUC/WMOCn3J9MlPLTbHN1sr2/6OL3zSnJKO5Cd1K7zzZfro6dkv2MaqrGuo/ZxgZPPftj+fX8pXdd7gXCtjLTUmSzIBABuWuYv9toDd8drII+qgAWv2f5GEZSkUL0OnjKlse+vWtdtAIVl4Jz9RZnwS4V9f+dHaNLiuvFCiyRzY4BgBfLOoYDi/1FOu42y+QNaQq4uTfeioUx6bl+MQOiJ43c1v0Ib8hxpm34nU9L7IFLcrrmjA6PK585Fcemk6lUrRSozrIzptBLmIAr5GsHjuBgGuWV19bR7RUA/hvWQhmpS6rqFqJAEQ1cWK+LKdHIKY/XFU3lI6beh8P+L0UEt55xHyxDFfsWKE=
|
||||
on:
|
||||
tags: true
|
||||
distributions: sdist bdist_wheel
|
||||
all_branches: true
|
||||
python: 3.4
|
||||
|
|
0
docs/custom.css → docs/_static/custom.css
vendored
0
docs/custom.css → docs/_static/custom.css
vendored
12
docs/api.rst
12
docs/api.rst
|
@ -21,6 +21,7 @@ implements the same interface:
|
|||
self.record_timing(self.request.request_time(), 'request', 'lookup')
|
||||
|
||||
.. method:: increase_counter(*path, amount=1)
|
||||
:noindex:
|
||||
|
||||
:param path: counter path to increment
|
||||
:keyword int amount: value to increase the counter by
|
||||
|
@ -30,6 +31,7 @@ implements the same interface:
|
|||
self.increase_counter('db', 'query', 'foo')
|
||||
|
||||
.. method:: execution_timer(*path)
|
||||
:noindex:
|
||||
|
||||
:param path: timing path to record
|
||||
|
||||
|
@ -41,6 +43,16 @@ implements the same interface:
|
|||
with self.execution_timer('db', 'query', 'foo'):
|
||||
rows = yield self.session.query('SELECT * FROM foo')
|
||||
|
||||
.. method:: set_metric_tag(tag, value)
|
||||
:noindex:
|
||||
|
||||
:param str tag: the tag to set
|
||||
:param str value: the value to assign to the tag
|
||||
|
||||
This method stores a tag and value pair to be reported with
|
||||
metrics. It is only implemented on back-ends that support
|
||||
tagging metrics (e.g., :class:`sprockets.mixins.metrics.InfluxDBMixin`)
|
||||
|
||||
|
||||
Statsd Implementation
|
||||
---------------------
|
||||
|
|
|
@ -21,7 +21,7 @@ master_doc = 'index'
|
|||
exclude_patterns = []
|
||||
pygments_style = 'sphinx'
|
||||
html_style = 'custom.css'
|
||||
html_static_path = ['.']
|
||||
html_static_path = ['_static']
|
||||
html_theme = 'alabaster'
|
||||
html_theme_path = [alabaster.get_path()]
|
||||
html_sidebars = {
|
||||
|
@ -33,6 +33,7 @@ html_theme_options = {
|
|||
'description': 'Application metrics tracker',
|
||||
'github_banner': True,
|
||||
'travis_button': True,
|
||||
'codecov_button': True,
|
||||
}
|
||||
|
||||
intersphinx_mapping = {
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
Release History
|
||||
===============
|
||||
|
||||
`Next Release`_
|
||||
---------------
|
||||
`0.9.0`_ (27-Jan-2016)
|
||||
----------------------
|
||||
- Add :class:`sprockets.mixins.metrics.StatsdMixin`
|
||||
- Add :class:`sprockets.mixins.metrics.testing.FakeStatsdServer`
|
||||
- Add :class:`sprockets.mixins.metrics.testing.FakeInfluxHandler`
|
||||
- Add :class:`sprockets.mixins.metrics.InfluxDBMixin`
|
||||
- Add :class:`sprockets.mixins.metrics.influxdb.InfluxDBConnection`
|
||||
|
||||
.. _Next Release: https://github.com/sprockets/sprockets.mixins.metrics/compare/0.0.0...master
|
||||
.. _Next Release: https://github.com/sprockets/sprockets.mixins.metrics/compare/0.9.0...master
|
||||
.. _0.9.0: https://github.com/sprockets/sprockets.mixins.metrics/compare/0.0.0...0.9.0
|
||||
|
|
|
@ -2,7 +2,7 @@ import os
|
|||
import signal
|
||||
|
||||
from sprockets.mixins import metrics
|
||||
from tornado import gen, ioloop, web
|
||||
from tornado import concurrent, gen, ioloop, web
|
||||
|
||||
|
||||
class SimpleHandler(metrics.InfluxDBMixin, web.RequestHandler):
|
||||
|
@ -32,6 +32,16 @@ class SimpleHandler(metrics.InfluxDBMixin, web.RequestHandler):
|
|||
|
||||
"""
|
||||
|
||||
@gen.coroutine
|
||||
def prepare(self):
|
||||
maybe_future = super(SimpleHandler, self).prepare()
|
||||
if concurrent.is_future(maybe_future):
|
||||
yield maybe_future
|
||||
|
||||
if 'Correlation-ID' in self.request.headers:
|
||||
self.set_metric_tag('correlation_id',
|
||||
self.request.headers['Correlation-ID'])
|
||||
|
||||
@gen.coroutine
|
||||
def get(self):
|
||||
with self.execution_timer('sleepytime'):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import signal
|
||||
|
||||
from sprockets.mixins import metrics
|
||||
from tornado import gen, ioloop, web
|
||||
from tornado import concurrent, gen, ioloop, web
|
||||
|
||||
|
||||
class SimpleHandler(metrics.StatsdMixin, web.RequestHandler):
|
||||
|
@ -14,6 +14,16 @@ class SimpleHandler(metrics.StatsdMixin, web.RequestHandler):
|
|||
|
||||
"""
|
||||
|
||||
@gen.coroutine
|
||||
def prepare(self):
|
||||
maybe_future = super(SimpleHandler, self).prepare()
|
||||
if concurrent.is_future(maybe_future):
|
||||
yield maybe_future
|
||||
|
||||
if 'Correlation-ID' in self.request.headers:
|
||||
self.set_metric_tag('correlation_id',
|
||||
self.request.headers['Correlation-ID'])
|
||||
|
||||
@gen.coroutine
|
||||
def get(self):
|
||||
yield gen.sleep(0.25)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
[bdist_wheel]
|
||||
universal = 1
|
||||
[nosetests]
|
||||
cover-package = sprockets.mixins.metrics
|
||||
cover-branches = 1
|
||||
|
|
2
setup.py
2
setup.py
|
@ -39,7 +39,7 @@ setuptools.setup(
|
|||
packages=setuptools.find_packages(exclude=['examples.']),
|
||||
namespace_packages=['sprockets', 'sprockets.mixins'],
|
||||
classifiers=[
|
||||
'Development Status :: 1 - Planning',
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Environment :: No Input/Output (Daemon)',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from .influxdb import InfluxDBMixin
|
||||
from .statsd import StatsdMixin
|
||||
|
||||
version_info = (0, 0, 0)
|
||||
version_info = (0, 9, 0)
|
||||
__version__ = '.'.join(str(v) for v in version_info)
|
||||
__all__ = ['InfluxDBMixin', 'StatsdMixin']
|
||||
|
|
|
@ -137,6 +137,6 @@ class InfluxDBMixin(object):
|
|||
self.record_timing(self.request.request_time(), 'duration')
|
||||
self.settings[self.SETTINGS_KEY]['db_connection'].submit(
|
||||
self.settings[self.SETTINGS_KEY]['measurement'],
|
||||
('{}={}'.format(k, v) for k, v in self.__tags.items()),
|
||||
('{}="{}"'.format(k, v) for k, v in self.__tags.items()),
|
||||
self.__metrics,
|
||||
)
|
||||
|
|
|
@ -39,6 +39,9 @@ class StatsdMixin(object):
|
|||
settings.setdefault('port', '8125')
|
||||
self.__status_code = None
|
||||
|
||||
def set_metric_tag(self, tag, value):
|
||||
"""Ignored for statsd since it does not support tagging."""
|
||||
|
||||
def set_status(self, status_code, reason=None):
|
||||
# Extended to track status code to avoid referencing the
|
||||
# _status internal variable
|
||||
|
|
28
tests.py
28
tests.py
|
@ -1,6 +1,7 @@
|
|||
import logging
|
||||
import socket
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from tornado import gen, testing, web
|
||||
import mock
|
||||
|
@ -106,6 +107,11 @@ class StatsdMethodTimingTests(testing.AsyncHTTPTestCase):
|
|||
for path, value, stat_type in self.statsd.find_metrics(prefix, 'ms'):
|
||||
assert_between(250.0, float(value), 300.0)
|
||||
|
||||
def test_that_add_metric_tag_is_ignored(self):
|
||||
response = self.fetch('/',
|
||||
headers={'Correlation-ID': 'does not matter'})
|
||||
self.assertEqual(response.code, 204)
|
||||
|
||||
|
||||
class InfluxDbTests(testing.AsyncHTTPTestCase):
|
||||
|
||||
|
@ -140,9 +146,10 @@ class InfluxDbTests(testing.AsyncHTTPTestCase):
|
|||
if key.startswith('my-service,'):
|
||||
tag_dict = dict(a.split('=') for a in key.split(',')[1:])
|
||||
self.assertEqual(tag_dict['handler'],
|
||||
'examples.influxdb.SimpleHandler')
|
||||
self.assertEqual(tag_dict['method'], 'GET')
|
||||
self.assertEqual(tag_dict['host'], socket.gethostname())
|
||||
'"examples.influxdb.SimpleHandler"')
|
||||
self.assertEqual(tag_dict['method'], '"GET"')
|
||||
self.assertEqual(tag_dict['host'],
|
||||
'"{}"'.format(socket.gethostname()))
|
||||
|
||||
value_dict = dict(a.split('=') for a in fields.split(','))
|
||||
assert_between(0.25, float(value_dict['duration']), 0.3)
|
||||
|
@ -189,3 +196,18 @@ class InfluxDbTests(testing.AsyncHTTPTestCase):
|
|||
response = self.fetch('/')
|
||||
self.assertEqual(response.code, 204)
|
||||
self.assertIs(cfg['db_connection'], conn)
|
||||
|
||||
def test_that_metric_tag_is_tracked(self):
|
||||
cid = str(uuid.uuid4())
|
||||
response = self.fetch('/', headers={'Correlation-ID': cid})
|
||||
self.assertEqual(response.code, 204)
|
||||
|
||||
for key, fields, timestamp in self.influx_messages:
|
||||
if key.startswith('my-service,'):
|
||||
tag_dict = dict(a.split('=') for a in key.split(',')[1:])
|
||||
self.assertEqual(tag_dict['correlation_id'],
|
||||
'"{}"'.format(cid))
|
||||
break
|
||||
else:
|
||||
self.fail('Expected to find "request" metric in {!r}'.format(
|
||||
list(self.application.influx_db['requests'])))
|
||||
|
|
Loading…
Reference in a new issue