Logging#
Application and request level loggers can be configured using the LoggingConfig
:
from litestar import Litestar, Request, get
from litestar.logging import LoggingConfig
@get("/")
def my_router_handler(request: Request) -> None:
request.logger.info("inside a request")
return None
logging_config = LoggingConfig(
root={"level": "INFO", "handlers": ["queue_listener"]},
formatters={
"standard": {"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"}
},
log_exceptions="always",
)
app = Litestar(route_handlers=[my_router_handler], logging_config=logging_config)
Attention
Litestar configures a non-blocking QueueListenerHandler
which
is keyed as queue_listener
in the logging configuration. The above example is using this handler,
which is optimal for async applications. Make sure to use it in your own loggers as in the above example.
Attention
Exceptions won’t be logged by default, except in debug mode. Make sure to use log_exceptions="always"
as in the
example above to log exceptions if you need it.
Using Python standard library#
logging is Python’s builtin standard logging library and can be
configured through LoggingConfig
.
The LoggingConfig.configure()
method returns a reference to logging.getLogger
which can be used to access a
logger instance. Thus, the root logger can retrieved with logging_config.configure()()
as shown in the example
below:
from litestar import Litestar, Request, get
from litestar.logging import LoggingConfig
logging_config = LoggingConfig(
root={"level": "INFO", "handlers": ["queue_listener"]},
formatters={
"standard": {"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"}
},
log_exceptions="always",
)
logger = logging_config.configure()()
@get("/")
def my_router_handler(request: Request) -> None:
request.logger.info("inside a request")
logger.info("here too")
app = Litestar(
route_handlers=[my_router_handler],
logging_config=logging_config,
)
The above example is the same as using logging without the litestar LoggingConfig
.
import logging
from litestar import Litestar, Request, get
def get_logger(mod_name: str) -> logging.Logger:
"""Return logger object."""
format = "%(asctime)s: %(name)s: %(levelname)s: %(message)s"
logger = logging.getLogger(mod_name)
# Writes to stdout
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
ch.setFormatter(logging.Formatter(format))
logger.addHandler(ch)
return logger
logger = get_logger(__name__)
@get("/")
def my_router_handler(request: Request) -> None:
logger.info("logger inside a request")
app = Litestar(
route_handlers=[my_router_handler],
)
Using Picologging#
Picologging is a high performance logging library that is developed by
Microsoft. Litestar will default to using this library automatically if its installed - requiring zero configuration on
the part of the user. That is, if picologging
is present the previous example will work with it automatically.
Using StructLog#
StructLog is a powerful structured-logging library. Litestar ships with a dedicated logging plugin and config for using it:
from litestar import Litestar, Request, get
from litestar.plugins.structlog import StructlogPlugin
@get("/")
def my_router_handler(request: Request) -> None:
request.logger.info("inside a request")
return None
structlog_plugin = StructlogPlugin()
app = Litestar(route_handlers=[my_router_handler], plugins=[StructlogPlugin()])
Subclass Logging Configs#
You can easily create you own LoggingConfig
class by subclassing
BaseLoggingConfig
and implementing the configure
method.