Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add django-memcached monitoring tool

  • Loading branch information...
commit 4851d564cfcd43272be7580930bdc41709beeebf 1 parent c258a4e
@bobsilverberg bobsilverberg authored
View
4 oneanddone/settings/base.py
@@ -39,6 +39,7 @@
'commonware.response.cookies',
'django_ace',
'django_browserid',
+ 'django_memcached',
'django_nose',
'funfactory',
'jingo_minify',
@@ -94,6 +95,7 @@
'admin',
'registration',
'browserid',
+ 'memcached',
]
# Accepted locales
@@ -191,6 +193,8 @@ def _request_args():
# CacheMachine config
CACHE_COUNT_TIMEOUT = 60 # seconds, not too long.
+DJANGO_MEMCACHED_REQUIRE_STAFF = True
+
# Project-specific Settings
##############################################################################
# Whitelisted tags allowed to be used in task instructions.
View
2  oneanddone/urls.py
@@ -40,6 +40,8 @@ def handler404(request):
(r'^browserid/', include('django_browserid.urls')),
+ (r'^cache/', include('django_memcached.urls')),
+
# Generate robots.txt
(r'^robots\.txt$',
lambda r: HttpResponse(
View
0  vendor-local/lib/python/django_memcached/__init__.py
No changes.
View
1  vendor-local/lib/python/django_memcached/models.py
@@ -0,0 +1 @@
+# None :)
View
51 vendor-local/lib/python/django_memcached/templates/memcached/server_list.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="" >
+ <head>
+ <title>Server List</title>
+ <style>
+ body { font: large sans-serif; background-color: #EEE; margin: 0; padding: 0; }
+ h1 { margin: 0px; padding: 10px; text-align: center; border-bottom: 1px solid #DDD; background-color: #FFC; }
+ table { width: 100%; border-collapse: collapse; }
+ table thead { background-color: #5B80B2; color: white; border-bottom: 1px solid #DDD; }
+ table td,table th { padding: 4px 0px 4px 0px; }
+ table tbody tr { border-bottom: 1px solid #DDD; }
+ table tbody tr.even { background-color: #F6F6F6; }
+ table th { font-size: 18px; }
+ table td { text-align: center; }
+ a { text-decoration: none; color: #7CA0C7; }
+ </style>
+ </head>
+ <body>
+ <h1>Memcached Server Stats</h1>
+ <table>
+ <thead>
+ <tr>
+ <th>Server</th>
+ <th>Keys</th>
+ <th>Hits</th>
+ <th>Gets</th>
+ <th>Hit Rate</th>
+ <th>Traffic In</th>
+ <th>Traffic Out</th>
+ <th>Usage</th>
+ <th>Uptime</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for i,server,stats in statuses %}
+ <tr class="{% cycle even,odd %}">
+ <td><a href="{% url django_memcached.views.server_status i %}">{{ server }}</a></td>
+ <td>{{ stats.curr_items }}</td>
+ <td>{{ stats.get_hits }}</td>
+ <td>{{ stats.cmd_get }}</td>
+ <td>{{ stats.hit_rate }}%</td>
+ <td>{{ stats.bytes_read|filesizeformat }}</td>
+ <td>{{ stats.bytes_written|filesizeformat }}</td>
+ <td>{{ stats.bytes|filesizeformat }}</td>
+ <td>{{ stats.uptime }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </body>
+</html>
View
36 vendor-local/lib/python/django_memcached/templates/memcached/server_status.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="" >
+ <head>
+ <title>Memcached Stats for {{ server }}</title>
+ <style>
+ body { font: large sans-serif; background-color: #EEE; margin: 0; padding: 0; }
+ h1 { margin: 0px; padding: 10px; text-align: center; border-bottom: 1px solid #DDD; background-color: #FFC; }
+ #tablecontainer { text-align: center; }
+ table { width: 50%; margin-left: auto; margin-right: auto; border-collapse: collapse; border-left: 1px solid #DDD; border-right: 1px solid #DDD; }
+ table thead { background-color: #7CA0C7; color: white; border-bottom: 1px solid #DDD; }
+ table td,table th { padding: 4px 0px 4px 0px; }
+ table tbody tr { border-bottom: 1px solid #DDD; }
+ table tbody tr.even { background-color: #F6F6F6; }
+ table th { font-size: 18px; }
+ table td { text-align: center; }
+ a { text-decoration: none; color: #5B80B2; }
+ a#back { display: block; background-color: #5B80B2; color: white; width: 100%; padding: 10px; border-bottom: 1px solid #DDD; }
+ </style>
+ </head>
+ <body>
+ <h1>Memcached Stats for {{ server }}</h1>
+ <a id="back" href="{% url django_memcached.views.server_list %}">&larr; Back to List</a>
+ <div id="tablecontainer">
+ <table>
+ <tbody>
+ {% for key,value in stats %}
+ <tr class="{% cycle even,odd %}">
+ <th>{{ key|title }}</th>
+ <td>{{ value }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </body>
+</html>
View
6 vendor-local/lib/python/django_memcached/urls.py
@@ -0,0 +1,6 @@
+from django.conf.urls import *
+
+urlpatterns = patterns('',
+ (r'^$', 'django_memcached.views.server_list'),
+ (r'^(\d+)/$', 'django_memcached.views.server_status'),
+)
View
41 vendor-local/lib/python/django_memcached/util.py
@@ -0,0 +1,41 @@
+import datetime
+
+try:
+ import memcache
+ memcache_installed = True
+except ImportError:
+ memcache_installed = False
+
+def get_memcached_stats(server):
+ if not memcache_installed:
+ return {}
+ host = memcache._Host(server)
+ host.connect()
+ host.send_cmd("stats")
+
+ stats = {}
+
+ while True:
+ try:
+ stat, key, value = host.readline().split(None, 2)
+ except ValueError:
+ break
+ try:
+ # Convert to native type, if possible
+ value = int(value)
+ if key == "uptime":
+ value = datetime.timedelta(seconds=value)
+ elif key == "time":
+ value = datetime.datetime.fromtimestamp(value)
+ except ValueError:
+ pass
+ stats[key] = value
+
+ host.close_socket()
+
+ try:
+ stats['hit_rate'] = 100 * stats['get_hits'] / stats['cmd_get']
+ except ZeroDivisionError:
+ stats['hit_rate'] = stats['get_hits']
+
+ return stats
View
84 vendor-local/lib/python/django_memcached/views.py
@@ -0,0 +1,84 @@
+from django.http import Http404
+from django.shortcuts import render_to_response
+from django.conf import settings
+from django.template import RequestContext
+from django.core.exceptions import ImproperlyConfigured
+from django.views.decorators.cache import never_cache
+
+from django_memcached.util import get_memcached_stats
+from django.contrib.auth.decorators import user_passes_test
+
+def get_cache_server_list():
+ """Returns configured memcached servers.
+
+ Works with both old-style (CACHE_BACKEND) and new-style (CACHES)
+ cache configurations.
+
+ """
+ engine = ''
+
+ # Django >= 1.3
+ #
+ # If somebody uses CACHE_BACKEND instead of CACHES in 1.3, it
+ # automatically converts their CACHE_BACKEND configuration to the
+ # appropriate CACHES configuration. So we can safely use
+ # parse_backend_conf here and it'll work with both old and new styles.
+ try:
+ from django.core.cache import parse_backend_conf, DEFAULT_CACHE_ALIAS
+ engine, hosts, params = parse_backend_conf(DEFAULT_CACHE_ALIAS)
+
+ # Django < 1.3
+ #
+ # No parse_backend_conf and DEFAULT_CACHE_ALIAS.
+ except ImportError:
+ from django.core.cache import parse_backend_uri
+ engine, hosts, params = parse_backend_uri(settings.CACHE_BACKEND)
+
+ if 'memcached' not in engine:
+ raise ImproperlyConfigured("django-memcached2 only works with memcached. Currently using '%s'" % engine)
+
+ return hosts if isinstance(hosts, list) else hosts.split(';')
+
+@never_cache
+def server_list(request):
+ servers = get_cache_server_list()
+ statuses = []
+ for idx, server in enumerate(servers):
+ statuses.append((idx, server, get_memcached_stats(server)))
+
+ context = {
+ 'statuses': statuses,
+ }
+ return render_to_response(
+ 'memcached/server_list.html',
+ context,
+ context_instance=RequestContext(request)
+ )
+
+@never_cache
+def server_status(request, index):
+ servers = get_cache_server_list()
+ try:
+ index = int(index)
+ except ValueError:
+ raise Http404
+ try:
+ server = servers[index]
+ except IndexError:
+ raise Http404
+ stats = get_memcached_stats(server)
+ if not stats:
+ raise Http404
+ context = {
+ 'server': server,
+ 'stats': stats.items(),
+ }
+ return render_to_response(
+ 'memcached/server_status.html',
+ context,
+ context_instance=RequestContext(request)
+ )
+
+if getattr(settings, 'DJANGO_MEMCACHED_REQUIRE_STAFF', False):
+ server_list = user_passes_test(lambda u: u.is_staff)(server_list)
+ server_status = user_passes_test(lambda u: u.is_staff)(server_status)
View
66 vendor-local/lib/python/django_memcached2-0.2-py2.7.egg-info/PKG-INFO
@@ -0,0 +1,66 @@
+Metadata-Version: 1.0
+Name: django-memcached2
+Version: 0.2
+Summary:
+django-memcached2 displays statistics about your currently running
+memcached instances. It's a fork of django-memcached that works with
+the new-style CACHES setting introduced in Django 1.3.
+
+Home-page: http://github.com/edavis/django-memcached
+Author: Eric Davis
+Author-email: ed@npri.org
+License: BSD
+Description: django-memcached2
+ =================
+
+ django-memcached2 is a lightweight, resuable Django app that displays
+ statistics about your currently running memcached instances.
+
+ It is a fork of Eric Florenzano's django-memcached_ that works with the
+ CACHES settings introduced in Django 1.3.
+
+ .. _django-memcached: https://github.com/ericflo/django-memcached
+
+ Installing django-memcached2
+ ----------------------------
+
+ 1. Either download the tarball and run ``python setup.py install``, or simply
+ use easy_install or pip like so ``easy_install django-memcached2``.
+
+
+ 2. Add django_memcached to your ``INSTALLED_APPS`` setting::
+
+ INSTALLED_APPS = (
+ # ...
+ 'django_memcached',
+ )
+
+
+ 3. Add the urls to your url configuration::
+
+ urlpatterns = patterns('',
+ # ...
+ (r'^cache/', include('django_memcached.urls')),
+ )
+
+
+ 4. If you want to restrict these urls to only staff members, just add this
+ setting to your settings file::
+
+ DJANGO_MEMCACHED_REQUIRE_STAFF = True
+
+
+ That's it. Hopefully this app gives you a little insight into how your
+ memcached servers are being utilized.
+
+Keywords: memcached,django,caching,caches
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Environment :: Web Environment
+Classifier: Framework :: Django
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: System Administrators
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Programming Language :: Python
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: System :: Monitoring
View
18 vendor-local/lib/python/django_memcached2-0.2-py2.7.egg-info/SOURCES.txt
@@ -0,0 +1,18 @@
+.gitignore
+LICENSE.txt
+README.rst
+setup.cfg
+setup.py
+django_memcached/__init__.py
+django_memcached/models.py
+django_memcached/urls.py
+django_memcached/util.py
+django_memcached/views.py
+django_memcached/templates/memcached/server_list.html
+django_memcached/templates/memcached/server_status.html
+django_memcached2.egg-info/PKG-INFO
+django_memcached2.egg-info/SOURCES.txt
+django_memcached2.egg-info/dependency_links.txt
+django_memcached2.egg-info/not-zip-safe
+django_memcached2.egg-info/requires.txt
+django_memcached2.egg-info/top_level.txt
View
1  vendor-local/lib/python/django_memcached2-0.2-py2.7.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
View
19 vendor-local/lib/python/django_memcached2-0.2-py2.7.egg-info/installed-files.txt
@@ -0,0 +1,19 @@
+../django_memcached/__init__.py
+../django_memcached/models.py
+../django_memcached/urls.py
+../django_memcached/util.py
+../django_memcached/views.py
+../django_memcached/templates/memcached/server_list.html
+../django_memcached/templates/memcached/server_status.html
+../django_memcached/__init__.pyc
+../django_memcached/models.pyc
+../django_memcached/urls.pyc
+../django_memcached/util.pyc
+../django_memcached/views.pyc
+./
+dependency_links.txt
+not-zip-safe
+PKG-INFO
+requires.txt
+SOURCES.txt
+top_level.txt
View
1  vendor-local/lib/python/django_memcached2-0.2-py2.7.egg-info/not-zip-safe
@@ -0,0 +1 @@
+
View
1  vendor-local/lib/python/django_memcached2-0.2-py2.7.egg-info/requires.txt
@@ -0,0 +1 @@
+setuptools
View
1  vendor-local/lib/python/django_memcached2-0.2-py2.7.egg-info/top_level.txt
@@ -0,0 +1 @@
+django_memcached
Please sign in to comment.
Something went wrong with that request. Please try again.