Skip to content

Commit

Permalink
Initial project creation
Browse files Browse the repository at this point in the history
  • Loading branch information
frankwiles committed May 12, 2010
0 parents commit b99c699
Show file tree
Hide file tree
Showing 17 changed files with 274 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS.txt
@@ -0,0 +1 @@
django-app-metrics was originally created by Frank Wiles <frank@revsys.com>
28 changes: 28 additions & 0 deletions LICENSE.txt
@@ -0,0 +1,28 @@
Copyright (c) Frank Wiles and individual contributors.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

3. Neither the name of django-app-metrics nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

24 changes: 24 additions & 0 deletions README.txt
@@ -0,0 +1,24 @@

Settings:
APP_METRIC_BACKEND='app-metrics.backends.db'

Usage:

from app_metrics.utils import create_metric, metric

# Create a new metric to track
create_metric(
name='New User Metric',
slug='new_user_signup',
email_recipients = [user1, user2],
no_email=True)

# Increment the metric by one
metric('new_user_signup')

# Increment the metric by some other number
metric('new_user_signup', 4)

manage.py metrics_aggregate
manage.py metrics_send_mail

1 change: 1 addition & 0 deletions app-metrics/__init__.py
@@ -0,0 +1 @@
VERSION = (0,1,0)
Empty file added app-metrics/admin.py
Empty file.
Empty file.
9 changes: 9 additions & 0 deletions app-metrics/backends/db.py
@@ -0,0 +1,9 @@
from app_metrics import Metric, MetricItem

def metric(slug=None, count=1):
""" Record our metric in the database """
met = Metric.objects.get(slug=slug)

new_metric = MetricItem(metric=met, count=count)
new_metric.save()

Empty file.
Empty file.
11 changes: 11 additions & 0 deletions app-metrics/management/commands/metrics_aggregate.py
@@ -0,0 +1,11 @@
from django.core.management.base import NoArgsCommand

class Command(NoArgsCommand):
help = "Aggregate Application Metrics"

requires_model_validation = True

def handle_noargs(self, **options):
""" Aggregate Application Metrics """
pass

11 changes: 11 additions & 0 deletions app-metrics/management/commands/metrics_send_mail.py
@@ -0,0 +1,11 @@
from django.core.management.base import NoArgsCommand

class Command(NoArgsCommand):
help = "Aggregate Application Metrics"

requires_model_validation = True

def handle_noargs(self, **options):
""" Aggregate Application Metrics """
pass

85 changes: 85 additions & 0 deletions app-metrics/models.py
@@ -0,0 +1,85 @@
import datetime

from django.db import models, IntegrityError
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User

class Metric(models.Model):
""" The type of metric we want to store """
name = models.CharField(max_length=50)
slug = models.SlugField(unique=True, max_length=60)
email_recipients = models.ManyToManyField(User)
no_email = models.BooleanField(default=False)
daily = models.BooleanField(default=True)
weekly = models.BooleanField(default=False)
monthly = models.BooleanField(default=False)

def __unicode__(self):
return self.name

def save(self, *args, **kwargs):
if not self.id and not self.slug:
self.slug = slug = slugify(self.name)
i = 0
while True:
try:
return super(Metric,self).save(*args, **kwargs)
except IntegrityError:
i += 1
self.slug = "%s_%d" % (self, i)
else:
return super(Metric, self).save(*args, **kwargs)

class MetricItem(models.Model):
""" Individual metric items """
metric = models.ForeignKey(Metric)
count = models.IntegerField(default=1)
created = models.DateField(default=datetime.datetime.now)

def __unicode__(self):
return "'%s' of %d on %s" % ( self.metric.name,
self.count,
self.created )

class MetricDay(models.Model):
""" Aggregation of Metrics on a per day basis """
metric = models.ForeignKey(Metric)
count = models.BigIntegerField(default=0)
created = models.DateField(default=datetime.datetime.now)

def __unicode__(self):
return "'%s' for '%s'" % (self.metric.name, self.created)

class MetricWeek(models.Model):
""" Aggregation of Metrics on a weekly basis """
metric = models.ForeignKey(Metric)
count = models.BigIntegerField(default=0)
created = models.DateField(default=datetime.datetime.now)

def __unicode__(self):
return "'%s' for week %d of %d" % (self.metric.name,
self.created.strftime("%m"))

class MetricMonth(models.Model):
""" Aggregation of Metrics on monthly basis """
metric = models.ForeignKey(Metric)
count = models.BigIntegerField(default=0)
created = models.DateField(default=datetime.datetime.now)

def __unicode__(self):
return "'%s' for %s %s" % (self.metric.name,
self.created.strftime("%B"),
self.created.strftime("%Y"))


class MetricYear(models.Model):
""" Aggregation of Metrics on a yearly basis """
metric = models.ForeignKey(Metric)
count = models.BigIntegerField(default=0)
created = models.DateField(default=datetime.datetime.now)

def __unicode__(self):
return "'%s' for month of '%s'" % (self.metric.name,
self.created.strftime("%Y"))


1 change: 1 addition & 0 deletions app-metrics/tests/__init__.py
@@ -0,0 +1 @@
from app_metrics.tests.tests import *
6 changes: 6 additions & 0 deletions app-metrics/tests/settings.py
@@ -0,0 +1,6 @@
DATABASE_ENGINE='sqlite3'

INSTALLED_APPS = [
'app_metrics',
'app_metrics.tests',
]
28 changes: 28 additions & 0 deletions app-metrics/tests/tests.py
@@ -0,0 +1,28 @@
from django.test import TestCase

from django.contrib.auth.models import User

from app_metrics.models import Metric, MetricItem, MetricDay, MetricWeek, MetricMonth, MetricYear
from app_metrics.utils import metric, create_metric

class MetricCreationTests(TestCase):

def setUp(self):
self.user1 = User.objects.create_user('user1', 'user1@example.com', 'user1pass')
self.user2 = User.objects.create_user('user2', 'user2@example.com', 'user2pass')

def test_metric(self):

new_metric = create_metric(name='Test Metric Class',
slug='test_metric'
email_recipients=[self.user1, self.user2])

metric('test_metric')
metric('test_metric')
metric('test_metric')

current_count = MetricItem.objects.filter(metric=new_metric)
self.assertEqual(len(current_count), 3)
self.assertEqual(current_count[0].count, 1)
self.assertEqual(current_count[1].count, 1)
self.assertEqual(current_count[2].count, 1)
39 changes: 39 additions & 0 deletions app-metrics/utils.py
@@ -0,0 +1,39 @@
from django.conf import settings

from app_metrics.models import Metric, MetricItem

def create_metric(name=None, slug=None, email_recipients=None, no_email=None, daily=True, weekly=False, monthly=False):
""" Create a new type of metric to track """
try:
new_metric = Metric(
name=name,
slug=slug,
email_recipients=email_recipients,
no_email=no_email,
daily=daily,
weekly=weekly,
monthly=monthly)
new_metric.save()
except:
return False

return new_metric

class InvalidMetricsBackend(Exception): pass
class MetricError(Exception): pass

def metric(slug=None, count=1):
""" Increment a metric """

# Attempt to import the backend
try:
backend_string = settings.get('APP_METRICS_BACKEND', 'app_metrics.backends.db')
backend = __import__(backend_string)

except:
raise InvalidMetricsBackend("Could not load '%s' as a backend" % backend_string )

try:
backend.metric(slug, count)
except:
raise MetricError('Unable to capture metric')
30 changes: 30 additions & 0 deletions setup.py
@@ -0,0 +1,30 @@
import os
from setuptools import setup, find_packages

from app-metrics import VERSION


f = open(os.path.join(os.path.dirname(__file__), 'README.txt'))
readme = f.read()
f.close()

setup(
name='django-app-metrics',
version=".".join(map(str, VERSION)),
description='django-app-metrics is a reusable Django application for tracking and emailing application metrics.',
long_description=readme,
author='Frank Wiles',
author_email='frank@revsys.com',
url='http://github.com/frankwiles/django-app-metrics/tree/master',
packages=find_packages(),
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Framework :: Django',
],
)

0 comments on commit b99c699

Please sign in to comment.