From c767ec9a37faa4414702aa9e39231afe0ba3b097 Mon Sep 17 00:00:00 2001 From: Clay Gerrard Date: Wed, 9 Jul 2014 16:04:20 -0700 Subject: [PATCH] Let eventlet.wsgi.server log tracebacks when eventlet_debug is enabled The "logging" available in eventlet.wsgi.server/BaseHTTPServer doesn't generally suite our needs, so it should be bypassed using a NullLogger in production. But in development it can be useful if tracebacks generated from inside eventlet.wsgi (say a NameError in DiskFile.__iter__) end up in logs. Since we already have eventlet_debug parsed inside of run_server we can skip the NullLogger bypass and let stuff blast out to STDERR when configured for development/debug logging. Change-Id: I20a9e82c7fed8948bf649f1f8571b4145fca201d --- swift/common/wsgi.py | 8 +++-- test/unit/common/test_wsgi.py | 59 ++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/swift/common/wsgi.py b/swift/common/wsgi.py index 5291746e6b..b1e1f5ea73 100644 --- a/swift/common/wsgi.py +++ b/swift/common/wsgi.py @@ -380,6 +380,10 @@ def run_server(conf, logger, sock, global_conf=None): eventlet.patcher.monkey_patch(all=False, socket=True) eventlet_debug = config_true_value(conf.get('eventlet_debug', 'no')) eventlet.debug.hub_exceptions(eventlet_debug) + wsgi_logger = NullLogger() + if eventlet_debug: + # let eventlet.wsgi.server log to stderr + wsgi_logger = None # utils.LogAdapter stashes name in server; fallback on unadapted loggers if not global_conf: if hasattr(logger, 'server'): @@ -395,10 +399,10 @@ def run_server(conf, logger, sock, global_conf=None): # necessary for the AWS SDK to work with swift3 middleware. argspec = inspect.getargspec(wsgi.server) if 'capitalize_response_headers' in argspec.args: - wsgi.server(sock, app, NullLogger(), custom_pool=pool, + wsgi.server(sock, app, wsgi_logger, custom_pool=pool, capitalize_response_headers=False) else: - wsgi.server(sock, app, NullLogger(), custom_pool=pool) + wsgi.server(sock, app, wsgi_logger, custom_pool=pool) except socket.error as err: if err[0] != errno.EINVAL: raise diff --git a/test/unit/common/test_wsgi.py b/test/unit/common/test_wsgi.py index aa10264898..67142decdd 100644 --- a/test/unit/common/test_wsgi.py +++ b/test/unit/common/test_wsgi.py @@ -317,7 +317,6 @@ class TestWSGI(unittest.TestCase): def test_run_server(self): config = """ [DEFAULT] - eventlet_debug = yes client_timeout = 30 max_clients = 1000 swift_dir = TEMPDIR @@ -354,7 +353,7 @@ class TestWSGI(unittest.TestCase): _eventlet.hubs.use_hub.assert_called_with(utils.get_hub()) _eventlet.patcher.monkey_patch.assert_called_with(all=False, socket=True) - _eventlet.debug.hub_exceptions.assert_called_with(True) + _eventlet.debug.hub_exceptions.assert_called_with(False) _wsgi.server.assert_called() args, kwargs = _wsgi.server.call_args server_sock, server_app, server_logger = args @@ -414,7 +413,6 @@ class TestWSGI(unittest.TestCase): """, 'proxy-server.conf.d/default.conf': """ [DEFAULT] - eventlet_debug = yes client_timeout = 30 """ } @@ -443,7 +441,7 @@ class TestWSGI(unittest.TestCase): _eventlet.hubs.use_hub.assert_called_with(utils.get_hub()) _eventlet.patcher.monkey_patch.assert_called_with(all=False, socket=True) - _eventlet.debug.hub_exceptions.assert_called_with(True) + _eventlet.debug.hub_exceptions.assert_called_with(False) _wsgi.server.assert_called() args, kwargs = _wsgi.server.call_args server_sock, server_app, server_logger = args @@ -452,6 +450,59 @@ class TestWSGI(unittest.TestCase): self.assert_(isinstance(server_logger, wsgi.NullLogger)) self.assert_('custom_pool' in kwargs) + def test_run_server_debug(self): + config = """ + [DEFAULT] + eventlet_debug = yes + client_timeout = 30 + max_clients = 1000 + swift_dir = TEMPDIR + + [pipeline:main] + pipeline = proxy-server + + [app:proxy-server] + use = egg:swift#proxy + # while "set" values normally override default + set client_timeout = 20 + # this section is not in conf during run_server + set max_clients = 10 + """ + + contents = dedent(config) + with temptree(['proxy-server.conf']) as t: + conf_file = os.path.join(t, 'proxy-server.conf') + with open(conf_file, 'w') as f: + f.write(contents.replace('TEMPDIR', t)) + _fake_rings(t) + with mock.patch('swift.proxy.server.Application.' + 'modify_wsgi_pipeline'): + with mock.patch('swift.common.wsgi.wsgi') as _wsgi: + mock_server = _wsgi.server + _wsgi.server = lambda *args, **kwargs: mock_server( + *args, **kwargs) + with mock.patch('swift.common.wsgi.eventlet') as _eventlet: + conf = wsgi.appconfig(conf_file) + logger = logging.getLogger('test') + sock = listen(('localhost', 0)) + wsgi.run_server(conf, logger, sock) + self.assertEquals('HTTP/1.0', + _wsgi.HttpProtocol.default_request_version) + self.assertEquals(30, _wsgi.WRITE_TIMEOUT) + _eventlet.hubs.use_hub.assert_called_with(utils.get_hub()) + _eventlet.patcher.monkey_patch.assert_called_with(all=False, + socket=True) + _eventlet.debug.hub_exceptions.assert_called_with(True) + mock_server.assert_called() + args, kwargs = mock_server.call_args + server_sock, server_app, server_logger = args + self.assertEquals(sock, server_sock) + self.assert_(isinstance(server_app, swift.proxy.server.Application)) + self.assertEquals(20, server_app.client_timeout) + self.assertEqual(server_logger, None) + self.assert_('custom_pool' in kwargs) + self.assertEquals(1000, kwargs['custom_pool'].size) + def test_appconfig_dir_ignores_hidden_files(self): config_dir = { 'server.conf.d/01.conf': """