Skip to content
Browse files

Log Medusa errors at the ERROR level. Fixes #310

  • Loading branch information
mnaberez committed Jun 24, 2015
1 parent ca70361 commit b3ad59703b554fcf61639ca922e8053e0280f435
Showing with 57 additions and 7 deletions.
  1. +5 −1 CHANGES.txt
  2. +18 −6 supervisor/
  3. +34 −0 supervisor/tests/
@@ -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
@@ -788,12 +788,7 @@ def handle_request(self, request):

def make_http_servers(options, supervisord):
servers = []
class LogWrapper:
def log(self, msg):
if msg.endswith('\n'):
msg = msg[:-1]
wrapper = LogWrapper()
wrapper = LogWrapper(options.logger)

for config in options.server_configs:
family = config['family']
@@ -864,6 +859,23 @@ def log(self, msg):

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():

class encrypted_dictionary_authorizer:
def __init__ (self, dict):
self.dict = dict
@@ -16,6 +16,7 @@
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 @@ def test_handle_request_does_not_authorize_bad_credentials(self):

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)
logdata =
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):

0 comments on commit b3ad597

Please sign in to comment.
You can’t perform that action at this time.