1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
.. _logging-usage:
Logging
=======
Application and request level loggers can be configured using the :class:`~litestar.logging.config.LoggingConfig`:
.. code-block:: python
import logging
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.
Controlling Exception Logging
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
While ``log_exceptions`` controls when exceptions are logged, sometimes you may want to suppress stack traces for specific
exception types or HTTP status codes. The ``disable_stack_trace`` parameter allows you to specify a set of exception types
or status codes that should not generate stack traces in logs:
.. code-block:: python
from litestar import Litestar
from litestar.logging import LoggingConfig
# Don't log stack traces for 404 errors and ValueError exceptions
logging_config = LoggingConfig(
debug=True,
disable_stack_trace={404, ValueError},
)
app = Litestar(logging_config=logging_config)
This is particularly useful for common exceptions that you expect in normal operation and don't need detailed stack traces for.
Using Python standard library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`logging <https://docs.python.org/3/howto/logging.html>`_ 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:
.. code-block:: python
import logging
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``.
.. code-block:: python
import logging
from litestar import Litestar, Request, get
from litestar.logging.config import LoggingConfig
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 <https://github.com/microsoft/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 <https://www.structlog.org/en/stable/>`_ is a powerful structured-logging library. Litestar ships with a
dedicated logging plugin and config for using it:
.. code-block:: python
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
:class:`BaseLoggingConfig <.logging.config.BaseLoggingConfig>` and implementing the ``configure`` method.
|