Skip to content

Commit

Permalink
Moved all Sentry CLI operations into new Sentry namespace. You can no…
Browse files Browse the repository at this point in the history
…w launch a standalone Sentry webserver using 'sentry start'
  • Loading branch information
dcramer committed May 7, 2011
1 parent d59b495 commit 1c73f8b
Show file tree
Hide file tree
Showing 23 changed files with 356 additions and 156 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -10,4 +10,5 @@ pip-log.txt
/docs/doctrees
sentry/sentry_index/
*.egg
sentry_index/
sentry_index/
*.db
4 changes: 2 additions & 2 deletions sentry/client/base.py
Expand Up @@ -16,15 +16,15 @@

import sentry
from sentry import conf
from sentry.helpers import construct_checksum, varmap, transform, get_installed_apps, force_unicode, \
from sentry.utils import construct_checksum, varmap, transform, get_installed_apps, force_unicode, \
get_versions, shorten, get_signature, get_auth_header

logger = logging.getLogger('sentry.errors')

class SentryClient(object):
def process(self, **kwargs):
"Processes the message before passing it on to the server"
from sentry.helpers import get_filters
from sentry.utils import get_filters

if kwargs.get('data'):
# Ensure we're not changing the original data which was passed
Expand Down
File renamed without changes.
28 changes: 0 additions & 28 deletions sentry/management/commands/cleanup_sentry.py

This file was deleted.

21 changes: 11 additions & 10 deletions sentry/models.py
Expand Up @@ -17,9 +17,9 @@
from django.utils.translation import ugettext_lazy as _

from sentry import conf
from sentry.helpers import cached_property, construct_checksum, transform, get_filters
from sentry.manager import GroupedMessageManager, SentryManager
from sentry.reporter import FakeRequest
from sentry.utils import cached_property, construct_checksum, transform, get_filters, \
MockDjangoRequest
from sentry.utils.manager import GroupedMessageManager, SentryManager

from indexer.models import BaseIndex

Expand Down Expand Up @@ -248,13 +248,14 @@ def full_url(self):

@cached_property
def request(self):
fake_request = FakeRequest()
fake_request.META = self.data.get('META') or {}
fake_request.GET = self.data.get('GET') or {}
fake_request.POST = self.data.get('POST') or {}
fake_request.FILES = self.data.get('FILES') or {}
fake_request.COOKIES = self.data.get('COOKIES') or {}
fake_request.url = self.url
fake_request = MockDjangoRequest(
META = self.data.get('META') or {},
GET = self.data.get('GET') or {},
POST = self.data.get('POST') or {},
FILES = self.data.get('FILES') or {},
COOKIES = self.data.get('COOKIES') or {},
url = self.url,
)
if self.url:
fake_request.path_info = '/' + self.url.split('/', 3)[-1]
else:
Expand Down
17 changes: 3 additions & 14 deletions sentry/routers.py
@@ -1,16 +1,5 @@
from sentry import conf
import warnings

class SentryRouter(object):
def db_for_write(self, model, **hints):
if model._meta.app_label == 'sentry':
return conf.DATABASE_USING
warnings.warn("The use of 'sentry.routers' is deprecated. Please use 'sentry.utils.router' instead.", DeprecationWarning)

def db_for_read(self, model, **hints):
return self.db_for_write(model, **hints)

def allow_syncdb(self, db, model):
sentry_db = conf.DATABASE_USING
if not sentry_db:
return None
if model._meta.app_label == 'sentry' and db != sentry_db:
return False
from sentry.utils.router import *
99 changes: 88 additions & 11 deletions sentry/scripts/runner.py
@@ -1,8 +1,48 @@
#!/usr/bin/env python
import eventlet
import os
import sys

from daemon.daemon import DaemonContext
from daemon.runner import DaemonRunner, make_pidlockfile
from django.conf import settings
from django.core.management import call_command
from eventlet import wsgi
from optparse import OptionParser
from sentry import VERSION
from sentry.wsgi import application

import sys
class SentryServer(DaemonRunner):
pidfile_timeout = 10
start_message = u"started with pid %(pid)d"

def __init__(self, host='localhost', port=9000, pidfile='/var/run/sentry.pid',
logfile='/var/log/sentry/sentry.log'):

self.daemon_context = DaemonContext()
self.daemon_context.stdout = open(logfile, 'w+')
self.daemon_context.stderr = open(logfile, 'w+', buffering=0)

self.pidfile = None
if pidfile is not None:
self.pidfile = make_pidlockfile(
pidfile, self.pidfile_timeout)

self.daemon_context.pidfile = self.pidfile

self.host = host
self.port = port

# HACK: set app to self so self.app.run() works
self.app = self

def execute(self, action):
self.action = action
self.do_action()

def run(self):
upgrade()
wsgi.server(eventlet.listen((self.host, self.port)), application)

def cleanup(days=30, logger=None, site=None, server=None):
from sentry.models import GroupedMessage, Message
Expand All @@ -27,21 +67,36 @@ def cleanup(days=30, logger=None, site=None, server=None):
qs.filter(logger=logger)
qs.delete()

def upgrade():
from sentry import conf

call_command('syncdb', database=conf.DATABASE_USING or 'default', interactive=False)

if 'south' in settings.INSTALLED_APPS:
call_command('migrate', database=conf.DATABASE_USING or 'default', interactive=False)

def main():
command_list = ('start', 'stop', 'cleanup', 'upgrade')
args = sys.argv
if len(args) < 2 or args[1] not in ('start', 'stop', 'cleanup'):
if len(args) < 2 or args[1] not in command_list:
print "usage: sentry [command] [options]"
print
print "Available subcommands:"
print " start"
print " stop"
print " cleanup"
for cmd in command_list:
print " ", cmd
sys.exit(1)

parser = OptionParser(version="%%prog %s" % VERSION)
parser.add_option('--config', default='/etc/sentry.conf', metavar='CONFIG')
parser.add_option('--config', metavar='CONFIG')
if args[1] == 'start':
parser.add_option('--host', default='0.0.0.0:8000', metavar='HOST')
parser.add_option('--host', default='localhost', metavar='HOSTNAME')
parser.add_option('--port', type=int, default=9000, metavar='PORT')
parser.add_option('--daemon', action='store_true', default=False, dest='daemonize')
parser.add_option('--pidfile', default='/var/run/sentry.pid', dest='pidfile')
parser.add_option('--logfile', default='/var/log/sentry.log', dest='logfile')
elif args[1] == 'stop':
parser.add_option('--pidfile', default='/var/run/sentry.pid', dest='pidfile')
parser.add_option('--logfile', default='/var/log/sentry.log', dest='logfile')
elif args[1] == 'cleanup':
parser.add_option('--days', default='30',
help='Numbers of days to truncate on.')
Expand All @@ -53,10 +108,32 @@ def main():
help='Limit truncation to only entries from server.')

(options, args) = parser.parse_args()
if args[0] == "start":
pass
elif args[0] == "stop":
pass

if options.config:
os.environ['DJANGO_SETTINGS_MODULE'] = options.config

if not settings.configured:
os.environ['DJANGO_SETTINGS_MODULE'] = 'sentry.utils.conf.default_settings'

if args[0] == 'upgrade':
upgrade()

elif args[0] == 'start':
if not options.pidfile:
sys.exit('You must specify --pidfile')

app = SentryServer(host=options.host, port=options.port,
pidfile=options.pidfile, logfile=options.logfile)
app.execute(args[0])


elif args[0] in ('stop', 'restart'):
if not options.pidfile:
sys.exit('You must specify --pidfile')

app = SentryServer(pidfile=options.pidfile, logfile=options.logfile)
app.execute(args[0])

elif args[0] == 'cleanup':
cleanup(days=options.days, logger=options.logger, site=options.site, server=options.server)

Expand Down
2 changes: 1 addition & 1 deletion sentry/search_indexes.py
Expand Up @@ -3,7 +3,7 @@
from haystack.sites import SearchSite

from sentry import conf
from sentry.helpers import to_unicode
from sentry.utils import to_unicode
from sentry.models import GroupedMessage

if conf.SEARCH_ENGINE:
Expand Down
2 changes: 1 addition & 1 deletion sentry/templatetags/sentry_helpers.py
Expand Up @@ -8,7 +8,7 @@
from django.template.defaultfilters import stringfilter
from django.template.loader import render_to_string
from paging.helpers import paginate as paginate_func
from sentry.helpers import get_db_engine
from sentry.utils import get_db_engine
from sentry.plugins import GroupActionProvider
from templatetag_sugar.register import tag
from templatetag_sugar.parser import Name, Variable, Constant, Optional
Expand Down
31 changes: 16 additions & 15 deletions sentry/tests/tests.py
Expand Up @@ -28,7 +28,7 @@
from django.utils.encoding import smart_unicode

from sentry import conf
from sentry.helpers import transform, get_signature, get_auth_header
from sentry.utils import transform, get_signature, get_auth_header
from sentry.models import Message, GroupedMessage
from sentry.client.base import SentryClient
from sentry.client.handlers import SentryHandler
Expand Down Expand Up @@ -683,10 +683,11 @@ def testResponseErrorIdMiddleware(self):
settings.MIDDLEWARE_CLASSES = existing

def testExtraStorage(self):
from sentry.reporter import FakeRequest
from sentry.utils import MockDjangoRequest

request = FakeRequest()
request.META['foo'] = 'bar'
request = MockDjangoRequest(
META = {'foo': 'bar'},
)

logger = logging.getLogger()

Expand All @@ -711,10 +712,11 @@ def testExtraStorage(self):
self.assertEquals(last.data['baz'], 'bar')

def testRawPostData(self):
from sentry.reporter import FakeRequest
from sentry.utils import MockDjangoRequest

request = FakeRequest()
request.raw_post_data = '{"json": "string"}'
request = MockDjangoRequest(
raw_post_data = '{"json": "string"}',
)

logger = logging.getLogger()

Expand Down Expand Up @@ -1107,7 +1109,7 @@ def test_url_prefix(self):

class SentryHelpersTest(TestCase):
def test_get_db_engine(self):
from sentry.helpers import get_db_engine
from sentry.utils import get_db_engine
_databases = getattr(settings, 'DATABASES', {}).copy()
_engine = settings.DATABASE_ENGINE

Expand All @@ -1128,7 +1130,7 @@ def test_get_db_engine(self):
settings.DATABASE_ENGINE = _engine

def test_transform_handles_gettext_lazy(self):
from sentry.helpers import transform
from sentry.utils import transform
from django.utils.functional import lazy

def fake_gettext(to_translate):
Expand All @@ -1141,7 +1143,7 @@ def fake_gettext(to_translate):

def test_get_versions(self):
import sentry
from sentry.helpers import get_versions
from sentry.utils import get_versions
versions = get_versions(['sentry'])
self.assertEquals(versions.get('sentry'), sentry.VERSION)
versions = get_versions(['sentry.client'])
Expand Down Expand Up @@ -1229,16 +1231,15 @@ def test_celery_client(self):
#
# conf.CLIENT = 'sentry.client.base.SentryClient'

class SentryManageTest(TestCase):
class SentryCommandTest(TestCase):
fixtures = ['sentry/tests/fixtures/cleanup.json']

def test_cleanup_sentry(self):
from sentry.management.commands.cleanup_sentry import Command
def test_cleanup(self):
from sentry.scripts.runner import cleanup

self.assertEquals(Message.objects.count(), 10)

command = Command()
command.handle(days=1)
cleanup(days=1)

self.assertEquals(Message.objects.count(), 0)

Expand Down
39 changes: 3 additions & 36 deletions sentry/urls.py
@@ -1,38 +1,5 @@
import os
import re
import warnings

from django.conf.urls.defaults import *
warnings.warn("The use of 'sentry.urls' is deprecated. Please use 'sentry.web.urls' instead.", DeprecationWarning)

from sentry.conf import KEY
from sentry import views
from sentry.feeds import MessageFeed, SummaryFeed

SENTRY_ROOT = os.path.dirname(__file__)

urlpatterns = patterns('',
# This path is also reflected in conf.STATIC_URL_PREFIX
url(r'^_static/(?P<path>.*)$', views.static_media, name='sentry-media'),

# Feeds

url(r'^feeds/%s/messages.xml$' % re.escape(KEY), MessageFeed(), name='sentry-feed-messages'),
url(r'^feeds/%s/summaries.xml$' % re.escape(KEY), SummaryFeed(), name='sentry-feed-summaries'),

# JS and API

url(r'^jsapi/$', views.ajax_handler, name='sentry-ajax'),
url(r'^store/$', views.store, name='sentry-store'),

# Normal views

url(r'^login$', views.login, name='sentry-login'),
url(r'^logout$', views.logout, name='sentry-logout'),
url(r'^group/(\d+)$', views.group, name='sentry-group'),
url(r'^group/(\d+)/messages$', views.group_message_list, name='sentry-group-messages'),
url(r'^group/(\d+)/messages/(\d+)$', views.group_message_details, name='sentry-group-message'),
url(r'^group/(\d+)/actions/([\w_-]+)', views.group_plugin_action, name='sentry-group-plugin-action'),

url(r'^search$', views.search, name='sentry-search'),

url(r'^$', views.index, name='sentry'),
)
from sentry.web.urls import *

0 comments on commit 1c73f8b

Please sign in to comment.