I believe the access_log_format
option is currently ignored when using the uvicorn/gunicorn/fastapi combo. But that is mostly for editing what will be the %(message)s
part of the log anyway. If you just want to add a timestamp you should be able to override the behavior of the loggers (though the defaults had a timestamp for me).
I put the example below in __init__.py
right before the fastapi app
was defined.
import logging, logging.config
LOG_CONFIG = {
"version": 1,
"disable_existing_loggers": True,
"formatters": {"default": {"format": "%(asctime)s [%(process)s] %(levelname)s: %(message)s"}},
"handlers": {
"console": {
"formatter": "default",
"class": "logging.StreamHandler",
"stream": "ext://sys.stdout",
"level": "INFO",
}
},
"root": {"handlers": ["console"], "level": "INFO"},
"loggers": {
"gunicorn": {"propagate": True},
"gunicorn.access": {"propagate": True},
"gunicorn.error": {"propagate": True},
"uvicorn": {"propagate": True},
"uvicorn.access": {"propagate": True},
"uvicorn.error": {"propagate": True},
},
}
logging.config.dictConfig(LOG_CONFIG)
logger = logging.getLogger(__name__)
Check out this answer for some good examples of the logging dict config.
If you actually want to edit the access log format of uvicorn I'm not sure there is an "official" way to do so. As of this writing they seem to have a hardcoded format in their code:
if self.access_log:
self.access_logger.info(
'%s - "%s %s HTTP/%s" %d',
get_client_addr(self.scope),
self.scope["method"],
get_path_with_query_string(self.scope),
self.scope["http_version"],
status_code,
extra={"status_code": status_code, "scope": self.scope},
)
I am interested in having that print x-forwarded-for
header values for example. One ugly way around that is to monkey patch uvicorn.protocols.utils.get_client_addr
and pull whatever you want from the scope
dict that gets passed to it. It happens to have the request headers. NOTE: This may have unintended consequences, particularly if the uvicorn
folks change their code to use get_client_addr
for anything more than printing a value.
Perhaps there is a way to do this with a custom worker class that uses a custom logger, but I haven't seen that done yet either.