Skip to content

Commit

Permalink
initiali import
Browse files Browse the repository at this point in the history
  • Loading branch information
wolph committed Jul 11, 2011
0 parents commit 2a6ec64
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 0 deletions.
42 changes: 42 additions & 0 deletions README.rst
@@ -0,0 +1,42 @@
Introduction
============

`django_statsd` is a middleware that uses `python-statsd` to log query
and view durations to statsd.

* Python Statsd
- https://github.com/WoLpH/python-statsd
* Graphite
- http://graphite.wikidot.com
* Statsd
- code: https://github.com/etsy/statsd
- blog post: http://codeascraft.etsy.com/2011/02/15/measure-anything-measure-everything/


Install
=======

To install simply execute `python setup.py install`.
If you want to run the tests first, run `python setup.py nosetests`


Usage
=====

Just add `django_statsd` to the `installed_apps` and add
`django_statsd.middleware.TimingMiddleware` to `MIDDLEWARE_CLASSES`


Advanced Usage
--------------

>>> def some_view(request):
... with request.timings('something_to_time'):
... # do something here
... pass
>>>
>>> def some_view(request):
... request.timings.start('something_to_time')
... # do something here
... request.timings.stop('something_to_time')

Empty file added django_statsd/__init__.py
Empty file.
81 changes: 81 additions & 0 deletions django_statsd/middleware.py
@@ -0,0 +1,81 @@
from __future__ import with_statement
import time
from django_statsd import utils
import logging
import threading
logger = logging.getLogger(__name__)

class WithTimer(object):
def __init__(self, timer, key):
self.timer = timer
self.key = key

def __enter__(self):
self.timer.start(self.key)

def __exit__(self, type_, value, traceback):
self.timer.stop(self.key)


class Timer(object):
def __init__(self):
self.starts = {}
self.totals = {}

def start(self, key):
assert key not in self.starts, 'Already started tracking %s' % key
self.starts[key] = time.time()

def stop(self, key):
assert (
key in self.starts,
'Unable to stop tracking %s, never started tracking it' % key,
)

delta = time.time() - self.starts.pop(key)
self.totals[key] = self.totals.get(key, 0.0) + delta
return delta

def submit(self, request_method, view_name):
prefix = 'view.%s.%s' % (request_method, view_name)

timer = utils.get_timer(prefix)

for k in self.totals.keys():
timer.send(k, self.totals.pop(k))

def __call__(self, key):
return WithTimer(self, key)


class TimingMiddleware(object):
scope = threading.local()

def process_request(self, request):
# store the timings in the request so it can be used everywhere
request.timings = Timer()
request.timings.start('total')
self.scope = request
self.view_name = None

def process_view(self, request, view_func, view_args, view_kwargs):
# View name is defined as module.view
# (e.g. django.contrib.auth.views.login)
self.view_name = view_func.__module__ + '.' + view_func.__name__

# Time the response
with request.timings('view'):
response = view_func(request, *view_args, **view_kwargs)

return response

def process_response(self, request, response):
request.timings.stop('total')
if self.view_name:
request.timings.submit(
request.method.lower(),
self.view_name,
)

return response

2 changes: 2 additions & 0 deletions django_statsd/models.py
@@ -0,0 +1,2 @@
from django_statsd import utils

27 changes: 27 additions & 0 deletions django_statsd/utils.py
@@ -0,0 +1,27 @@
import statsd
from django.conf import settings

def get_connection(host=None, port=None, sample_rate=None):
if not host:
host = getattr(settings, 'STATSD_HOST', '127.0.0.1')

if not port:
port = getattr(settings, 'STATSD_PORT', 8125)

if not sample_rate:
sample_rate = getattr(settings, 'STATSD_SAMPLE_RATE', 1.0)

return statsd.Connection(host, port, sample_rate)

def get_timer(name, connection=None):
if not connection:
connection = get_connection()

return statsd.Timer(name, connection)

def get_client(name, connection=None):
if not connection:
connection = get_connection()

return statsd.Client(name, connection)

5 changes: 5 additions & 0 deletions setup.cfg
@@ -0,0 +1,5 @@
[nosetests]
verbosity=3
with-doctest=1
detailed-errors=1

23 changes: 23 additions & 0 deletions setup.py
@@ -0,0 +1,23 @@
import os
from setuptools import setup

def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()

setup(
name = 'django-statsd',
version = '1.0',
author = 'Rick van Hattem',
author_email = 'Rick.van.Hattem@Fawo.nl',
description = '''django-statsd is a django app that submits query and
view durations to Etsy's statsd.''',
url='https://github.com/WoLpH/django-statsd',
license = 'BSD',
packages=['django_statsd'],
long_description=read('README.rst'),
test_suite='nose.collector',
setup_requires=['nose'],
classifiers=[
'License :: OSI Approved :: BSD License',
],
)

0 comments on commit 2a6ec64

Please sign in to comment.