From: Joar Wandborg Date: Sun, 3 Mar 2013 01:32:03 +0000 (+0100) Subject: Updated raven plugin X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=f3f530286ff576a3120e29f734aff0b7b7fe882c;p=mediagoblin.git Updated raven plugin - Added wrap_wsgi, celery_setup, celery_logging_setup hooks - Updated raven plugin docs - Updated production considerations docs - Added raven logging setup --- diff --git a/docs/source/plugindocs/raven.rst b/docs/source/plugindocs/raven.rst index ae96f3f8..71e284d0 100644 --- a/docs/source/plugindocs/raven.rst +++ b/docs/source/plugindocs/raven.rst @@ -1 +1,2 @@ +.. _raven-setup: Set up the raven plugin .. include:: ../../../mediagoblin/plugins/raven/README.rst diff --git a/docs/source/siteadmin/production-deployments.rst b/docs/source/siteadmin/production-deployments.rst index 0ed5ac6a..3e9431c9 100644 --- a/docs/source/siteadmin/production-deployments.rst +++ b/docs/source/siteadmin/production-deployments.rst @@ -77,51 +77,16 @@ Modify your existing MediaGoblin and application init scripts, if necessary, to prevent them from starting their own ``celeryd`` processes. -Monitor exceptions ------------------- - -This is an example config using raven_ to report exceptions and -:py:mod:`logging` messages to a sentry_ instance - -.. _raven: http://raven.readthedocs.org/ -.. _sentry: https://github.com/getsentry - -.. code-block:: ini - - [pipeline:main] - pipeline = - errors - raven - routing - - [loggers] - keys = root, sentry - - [handlers] - keys = console, sentry - - [formatters] - keys = generic +.. _sentry: - [logger_root] - level = INFO - handlers = console, sentry +Set up sentry to monitor exceptions +----------------------------------- - [logger_sentry] - level = WARN - handlers = console - qualname = sentry.errors - propagate = 0 +We have a plugin for `raven`_ integration, see the ":doc:`/plugindocs/raven`" +documentation. - [handler_sentry] - class = raven.handlers.logging.SentryHandler - args = ('http://public:secret@example.com/1',) - level = WARNING - formatter = generic +.. _`raven`: http://raven.readthedocs.org - [filter:raven] - use = egg:raven#raven - dsn = http://71727ea2c69043e4bbcd793bb0115cd4:e9cedccb32d9482d81f99eeca8b1ad30@sentry.talka.tv/3 .. _init-script: diff --git a/mediagoblin/app.py b/mediagoblin/app.py index 607d599b..bb6be4d4 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -253,4 +253,7 @@ def paste_app_factory(global_config, **app_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 diff --git a/mediagoblin/init/celery/__init__.py b/mediagoblin/init/celery/__init__.py index fc595ea7..8d7a41bd 100644 --- a/mediagoblin/init/celery/__init__.py +++ b/mediagoblin/init/celery/__init__.py @@ -18,6 +18,7 @@ import os import sys from celery import Celery +from mediagoblin.tools.pluginapi import PluginManager MANDATORY_CELERY_IMPORTS = ['mediagoblin.processing.task'] @@ -65,6 +66,9 @@ def setup_celery_app(app_config, global_config, celery_app = Celery() 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, settings_module=DEFAULT_SETTINGS_MODULE, diff --git a/mediagoblin/init/celery/from_celery.py b/mediagoblin/init/celery/from_celery.py index 5c99ddff..8a794abb 100644 --- a/mediagoblin/init/celery/from_celery.py +++ b/mediagoblin/init/celery/from_celery.py @@ -22,6 +22,7 @@ from celery.signals import setup_logging from mediagoblin import app, mg_globals from mediagoblin.init.celery import setup_celery_from_config +from mediagoblin.tools.pluginapi import PluginManager OUR_MODULENAME = __name__ @@ -46,6 +47,10 @@ def setup_logging_from_paste_ini(loglevel, **kw): 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) diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index 5b9be242..3a2dc481 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -60,6 +60,7 @@ def process_video(proc_state): A Workbench() represents a local tempory dir. It is automatically cleaned up when this function exits. """ + raise Exception('Testing celery and raven') entry = proc_state.entry workbench = proc_state.workbench video_config = mgg.global_config['media_type:mediagoblin.media_types.video'] diff --git a/mediagoblin/plugins/raven/README.rst b/mediagoblin/plugins/raven/README.rst index 06510a96..de5fd20d 100644 --- a/mediagoblin/plugins/raven/README.rst +++ b/mediagoblin/plugins/raven/README.rst @@ -2,10 +2,7 @@ raven plugin ============== -.. warning:: - The raven plugin only sets up raven for celery. To enable raven for paster, - see the deployment docs section on setting up exception monitoring. - +.. _raven-setup: Set up the raven plugin ======================= @@ -14,3 +11,5 @@ Set up the raven plugin [[mediagoblin.plugins.raven]] sentry_dsn = + # Logging is very high-volume, set to 0 if you want to turn off logging + setup_logging = 1 diff --git a/mediagoblin/plugins/raven/__init__.py b/mediagoblin/plugins/raven/__init__.py index 16b3b94b..8cfaed0a 100644 --- a/mediagoblin/plugins/raven/__init__.py +++ b/mediagoblin/plugins/raven/__init__.py @@ -22,19 +22,14 @@ from mediagoblin.tools import pluginapi _log = logging.getLogger(__name__) -def setup_plugin(): - if not os.environ.get('CELERY_CONFIG_MODULE'): - # Exit early if we're (seemingly) not called from the celery process - return - +def get_client(): from raven import Client - from raven.contrib.celery import register_signal config = pluginapi.get_config('mediagoblin.plugins.raven') - _log.info('Setting up raven for celery...') - sentry_dsn = config.get('sentry_dsn') + client = None + if sentry_dsn: _log.info('Setting up raven from plugin config: {0}'.format( sentry_dsn)) @@ -43,13 +38,55 @@ def setup_plugin(): _log.info('Setting up raven from SENTRY_DSN environment variable: {0}'\ .format(os.environ.get('SENTRY_DSN'))) client = Client() # Implicitly looks for SENTRY_DSN - else: + + if not client: _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) +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 = { - 'setup': setup_plugin, + 'setup': setup_logging, + 'wrap_wsgi': wrap_wsgi, + 'celery_logging_setup': setup_logging, + 'celery_setup': setup_celery, }