fix bug in access logging when error happens

This commit is contained in:
zenix
2017-04-12 17:39:17 +09:00
parent bf46bcf376
commit f872ceb0d9
2 changed files with 47 additions and 14 deletions

View File

@@ -25,7 +25,8 @@ try:
except ImportError:
async_loop = asyncio
from sanic.log import log
from sanic.log import log, netlog
from sanic.response import HTTPResponse
from sanic.request import Request
from sanic.exceptions import (
RequestTimeout, PayloadTooLarge, InvalidUsage, ServerError)
@@ -64,12 +65,14 @@ class HttpProtocol(asyncio.Protocol):
'parser', 'request', 'url', 'headers',
# request config
'request_handler', 'request_timeout', 'request_max_size',
# enable or disable access log / error log purpose
'has_log_file',
# connection management
'_total_request_size', '_timeout_handler', '_last_communication_time')
def __init__(self, *, loop, request_handler, error_handler,
signal=Signal(), connections=set(), request_timeout=60,
request_max_size=None):
request_max_size=None, has_log_file=True):
self.loop = loop
self.transport = None
self.request = None
@@ -77,6 +80,7 @@ class HttpProtocol(asyncio.Protocol):
self.url = None
self.headers = None
self.signal = signal
self.has_log_file = has_log_file
self.connections = connections
self.request_handler = request_handler
self.error_handler = error_handler
@@ -187,6 +191,14 @@ class HttpProtocol(asyncio.Protocol):
response.output(
self.request.version, keep_alive,
self.request_timeout))
if self.has_log_file:
netlog.info('', extra={
'status': response.status,
'byte': len(response.body),
'host': '%s:%d' % self.request.ip,
'request': '%s %s' % (self.request.method,
self.request.url)
})
except AttributeError:
log.error(
('Invalid response object for url {}, '
@@ -222,6 +234,14 @@ class HttpProtocol(asyncio.Protocol):
response.transport = self.transport
await response.stream(
self.request.version, keep_alive, self.request_timeout)
if self.has_log_file:
netlog.info('', extra={
'status': response.status,
'byte': -1,
'host': '%s:%d' % self.request.ip,
'request': '%s %s' % (self.request.method,
self.request.url)
})
except AttributeError:
log.error(
('Invalid response object for url {}, '
@@ -257,6 +277,21 @@ class HttpProtocol(asyncio.Protocol):
"Writing error failed, connection closed {}".format(repr(e)),
from_error=True)
finally:
if self.has_log_file:
extra = {
'status': response.status,
'host': '',
'request': str(self.request) + str(self.url)
}
if response and isinstance(response, HTTPResponse):
extra['byte'] = len(response.body)
else:
extra['byte'] = -1
if self.request:
extra['host'] = '%s:%d' % self.request.ip,
extra['request'] = '%s %s' % (self.request.method,
self.url)
netlog.info('', extra=extra)
self.transport.close()
def bail_out(self, message, from_error=False):
@@ -320,7 +355,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
request_timeout=60, ssl=None, sock=None, request_max_size=None,
reuse_port=False, loop=None, protocol=HttpProtocol, backlog=100,
register_sys_signals=True, run_async=False, connections=None,
signal=Signal()):
signal=Signal(), has_log_file=True):
"""Start asynchronous HTTP Server on an individual process.
:param host: Address to host on
@@ -345,6 +380,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
:param reuse_port: `True` for multiple workers
:param loop: asyncio compatible event loop
:param protocol: subclass of asyncio protocol class
:param has_log_file: disable/enable access log and error log
:return: Nothing
"""
if not run_async:
@@ -366,6 +402,7 @@ def serve(host, port, request_handler, error_handler, before_start=None,
error_handler=error_handler,
request_timeout=request_timeout,
request_max_size=request_max_size,
has_log_file=has_log_file
)
server_coroutine = loop.create_server(