Skip to content
This repository was archived by the owner on Oct 23, 2023. It is now read-only.

Commit 4c59089

Browse files
Michael Pistrangashwoods
authored andcommitted
allow subclasses of SentryHandler to be modified by the celery logging signal, resolves #961
1 parent f516edf commit 4c59089

File tree

2 files changed

+124
-2
lines changed

2 files changed

+124
-2
lines changed

raven/contrib/celery/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def process_logger_event(sender, logger, loglevel, logfile, format,
4343
# that the CeleryFilter is installed.
4444
# If one is found, we do not attempt to install another one.
4545
for h in logger.handlers:
46-
if type(h) == SentryHandler:
46+
if isinstance(h, SentryHandler):
4747
h.addFilter(filter_)
4848
return False
4949

tests/contrib/test_celery.py

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
from __future__ import absolute_import
22

33
import celery
4+
import logging
45

5-
from raven.contrib.celery import SentryCeleryHandler
6+
from raven.contrib.celery import (
7+
SentryCeleryHandler,
8+
register_logger_signal,
9+
CeleryFilter
10+
)
11+
from raven.handlers.logging import SentryHandler
612
from raven.utils.testutils import InMemoryClient, TestCase
713

814

@@ -38,3 +44,119 @@ def dummy_task(x, y):
3844
dummy_task.delay(1, 2)
3945
dummy_task.delay(1, 0)
4046
assert len(self.client.events) == 0
47+
48+
49+
class CeleryLoggingHandlerTestCase(TestCase):
50+
def setUp(self):
51+
super(CeleryLoggingHandlerTestCase, self).setUp()
52+
53+
self.client = InMemoryClient()
54+
55+
# register the logger signal
56+
# and unregister the signal when the test is done
57+
register_logger_signal(self.client)
58+
receiver = celery.signals.after_setup_logger.receivers[0][1]
59+
self.addCleanup(celery.signals.after_setup_logger.disconnect, receiver)
60+
61+
# remove any existing handlers and restore
62+
# them when complete
63+
self.root = logging.getLogger()
64+
for handler in self.root.handlers:
65+
self.root.removeHandler(handler)
66+
self.addCleanup(self.root.addHandler, handler)
67+
68+
def test_handler_added(self):
69+
# Given: there are no handlers configured
70+
assert not self.root.handlers
71+
72+
# When: the after_setup_logger signal is sent
73+
celery.signals.after_setup_logger.send(
74+
sender=None, logger=self.root,
75+
loglevel=logging.WARNING, logfile=None,
76+
format=u'', colorize=False,
77+
)
78+
79+
# Then: there is 1 new handler
80+
assert len(self.root.handlers) == 1
81+
82+
# Then: the new handler is an instance of
83+
# `raven.handlers.logging.SentryHandler`
84+
handler = self.root.handlers[0]
85+
assert isinstance(handler, SentryHandler)
86+
87+
# Then: the handler has 1 filter
88+
assert len(handler.filters) == 1
89+
90+
# Then: the filter is a CeleryFilter
91+
_filter = handler.filters[0]
92+
assert isinstance(_filter, CeleryFilter)
93+
94+
# set up the handler to be removed once the test is done
95+
self.addCleanup(self.root.removeHandler, handler)
96+
97+
def test_handler_updated(self):
98+
99+
# Given: there is 1 preconfigured SentryHandler
100+
# with no filters
101+
handler = SentryHandler(self.client)
102+
assert not handler.filters
103+
self.root.addHandler(handler)
104+
# set up the handler to be removed once the test is done
105+
self.addCleanup(self.root.removeHandler, handler)
106+
107+
# When: the after_setup_logger signal is sent
108+
celery.signals.after_setup_logger.send(
109+
sender=None, logger=self.root,
110+
loglevel=logging.WARNING, logfile=None,
111+
format=u'', colorize=False,
112+
)
113+
114+
# Then: there is still just 1 handler
115+
assert len(self.root.handlers) == 1
116+
117+
# Then: the existing handler is an instance of
118+
# `raven.handlers.logging.SentryHandler`
119+
handler = self.root.handlers[0]
120+
assert isinstance(handler, SentryHandler)
121+
122+
# Then: the existing handler has 1 filter
123+
assert len(handler.filters) == 1
124+
125+
# Then: the filter is a CeleryFilter
126+
_filter = handler.filters[0]
127+
assert isinstance(_filter, CeleryFilter)
128+
129+
def test_subclassed_handler_updated(self):
130+
131+
# Given: there is 1 preconfigured CustomHandler
132+
# with no filters
133+
class CustomHandler(SentryHandler):
134+
pass
135+
136+
handler = CustomHandler(self.client)
137+
assert not handler.filters
138+
self.root.addHandler(handler)
139+
# set up the handler to be removed once the test is done
140+
self.addCleanup(self.root.removeHandler, handler)
141+
142+
# When: the after_setup_logger signal is sent
143+
celery.signals.after_setup_logger.send(
144+
sender=None, logger=self.root,
145+
loglevel=logging.WARNING, logfile=None,
146+
format=u'', colorize=False,
147+
)
148+
149+
# Then: there is still just 1 handler
150+
assert len(self.root.handlers) == 1
151+
152+
# Then: the existing handler is an instance of
153+
# `CustomHandler`
154+
handler = self.root.handlers[0]
155+
assert isinstance(handler, CustomHandler)
156+
157+
# Then: the existing handler has 1 filter
158+
assert len(handler.filters) == 1
159+
160+
# Then: the filter is a CeleryFilter
161+
_filter = handler.filters[0]
162+
assert isinstance(_filter, CeleryFilter)

0 commit comments

Comments
 (0)