mirror of
https://github.com/vinta/awesome-python.git
synced 2026-10-02 08:23:10 +08:00
docs: add Logging category intro
The Logging category page showed only the table with a generic meta description, with no intro. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
Keep the built-in logging module until you need what a Python logging library adds: structlog's key-value logs in JSON, or Loguru's logger, ready on import.
|
||||
|
||||
How to choose:
|
||||
|
||||
- A library other people import: logging, with only a `NullHandler`
|
||||
- Key-value events, pretty in development and JSON in production: structlog
|
||||
- An app already on logging that needs structured output: structlog, which wraps it
|
||||
- A script you want logging in with no setup: Loguru
|
||||
- Log files that rotate, expire, and compress: Loguru
|
||||
|
||||
Every Python module [can take part in the standard library's logging](https://docs.python.org/3/library/logging.html), so your app's log holds messages from third-party packages next to your own. In each module, create a logger with [`logging.getLogger(__name__)`](https://docs.python.org/3/howto/logging.html#advanced-logging-tutorial), so logger names follow your package layout. Use `basicConfig()` for a quick setup, and move to [`dictConfig()`](https://docs.python.org/3/howto/logging.html#configuring-logging), which the docs recommend for new applications. In a library, [add no handler other than `NullHandler`](https://docs.python.org/3/howto/logging.html#configuring-logging-for-a-library) and don't log to the root logger: handlers are for the app developer to pick.
|
||||
|
||||
structlog logs [events in a context of key-value pairs](https://www.structlog.org/en/latest/why.html#structured-logging) instead of prose, so each entry is a dictionary instead of a string. [Bind values to a logger](https://www.structlog.org/en/latest/getting-started.html#building-a-context), and every entry it logs carries them. In a web app, [call `clear_contextvars()` at the start of each request](https://www.structlog.org/en/latest/contextvars.html), then `bind_contextvars()` for values like a request ID. Render [pretty, colored output during development and JSON in production](https://www.structlog.org/en/latest/logging-best-practices.html#pretty-printing-vs-structured-output), since log aggregators parse JSON more easily. structlog can also [wrap the standard library's logging and add structure to it](https://www.structlog.org/en/latest/getting-started.html#structlog-and-standard-librarys-logging), so an app already built on logging keeps it.
|
||||
|
||||
Loguru has [one logger, ready to use](https://loguru.readthedocs.io/en/latest/overview.html#ready-to-use-out-of-the-box-without-boilerplate) after `from loguru import logger`, and it writes to stderr out of the box. Instead of handlers, formatters, and filters, you configure it with [one function, `add()`](https://loguru.readthedocs.io/en/latest/overview.html#no-handler-no-formatter-no-filter-one-function-to-rule-them-all). In an app, [call `remove()` first](https://loguru.readthedocs.io/en/latest/resources/troubleshooting.html#how-do-i-create-and-configure-a-logger) to drop the default handler, then `add()` where your logs should go. Given a file path, `add()` handles [rotation, retention, and compression](https://loguru.readthedocs.io/en/latest/overview.html#easier-file-logging-with-rotation-retention-compression), and [`serialize=True`](https://loguru.readthedocs.io/en/latest/overview.html#structured-logging-as-needed) turns each message into JSON. In a library, [call `disable()` instead of `add()`](https://loguru.readthedocs.io/en/latest/overview.html#suitable-for-scripts-and-libraries), and the app using it can `enable()` your logs again.
|
||||
|
||||
Whichever you pick, configure logging once, where your app starts, and have each module only get its logger. With the standard library, usually [only the root logger needs configuring](https://docs.python.org/3/library/logging.html), since module loggers pass their messages up to it. structlog wants [`structlog.configure()` on app initialization](https://www.structlog.org/en/latest/configuration.html), and with Loguru, [your other modules inherit the configuration](https://loguru.readthedocs.io/en/latest/resources/troubleshooting.html#how-do-i-create-and-configure-a-logger) from your entry point. Third-party packages that use the standard library's logging keep logging there. Send their messages to your output too: structlog [formats them with `ProcessorFormatter`](https://www.structlog.org/en/latest/standard-library.html#processor-formatter), and Loguru [intercepts them with a handler](https://loguru.readthedocs.io/en/latest/overview.html#entirely-compatible-with-standard-logging).
|
||||
Reference in New Issue
Block a user