added a metlog backend for django-statsd (issue #11)
This commit is contained in:
parent
7286074273
commit
34047e50e6
|
@ -1 +1,3 @@
|
|||
*.py[co]
|
||||
build
|
||||
dist
|
||||
|
|
|
@ -2,7 +2,7 @@ language: python
|
|||
python:
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
install: pip install -r requirements.txt --use-mirrors
|
||||
install: pip install -r requirements.txt -r optional.txt --use-mirrors
|
||||
script: nosetests
|
||||
notifications:
|
||||
irc: "irc.mozilla.org#amo-bots"
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
from statsd.client import StatsClient
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class StatsClient(StatsClient):
|
||||
"""A client that pushes messages to metlog """
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
super(StatsClient, self).__init__(*args, **kw)
|
||||
if getattr(settings, 'METLOG', None) is None:
|
||||
raise AttributeError(
|
||||
"Metlog needs to be configured as settings.METLOG")
|
||||
|
||||
self.metlog = settings.METLOG
|
||||
|
||||
def timing(self, stat, delta, rate=1):
|
||||
"""Send new timing information. `delta` is in milliseconds."""
|
||||
self.metlog.timer_send(stat, delta, rate=rate)
|
||||
|
||||
def incr(self, stat, count=1, rate=1):
|
||||
"""Increment a stat by `count`."""
|
||||
self.metlog.incr(stat, count, rate=rate)
|
||||
|
||||
def decr(self, stat, count=1, rate=1):
|
||||
"""Decrement a stat by `count`."""
|
||||
self.metlog.incr(stat, -count, rate=rate)
|
|
@ -1,7 +1,10 @@
|
|||
import json
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from nose.exc import SkipTest
|
||||
from nose import tools as nose_tools
|
||||
|
||||
minimal = {
|
||||
'DATABASES': {
|
||||
|
@ -10,8 +13,9 @@ minimal = {
|
|||
'NAME': 'mydatabase'
|
||||
}
|
||||
},
|
||||
'ROOT_URLCONF':'',
|
||||
'STATSD_CLIENT': 'django_statsd.clients.null'
|
||||
'ROOT_URLCONF': '',
|
||||
'STATSD_CLIENT': 'django_statsd.clients.null',
|
||||
'METLOG': None
|
||||
}
|
||||
|
||||
if not settings.configured:
|
||||
|
@ -45,7 +49,6 @@ cfg = {
|
|||
}
|
||||
|
||||
|
||||
|
||||
@mock.patch.object(middleware.statsd, 'incr')
|
||||
class TestIncr(TestCase):
|
||||
|
||||
|
@ -135,6 +138,129 @@ class TestClient(unittest.TestCase):
|
|||
eq_(client.cache, {'testing|count': [[1, 1]]})
|
||||
|
||||
|
||||
class TestMetlogClient(unittest.TestCase):
|
||||
|
||||
def check_metlog(self):
|
||||
try:
|
||||
from metlog.config import client_from_dict_config
|
||||
return client_from_dict_config
|
||||
except ImportError:
|
||||
raise SkipTest("Metlog is not installed")
|
||||
|
||||
@nose_tools.raises(AttributeError)
|
||||
def test_no_metlog(self):
|
||||
with mock.patch.object(settings, 'STATSD_CLIENT',
|
||||
'django_statsd.clients.moz_metlog'):
|
||||
get_client()
|
||||
|
||||
def test_get_client(self):
|
||||
client_from_dict_config = self.check_metlog()
|
||||
|
||||
METLOG_CONF = {
|
||||
'logger': 'django-statsd',
|
||||
'sender': {
|
||||
'class': 'metlog.senders.DebugCaptureSender',
|
||||
},
|
||||
}
|
||||
|
||||
metlog = client_from_dict_config(METLOG_CONF)
|
||||
with mock.patch.object(settings, 'METLOG', metlog):
|
||||
with mock.patch.object(settings, 'STATSD_CLIENT',
|
||||
'django_statsd.clients.moz_metlog'):
|
||||
|
||||
client = get_client()
|
||||
eq_(client.__module__, 'django_statsd.clients.moz_metlog')
|
||||
|
||||
def test_metlog_incr(self):
|
||||
client_from_dict_config = self.check_metlog()
|
||||
|
||||
# Need to load within the test in case metlog is not installed
|
||||
from metlog.config import client_from_dict_config
|
||||
METLOG_CONF = {
|
||||
'logger': 'django-statsd',
|
||||
'sender': {
|
||||
'class': 'metlog.senders.DebugCaptureSender',
|
||||
},
|
||||
}
|
||||
|
||||
metlog = client_from_dict_config(METLOG_CONF)
|
||||
with mock.patch.object(settings, 'METLOG', metlog):
|
||||
with mock.patch.object(settings, 'STATSD_CLIENT',
|
||||
'django_statsd.clients.moz_metlog'):
|
||||
|
||||
client = get_client()
|
||||
eq_(len(client.metlog.sender.msgs), 0)
|
||||
client.incr('testing')
|
||||
eq_(len(client.metlog.sender.msgs), 1)
|
||||
|
||||
msg = json.loads(client.metlog.sender.msgs[0])
|
||||
eq_(msg['severity'], 6)
|
||||
eq_(msg['payload'], '1')
|
||||
eq_(msg['fields']['rate'], 1)
|
||||
eq_(msg['fields']['name'], 'testing')
|
||||
eq_(msg['type'], 'counter')
|
||||
|
||||
def test_metlog_decr(self):
|
||||
client_from_dict_config = self.check_metlog()
|
||||
|
||||
# Need to load within the test in case metlog is not installed
|
||||
from metlog.config import client_from_dict_config
|
||||
|
||||
METLOG_CONF = {
|
||||
'logger': 'django-statsd',
|
||||
'sender': {
|
||||
'class': 'metlog.senders.DebugCaptureSender',
|
||||
},
|
||||
}
|
||||
|
||||
metlog = client_from_dict_config(METLOG_CONF)
|
||||
with mock.patch.object(settings, 'METLOG', metlog):
|
||||
with mock.patch.object(settings, 'STATSD_CLIENT',
|
||||
'django_statsd.clients.moz_metlog'):
|
||||
|
||||
client = get_client()
|
||||
eq_(len(client.metlog.sender.msgs), 0)
|
||||
client.decr('testing')
|
||||
eq_(len(client.metlog.sender.msgs), 1)
|
||||
|
||||
msg = json.loads(client.metlog.sender.msgs[0])
|
||||
eq_(msg['severity'], 6)
|
||||
eq_(msg['payload'], '-1')
|
||||
eq_(msg['fields']['rate'], 1)
|
||||
eq_(msg['fields']['name'], 'testing')
|
||||
eq_(msg['type'], 'counter')
|
||||
|
||||
def test_metlog_timing(self):
|
||||
client_from_dict_config = self.check_metlog()
|
||||
|
||||
# Need to load within the test in case metlog is not installed
|
||||
from metlog.config import client_from_dict_config
|
||||
|
||||
METLOG_CONF = {
|
||||
'logger': 'django-statsd',
|
||||
'sender': {
|
||||
'class': 'metlog.senders.DebugCaptureSender',
|
||||
},
|
||||
}
|
||||
|
||||
metlog = client_from_dict_config(METLOG_CONF)
|
||||
with mock.patch.object(settings, 'METLOG', metlog):
|
||||
with mock.patch.object(settings, 'STATSD_CLIENT',
|
||||
'django_statsd.clients.moz_metlog'):
|
||||
|
||||
client = get_client()
|
||||
eq_(len(client.metlog.sender.msgs), 0)
|
||||
client.timing('testing', 512, rate=2)
|
||||
eq_(len(client.metlog.sender.msgs), 1)
|
||||
|
||||
msg = json.loads(client.metlog.sender.msgs[0])
|
||||
eq_(msg['severity'], 6)
|
||||
eq_(msg['payload'], '512')
|
||||
eq_(msg['fields']['rate'], 2)
|
||||
eq_(msg['fields']['name'], 'testing')
|
||||
eq_(msg['type'], 'timer')
|
||||
|
||||
|
||||
# This is primarily for Zamboni, which loads in the custom middleware
|
||||
# classes, one of which, breaks posts to our url. Let's stop that.
|
||||
@mock.patch.object(settings, 'MIDDLEWARE_CLASSES', [])
|
||||
|
|
|
@ -73,6 +73,14 @@ First off, pick your client, one of:
|
|||
|
||||
Just writes the values to a log file using Python's logging module.
|
||||
|
||||
- django_statsd.clients.moz_metlog
|
||||
|
||||
Use this to route messages through
|
||||
_metlog: http://github.com/mozilla-services/metlog-py. Note that
|
||||
using metlog will require you to bind the metlog instance to bind
|
||||
the metlog client instance as settings.METLOG.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
metlog-py
|
Loading…
Reference in New Issue