← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~lifeless/python-oops-twisted/bug-902006 into lp:python-oops-twisted

 

Robert Collins has proposed merging lp:~lifeless/python-oops-twisted/bug-902006 into lp:python-oops-twisted.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~lifeless/python-oops-twisted/bug-902006/+merge/85065

Let OOPSObserver be used in more places. http://twistedmatrix.com/trac/ticket/5425 may help for context.
-- 
https://code.launchpad.net/~lifeless/python-oops-twisted/bug-902006/+merge/85065
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~lifeless/python-oops-twisted/bug-902006 into lp:python-oops-twisted.
=== modified file 'NEWS'
--- NEWS	2011-11-07 07:05:31 +0000
+++ NEWS	2011-12-09 06:00:32 +0000
@@ -6,6 +6,9 @@
 NEXT
 ----
 
+* OOPObserver now implements ILogObserver allowing it to be connected to an
+  application in a .tac file via addComponent. (Robert Collins, #902006)
+
 0.0.5
 -----
 

=== modified file 'README'
--- README	2011-11-07 03:06:22 +0000
+++ README	2011-12-09 06:00:32 +0000
@@ -70,7 +70,7 @@
 * And enable it::
 
  >>> from twisted.log import addObserver
- >>> addObserver(observer.emit)
+ >>> addObserver(observer)
 
 * This is typically used to supplement regular logging, e.g. you might
   initialize normal logging to a file first::

=== modified file 'oops_twisted/log.py'
--- oops_twisted/log.py	2011-10-13 03:02:31 +0000
+++ oops_twisted/log.py	2011-12-09 06:00:32 +0000
@@ -21,7 +21,11 @@
 import datetime
 
 from pytz import utc
-from twisted.python.log import textFromEventDict
+from twisted.python.log import (
+    ILogObserver,
+    textFromEventDict,
+    )
+from zope.interface import implements
 
 
 __all__ = [
@@ -32,6 +36,8 @@
 class OOPSObserver:
     """Convert twisted log events to OOPSes if they are failures."""
 
+    implements(ILogObserver)
+
     def __init__(self, config, fallback=None):
         """"Create an OOPSObserver.
 
@@ -47,6 +53,10 @@
     def emit(self, eventDict):
         """Handle a twisted log entry.
 
+        Note that you should generally pass the actual observer to twisted
+        functions, as the observer instance 'implements' ILogObserver, but the
+        emit method does not (and cannot).
+
         :return: For testing convenience returns the oops report and a deferred
             which fires after all publication and fallback forwarding has
             occured, though the twisted logging protocol does not need (or
@@ -67,6 +77,8 @@
             d.addCallback(self._fallback_report, report, dict(eventDict))
         return report, d
 
+    __call__ = emit
+
     def _fallback_report(self, ids, report, event):
         # If ids is empty, no publication occured so there is no id to forward:
         # don't alter the event at all in this case.

=== modified file 'oops_twisted/tests/test_log.py'
--- oops_twisted/tests/test_log.py	2011-10-13 03:02:31 +0000
+++ oops_twisted/tests/test_log.py	2011-12-09 06:00:32 +0000
@@ -28,7 +28,12 @@
     reactor,
     )
 from twisted.python import failure
-from twisted.python.log import textFromEventDict
+from twisted.python.log import (
+    ILogObserver,
+    textFromEventDict,
+    )
+from zope.interface.verify import verifyObject
+
 
 from oops_twisted import (
     Config,
@@ -40,6 +45,11 @@
 
     run_tests_with = AsynchronousDeferredRunTest
 
+    def test_implements_ILogObserver(self):
+        config = Config()
+        observer = OOPSObserver(config)
+        self.assertTrue(verifyObject(ILogObserver, observer))
+
     def test_nonfailure_no_fallback(self):
         config = Config()
         observer = OOPSObserver(config)
@@ -47,6 +57,13 @@
         self.assertEqual(None, report)
         self.assertEqual(None, d)
 
+    def test_can_call_observer_directly(self):
+        config = Config()
+        observer = OOPSObserver(config)
+        report, d = observer({})
+        self.assertEqual(None, report)
+        self.assertEqual(None, d)
+
     def test_nonfailure_fallback(self):
         config = Config()
         calls = []