diff --git a/daphne/access.py b/daphne/access.py index e18138a..7e730ca 100644 --- a/daphne/access.py +++ b/daphne/access.py @@ -1,4 +1,6 @@ -import datetime +import logging + +logger = logging.getLogger(__name__) class AccessLogGenerator: @@ -8,7 +10,16 @@ class AccessLogGenerator: """ def __init__(self, stream): - self.stream = stream + if stream: + logger.propagate = False + handler = logging.StreamHandler(stream) + formatter = logging.Formatter( + '%(host)s %(ident)s %(user)s [%(asctime)s] "%(message)s" ' + "%(status)s %(length)s", + "%d/%b/%Y:%H:%M:%S", + ) + handler.setFormatter(fmt=formatter) + logger.addHandler(handler) def __call__(self, protocol, action, details): """ @@ -18,8 +29,8 @@ def __call__(self, protocol, action, details): if protocol == "http" and action == "complete": self.write_entry( host=details["client"], - date=datetime.datetime.now(), - request="%(method)s %(path)s" % details, + request="%(method)s" % details, + details="%(path)s" % details, status=details["status"], length=details["size"], ) @@ -27,44 +38,48 @@ def __call__(self, protocol, action, details): elif protocol == "websocket" and action == "connecting": self.write_entry( host=details["client"], - date=datetime.datetime.now(), - request="WSCONNECTING %(path)s" % details, + request="WSCONNECTING", + details="%(path)s" % details, ) elif protocol == "websocket" and action == "rejected": self.write_entry( host=details["client"], - date=datetime.datetime.now(), - request="WSREJECT %(path)s" % details, + request="WSREJECT", + details="%(path)s" % details, ) elif protocol == "websocket" and action == "connected": self.write_entry( host=details["client"], - date=datetime.datetime.now(), - request="WSCONNECT %(path)s" % details, + request="WSCONNECT", + details="%(path)s" % details, ) elif protocol == "websocket" and action == "disconnected": self.write_entry( host=details["client"], - date=datetime.datetime.now(), - request="WSDISCONNECT %(path)s" % details, + request="WSDISCONNECT", + details="%(path)s" % details, ) def write_entry( - self, host, date, request, status=None, length=None, ident=None, user=None + self, host, request, details, status=None, length=None, ident=None, user=None ): """ - Writes an NCSA-style entry to the log file (some liberty is taken with - what the entries are for non-HTTP) + Writes an access log. If a file is specified, an NCSA-style entry to the log file + (some liberty is taken with what the entries are for non-HTTP). The format can be + overriden with logging configuration for 'daphne.access' """ - self.stream.write( - '%s %s %s [%s] "%s" %s %s\n' - % ( - host, - ident or "-", - user or "-", - date.strftime("%d/%b/%Y:%H:%M:%S"), - request, - status or "-", - length or "-", - ) + + logger.info( + "%s %s", + request, + details, + extra={ + "host": host, + "request": request, + "details": details, + "ident": ident or "-", + "user": user or "-", + "status": status or "-", + "length": length or "-", + }, ) diff --git a/daphne/cli.py b/daphne/cli.py index a036821..652a972 100755 --- a/daphne/cli.py +++ b/daphne/cli.py @@ -228,6 +228,10 @@ def run(self, args): elif args.verbosity >= 1: access_log_stream = sys.stdout + access_logger = ( + AccessLogGenerator(access_log_stream) if access_log_stream else None + ) + # Import application sys.path.insert(0, ".") application = import_by_path(args.application) @@ -270,9 +274,7 @@ def run(self, args): websocket_connect_timeout=args.websocket_connect_timeout, websocket_handshake_timeout=args.websocket_connect_timeout, application_close_timeout=args.application_close_timeout, - action_logger=( - AccessLogGenerator(access_log_stream) if access_log_stream else None - ), + action_logger=access_logger if access_log_stream else None, root_path=args.root_path, verbosity=args.verbosity, proxy_forwarded_address_header=self._get_forwarded_host(args=args),