Updated raven plugin

- Added wrap_wsgi, celery_setup, celery_logging_setup hooks
- Updated raven plugin docs
- Updated production considerations docs
- Added raven logging setup
This commit is contained in:
Joar Wandborg 2013-03-03 02:32:03 +01:00
parent 40ef3f5e05
commit f3f530286f
8 changed files with 71 additions and 56 deletions

View File

@ -1 +1,2 @@
.. _raven-setup: Set up the raven plugin
.. include:: ../../../mediagoblin/plugins/raven/README.rst .. include:: ../../../mediagoblin/plugins/raven/README.rst

View File

@ -77,51 +77,16 @@ Modify your existing MediaGoblin and application init scripts, if
necessary, to prevent them from starting their own ``celeryd`` necessary, to prevent them from starting their own ``celeryd``
processes. processes.
Monitor exceptions .. _sentry:
------------------
This is an example config using raven_ to report exceptions and Set up sentry to monitor exceptions
:py:mod:`logging` messages to a sentry_ instance -----------------------------------
.. _raven: http://raven.readthedocs.org/ We have a plugin for `raven`_ integration, see the ":doc:`/plugindocs/raven`"
.. _sentry: https://github.com/getsentry documentation.
.. code-block:: ini .. _`raven`: http://raven.readthedocs.org
[pipeline:main]
pipeline =
errors
raven
routing
[loggers]
keys = root, sentry
[handlers]
keys = console, sentry
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console, sentry
[logger_sentry]
level = WARN
handlers = console
qualname = sentry.errors
propagate = 0
[handler_sentry]
class = raven.handlers.logging.SentryHandler
args = ('http://public:secret@example.com/1',)
level = WARNING
formatter = generic
[filter:raven]
use = egg:raven#raven
dsn = http://71727ea2c69043e4bbcd793bb0115cd4:e9cedccb32d9482d81f99eeca8b1ad30@sentry.talka.tv/3
.. _init-script: .. _init-script:

View File

@ -253,4 +253,7 @@ def paste_app_factory(global_config, **app_config):
mgoblin_app = MediaGoblinApp(mediagoblin_config) mgoblin_app = MediaGoblinApp(mediagoblin_config)
for callable_hook in PluginManager().get_hook_callables('wrap_wsgi'):
mgoblin_app = callable_hook(mgoblin_app)
return mgoblin_app return mgoblin_app

View File

@ -18,6 +18,7 @@ import os
import sys import sys
from celery import Celery from celery import Celery
from mediagoblin.tools.pluginapi import PluginManager
MANDATORY_CELERY_IMPORTS = ['mediagoblin.processing.task'] MANDATORY_CELERY_IMPORTS = ['mediagoblin.processing.task']
@ -65,6 +66,9 @@ def setup_celery_app(app_config, global_config,
celery_app = Celery() celery_app = Celery()
celery_app.config_from_object(celery_settings) celery_app.config_from_object(celery_settings)
for callable_hook in PluginManager().get_hook_callables('celery_setup'):
callable_hook(celery_app)
def setup_celery_from_config(app_config, global_config, def setup_celery_from_config(app_config, global_config,
settings_module=DEFAULT_SETTINGS_MODULE, settings_module=DEFAULT_SETTINGS_MODULE,

View File

@ -22,6 +22,7 @@ from celery.signals import setup_logging
from mediagoblin import app, mg_globals from mediagoblin import app, mg_globals
from mediagoblin.init.celery import setup_celery_from_config from mediagoblin.init.celery import setup_celery_from_config
from mediagoblin.tools.pluginapi import PluginManager
OUR_MODULENAME = __name__ OUR_MODULENAME = __name__
@ -46,6 +47,10 @@ def setup_logging_from_paste_ini(loglevel, **kw):
logging.config.fileConfig(logging_conf_file) logging.config.fileConfig(logging_conf_file)
for callable_hook in \
PluginManager().get_hook_callables('celery_logging_setup'):
callable_hook()
setup_logging.connect(setup_logging_from_paste_ini) setup_logging.connect(setup_logging_from_paste_ini)

View File

@ -60,6 +60,7 @@ def process_video(proc_state):
A Workbench() represents a local tempory dir. It is automatically A Workbench() represents a local tempory dir. It is automatically
cleaned up when this function exits. cleaned up when this function exits.
""" """
raise Exception('Testing celery and raven')
entry = proc_state.entry entry = proc_state.entry
workbench = proc_state.workbench workbench = proc_state.workbench
video_config = mgg.global_config['media_type:mediagoblin.media_types.video'] video_config = mgg.global_config['media_type:mediagoblin.media_types.video']

View File

@ -2,10 +2,7 @@
raven plugin raven plugin
============== ==============
.. warning:: .. _raven-setup:
The raven plugin only sets up raven for celery. To enable raven for paster,
see the deployment docs section on setting up exception monitoring.
Set up the raven plugin Set up the raven plugin
======================= =======================
@ -14,3 +11,5 @@ Set up the raven plugin
[[mediagoblin.plugins.raven]] [[mediagoblin.plugins.raven]]
sentry_dsn = <YOUR SENTRY DSN> sentry_dsn = <YOUR SENTRY DSN>
# Logging is very high-volume, set to 0 if you want to turn off logging
setup_logging = 1

View File

@ -22,19 +22,14 @@ from mediagoblin.tools import pluginapi
_log = logging.getLogger(__name__) _log = logging.getLogger(__name__)
def setup_plugin(): def get_client():
if not os.environ.get('CELERY_CONFIG_MODULE'):
# Exit early if we're (seemingly) not called from the celery process
return
from raven import Client from raven import Client
from raven.contrib.celery import register_signal
config = pluginapi.get_config('mediagoblin.plugins.raven') config = pluginapi.get_config('mediagoblin.plugins.raven')
_log.info('Setting up raven for celery...')
sentry_dsn = config.get('sentry_dsn') sentry_dsn = config.get('sentry_dsn')
client = None
if sentry_dsn: if sentry_dsn:
_log.info('Setting up raven from plugin config: {0}'.format( _log.info('Setting up raven from plugin config: {0}'.format(
sentry_dsn)) sentry_dsn))
@ -43,13 +38,55 @@ def setup_plugin():
_log.info('Setting up raven from SENTRY_DSN environment variable: {0}'\ _log.info('Setting up raven from SENTRY_DSN environment variable: {0}'\
.format(os.environ.get('SENTRY_DSN'))) .format(os.environ.get('SENTRY_DSN')))
client = Client() # Implicitly looks for SENTRY_DSN client = Client() # Implicitly looks for SENTRY_DSN
else:
if not client:
_log.error('Could not set up client, missing sentry DSN') _log.error('Could not set up client, missing sentry DSN')
return return None
return client
def setup_celery():
from raven.contrib.celery import register_signal
client = get_client()
register_signal(client) register_signal(client)
def setup_logging():
config = pluginapi.get_config('mediagoblin.plugins.raven')
conf_setup_logging = False
if config.get('setup_logging'):
conf_setup_logging = bool(int(config.get('setup_logging')))
if not conf_setup_logging:
return
from raven.handlers.logging import SentryHandler
from raven.conf import setup_logging
client = get_client()
_log.info('Setting up raven logging handler')
setup_logging(SentryHandler(client))
def wrap_wsgi(app):
from raven.middleware import Sentry
client = get_client()
_log.info('Attaching raven middleware...')
return Sentry(app, client)
hooks = { hooks = {
'setup': setup_plugin, 'setup': setup_logging,
'wrap_wsgi': wrap_wsgi,
'celery_logging_setup': setup_logging,
'celery_setup': setup_celery,
} }