소스 검색

Log Medusa errors at the ERROR level. Fixes #310

Mike Naberezny 10 년 전
부모
커밋
b3ad59703b
3개의 변경된 파일57개의 추가작업 그리고 7개의 파일을 삭제
  1. 5 1
      CHANGES.txt
  2. 18 6
      supervisor/http.py
  3. 34 0
      supervisor/tests/test_http.py

+ 5 - 1
CHANGES.txt

@@ -72,6 +72,10 @@
   which usually indicates a bug in the eventlistener.  Thanks to Steve
   Winton and detailyang for reporting issues that led to this change.
 
+- Errors from the web interface are now logged at the ``ERROR`` level.
+  Previously, they were logged at the ``TRACE`` level and easily
+  missed.  Thanks to Thomas Güttler for reporting this issue.
+
 3.1.3 (2014-10-28)
 ------------------
 
@@ -155,7 +159,7 @@
   it caused installation issues on some systems.
 
 - Fixed a bug in Medusa where the HTTP Basic authorizer would cause an
-  exception if the password contained a colon.  Thanks to Thomas Guttler
+  exception if the password contained a colon.  Thanks to Thomas Güttler
   for reporting this issue.
 
 - Fixed an XML-RPC bug where calling supervisor.clearProcessLogs() with a

+ 18 - 6
supervisor/http.py

@@ -788,12 +788,7 @@ class mainlogtail_handler:
 
 def make_http_servers(options, supervisord):
     servers = []
-    class LogWrapper:
-        def log(self, msg):
-            if msg.endswith('\n'):
-                msg = msg[:-1]
-            options.logger.trace(msg)
-    wrapper = LogWrapper()
+    wrapper = LogWrapper(options.logger)
 
     for config in options.server_configs:
         family = config['family']
@@ -864,6 +859,23 @@ def make_http_servers(options, supervisord):
 
     return servers
 
+class LogWrapper:
+    '''Receives log messages from the Medusa servers and forwards
+    them to the Supervisor logger'''
+    def __init__(self, logger):
+        self.logger = logger
+
+    def log(self, msg):
+        '''Medusa servers call this method.  There is no log level so
+        we have to sniff the message.  We want "Server Error" messages
+        from medusa.http_server logged as errors at least.'''
+        if msg.endswith('\n'):
+            msg = msg[:-1]
+        if 'error' in msg.lower():
+            self.logger.error(msg)
+        else:
+            self.logger.trace(msg)
+
 class encrypted_dictionary_authorizer:
     def __init__ (self, dict):
         self.dict = dict

+ 34 - 0
supervisor/tests/test_http.py

@@ -16,6 +16,7 @@ from supervisor.tests.base import DummyRPCInterfaceFactory
 from supervisor.tests.base import DummyPConfig
 from supervisor.tests.base import DummyOptions
 from supervisor.tests.base import DummyRequest
+from supervisor.tests.base import DummyLogger
 
 from supervisor.http import NOT_DONE_YET
 
@@ -503,6 +504,39 @@ class SupervisorAuthHandlerTests(unittest.TestCase):
         auth_handler.handle_request(request)
         self.assertFalse(handler.handled_request)
 
+class LogWrapperTests(unittest.TestCase):
+    def _getTargetClass(self):
+        from supervisor.http import LogWrapper
+        return LogWrapper
+
+    def _makeOne(self, logger):
+        return self._getTargetClass()(logger)
+
+    def test_strips_trailing_newlines_from_msgs(self):
+        logger = DummyLogger()
+        log_wrapper = self._makeOne(logger)
+        log_wrapper.log("foo\n")
+        logdata = logger.data
+        self.assertEqual(len(logdata), 1)
+        self.assertEqual(logdata[0], "foo")
+
+    def test_logs_msgs_with_error_at_error_level(self):
+        logger = DummyLogger()
+        log_wrapper = self._makeOne(logger)
+        errors = []
+        logger.error = errors.append
+        log_wrapper.log("Server Error")
+        self.assertEqual(len(errors), 1)
+        self.assertEqual(errors[0], "Server Error")
+
+    def test_logs_other_messages_at_trace_level(self):
+        logger = DummyLogger()
+        log_wrapper = self._makeOne(logger)
+        traces = []
+        logger.trace = traces.append
+        log_wrapper.log("GET /")
+        self.assertEqual(len(traces), 1)
+        self.assertEqual(traces[0], "GET /")
 
 class TopLevelFunctionTests(unittest.TestCase):
     def _make_http_servers(self, sconfigs):