Updated raven plugin
authorJoar Wandborg <joar@wandborg.se>
Sun, 3 Mar 2013 01:32:03 +0000 (02:32 +0100)
committerJoar Wandborg <joar@wandborg.se>
Sun, 3 Mar 2013 01:32:03 +0000 (02:32 +0100)
- Added wrap_wsgi, celery_setup, celery_logging_setup hooks
- Updated raven plugin docs
- Updated production considerations docs
- Added raven logging setup

docs/source/plugindocs/raven.rst
docs/source/siteadmin/production-deployments.rst
mediagoblin/app.py
mediagoblin/init/celery/__init__.py
mediagoblin/init/celery/from_celery.py
mediagoblin/media_types/video/processing.py
mediagoblin/plugins/raven/README.rst
mediagoblin/plugins/raven/__init__.py

index ae96f3f87e44af4de51e5b6d6072a334c8b0e9e1..71e284d0cc49ce2688049cd80d175c1074edeb40 100644 (file)
@@ -1 +1,2 @@
+.. _raven-setup: Set up the raven plugin
 .. include:: ../../../mediagoblin/plugins/raven/README.rst
index 0ed5ac6a757df2f843c32e270b296e93c8052d6d..3e9431c9264a61873e416831e73324493edd59f0 100644 (file)
@@ -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:
 
index 607d599b0dfbfe39b74655f4fc78832afdb92503..bb6be4d4204366d8243ccb0a954a7db4e1604f7d 100644 (file)
@@ -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
index fc595ea77bb671998ff218ca35de6f0c45a185d3..8d7a41bdaf7a617ebcbe17d38b9eced48cffeadd 100644 (file)
@@ -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,
index 5c99ddff07952d52466c83808c118fd6f9452b41..8a794abbe1e4a62649c90dd6e68ba8db748167ac 100644 (file)
@@ -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)
 
index 5b9be2425e7c72972b234dec69726afb2e86259a..3a2dc481b07ea8b846afc04776abab4284257aa0 100644 (file)
@@ -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']
index 06510a96de902e1f6c9a65ff7f041b34c0805f84..de5fd20d42ca2aa378ee9db422bac75a1d42d54f 100644 (file)
@@ -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 = <YOUR SENTRY DSN>
+    # Logging is very high-volume, set to 0 if you want to turn off logging
+    setup_logging = 1
index 16b3b94b88364a0b7824ea64898d7d6cfff397dd..8cfaed0aa8cb24f4698ad2f91b9b4dfee2ab8a5d 100644 (file)
@@ -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,
     }