bug 858360 initialize the SentryHandler for Raven >= 3.0

* Got rid of the alternate MetlogTastypieHandler and just use the
  standard SentryHandler with a client extracted from
  raven.contrib.django.models
* dropped USE_METLOG_FOR_TASTYPIE as tastypie will now just use
  whatever sentry client is defined by settings.SENTRY_CLIENT
* fixed the construction of SentryHandler to use raven 3.0 compatible
  arguments
This commit is contained in:
Victor Ng 2013-04-08 14:04:47 -04:00
Родитель 3d3f71625a
Коммит ff365249ec
7 изменённых файлов: 31 добавлений и 99 удалений

Просмотреть файл

@ -3,7 +3,6 @@ import logging.handlers
from django.conf import settings
from .metlog_shim import MetlogTastypieHandler
from raven.handlers.logging import SentryHandler
import commonware.log
import dictconfig
@ -96,6 +95,15 @@ cfg = {
}
def get_sentry_handler():
# This should effectively make Tastypie do the same thing as
# the error trapping in
# raven.contrib.django.models:sentry_exception_handler
from raven.contrib.django.models import get_client
handler = SentryHandler(get_client())
return handler
def log_configure():
"""You have to explicitly call this to configure logging."""
for key, value in settings.LOGGING.items():
@ -120,7 +128,4 @@ def log_configure():
# logging.getLogger() accesses a singleton, this just binds
# in the SentryHandler to error level messages
tastypie = logging.getLogger('django.request.tastypie')
if settings.USE_METLOG_FOR_TASTYPIE:
tastypie.addHandler(MetlogTastypieHandler(settings.METLOG))
else:
tastypie.addHandler(SentryHandler())
tastypie.addHandler(get_sentry_handler())

Просмотреть файл

@ -1,57 +0,0 @@
from __future__ import absolute_import
from metlog.client import SEVERITY
import logging
class MetlogTastypieHandler(logging.Handler):
"""
This handler will *only* handle error level logging
and it meant as a temporary shim to add Metlog's Raven capability
to the standard python logging library.
It is only intended for use with django-tastypie
"""
def __init__(self, metlog_client):
logging.Handler.__init__(self)
self.metlog_client = metlog_client
def emit(self, record):
severity = {
logging.DEBUG: SEVERITY.DEBUG,
logging.INFO: SEVERITY.INFORMATIONAL,
logging.WARNING: SEVERITY.WARNING,
logging.ERROR: SEVERITY.ERROR,
}.get(record.levelno, SEVERITY.CRITICAL)
safe_dict = dict(record.__dict__)
del safe_dict['exc_info']
del safe_dict['msg']
del safe_dict['args']
self.metlog_client.raven(msg=record.msg,
exc_info=record.exc_info,
logger=record.name,
severity=severity,
args=record.args, kwargs=safe_dict)
def hook_logger(logger_name, client):
"""
Used to hook metlog into the Python stdlib logging framework. Registers a
logging module handler that delegates to a MetlogClient for actual message
delivery.
:param name: Name of the stdlib logging `logger` object for which the
handler should be registered.
:param client: MetlogClient instance that the registered handler will use
for actual message delivery.
"""
logger = logging.getLogger(logger_name)
# first check to see if we're already registered
for existing in logger.handlers:
if (isinstance(existing, MetlogTastypieHandler) and
existing.metlog_client is client):
# already done, do nothing
return
logger.addHandler(MetlogTastypieHandler(client))

Просмотреть файл

@ -12,7 +12,7 @@ from metlog.config import client_from_dict_config
import amo.tests
import commonware.log
from lib.log_settings_base import error_fmt
from lib.metlog_shim import MetlogTastypieHandler
from lib.log_settings_base import get_sentry_handler
from lib.misc.admin_log import ErrorTypeHandler
from test_utils import RequestFactory
@ -178,11 +178,6 @@ class TestRaven(amo.tests.TestCase):
"""
We need to set the settings.METLOG instance to use a
DebugCaptureSender so that we can inspect the sent messages.
We also need to force list of handlers for
'django.request.tastypie' to use only the MetlogTastypieHandler,
then revert the list of handlers back to whatever they were
prior to invoking the test case.
"""
metlog = settings.METLOG
@ -204,42 +199,35 @@ class TestRaven(amo.tests.TestCase):
eq_(msg['type'], 'sentry')
class TestTastypieHandler(amo.tests.TestCase):
class TestStdTastypieHandler(amo.tests.TestCase):
def setUp(self):
"""
We need to set the settings.METLOG instance to use a
DebugCaptureSender so that we can inspect the sent messages.
The SentryHandler had it's constructor arguments change.
This just verifies that client wrapped inside the
SentryHandler is properly initialized
We also need to force list of handlers for
'django.request.tastypie' to use only the MetlogTastypieHandler,
then revert the list of handlers back to whatever they were
prior to invoking the test case.
"""
metlog = settings.METLOG
METLOG_CONF = {
'logger': 'zamboni',
'sender': {'class': 'metlog.senders.DebugCaptureSender'},
}
from metlog.config import client_from_dict_config
self.metlog = client_from_dict_config(METLOG_CONF, metlog)
self.metlog.sender.msgs.clear()
self.logger = logging.getLogger('django.request.tastypie')
"""
When logging.config.dictConfig is used to configure logging
with a 'one-shot' config dictionary, any previously
instantiated singleton loggers (ie: all old loggers not in
the new config) will be explicitly disabled.
"""
self.logger = logging.getLogger('django.request.tastypie')
self.logger.disabled = False
self._orig_handlers = self.logger.handlers
self.logger.handlers = [MetlogTastypieHandler(settings.METLOG)]
while self.logger.handlers:
self.logger.removeHandler(self.logger.handlers[0])
self._handler = get_sentry_handler()
def capture_func(record):
self._captured = record
self._handler.emit = capture_func
self.logger.addHandler(self._handler)
def tearDown(self):
self.logger.handlers = self._orig_handlers
while self.logger.handlers:
self.logger.removeHandler(self.logger.handlers[0])
while self._orig_handlers:
self.logger.addHandler(self._orig_handlers[0])
def test_tastypie_handler(self):
err_msg = "tastypie error triggered"
@ -248,7 +236,7 @@ class TestTastypieHandler(amo.tests.TestCase):
except:
self.logger.error(err_msg)
msg = json.loads(self.metlog.sender.msgs[0])
eq_(msg['type'], 'sentry')
eq_(msg['fields']['msg'], err_msg)
# This will fail if the SentryHandler isn't configured
# properly
assert self._handler.client.is_enabled()
eq_("tastypie error triggered", self._captured.message)

Просмотреть файл

@ -150,5 +150,4 @@ METLOG_CONF = {
}
METLOG = client_from_dict_config(METLOG_CONF)
USE_METLOG_FOR_CEF = True
USE_METLOG_FOR_TASTYPIE = True
SENTRY_CLIENT = 'djangoraven.metlog.MetlogDjangoClient'

Просмотреть файл

@ -165,7 +165,6 @@ METLOG_CONF = {
}
METLOG = client_from_dict_config(METLOG_CONF)
USE_METLOG_FOR_CEF = True
USE_METLOG_FOR_TASTYPIE = False
SENTRY_CLIENT = 'djangoraven.metlog.MetlogDjangoClient'
GOOGLE_ANALYTICS_DOMAIN = 'marketplace.firefox.com'

Просмотреть файл

@ -146,7 +146,6 @@ METLOG_CONF = {
}
METLOG = client_from_dict_config(METLOG_CONF)
USE_METLOG_FOR_CEF = True
USE_METLOG_FOR_TASTYPIE = True
SENTRY_CLIENT = 'djangoraven.metlog.MetlogDjangoClient'

Просмотреть файл

@ -163,7 +163,6 @@ METLOG_CONF = {
}
METLOG = client_from_dict_config(METLOG_CONF)
USE_METLOG_FOR_CEF = True
USE_METLOG_FOR_TASTYPIE = True
SENTRY_CLIENT = 'djangoraven.metlog.MetlogDjangoClient'
# See mkt/settings.py for more info.