"""Example 1
In this example we just create a root logger with no configuration, and log to that root logger, to see what happens.
Note: as I mentioned in the concepts video, we do not normally log to the root logger, but here I just want to show you
the default configuration for the root logger, as well as the "last resort" functionality.
The default configuration for the root logger is a WARNING level, and no handlers, with last resort turned on.
"""
import logging
# With last resort on (the default)
logger = logging.getLogger()
# Inspect root logger configuration
print(f"{logger.hasHandlers()=}")
print(f"{logger.getEffectiveLevel()=}, {logging.WARNING=}")
Running Result:
/Users/egonever/DjangoByExamples/mysite/logging_demystified/example1.py
logger.hasHandlers()=False
logger.getEffectiveLevel()=30, logging.WARNING=30
Process finished with exit code 0
The root logger has no handlers, with an effective level of 30 (WARNING level).
When no handlers are attached to the root logger, the logging library resorts to using a last-resort handler. This handler simply outputs the logging message to the console as a fallback when no other handlers are available.
添加如下代码[code block 2]:
# Send various level log messages to the root logger
logger.debug("This is a debug message")
logger.info("This is an info message")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")
Running Result:
/Users/egonever/DjangoByExamples/mysite/logging_demystified/example1.py
This is a warning message
This is an error message
This is a critical message
logger.hasHandlers()=False
logger.getEffectiveLevel()=30, logging.WARNING=30
Process finished with exit code 0
We received warning, error, and critical messages because our root logger is set to WARNING level, meaning we only capture warning-level logs and above—specifically warning, error, and critical in this case.
替换[code block 2]为如下代码:
# Turn off last resort handler:
logging.lastResort = False
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")
Running Result:
/Users/egonever/DjangoByExamples/mysite/logging_demystified/example1.py
No handlers could be found for logger "root"
logger.hasHandlers()=False
logger.getEffectiveLevel()=30, logging.WARNING=30
Process finished with exit code 0
Now we disabled the last resort handler. The behavior changes slightly - our application continues running without exceptions -- logging failures shouldn't crash your application, even if logging encounters issues, your app should keep running.
With no handlers attached to the root logger and the last resort handler turned off, we only received a single message despite making three logging calls. Since the default level is WARNING, we'd normally expect WARNING messages and higher, but instead we just see one console message indicating: "No handlers could be found for logger 'root'."
Okay, this example demonstrates how to obtain the root logger. You can inspect loggers to check their handlers and effective levels.
总结:
logging.lastResort
是 Python logging
模块(3.2及以上版本)提供的一个兜底的、未格式化的 StreamHandler
,仅在完全没有配置任何有效处理器的情况下,将 WARNING
及以上级别的日志消息原始内容输出至 sys.stderr
。它的存在是为了避免关键错误信息被完全忽略,但它简陋的输出形式表明开发者应当进行正确的日志配置而非依赖它。
Check the documentation, there's a lot of other things that you can inspect on your existing loggers. logging — Logging facility for Python — Python 3.13.5 documentationSource code: Lib/logging/__init__.py Important: This page contains the API reference information. For tutorial information and discussion of more advanced topics, see Basic Tutorial, Advanced Tutor...https://docs.python.org/3/library/logging.html#logging-levels
Original source: https://www.youtube.com/watch?v=-YelOky3ZRE&t=168shttps://www.youtube.com/watch?v=-YelOky3ZRE&t=168s