HOWTO · Python
在 Python 中记录到标准输出 stdout
我们可以使用 logging.basicConfig() 和 logging.StreamHandler() 函数在 Python 中记录到标准输出。
本页内容
要将 Python 日志消息发送到标准输出(stdout),请在 logging.basicConfig() 中将 stream 设为 sys.stdout。如需更多控制,可将 logging.StreamHandler(sys.stdout) 添加到日志记录器中。如果要将相同的日志记录同时发送到控制台和文件,请在流处理器旁另设一个 FileHandler。
在 Python 中使用 logging.basicConfig() 将日志输出到 stdout
对于简单的全应用程序配置,logging.basicConfig() 会配置根日志记录器。它的 stream 参数用于选择输出流;默认情况下,日志会写入 sys.stderr。将其设为 sys.stdout,即可把日志记录发送到标准输出。level 用于控制哪些日志记录能通过根日志记录器,format 则用于控制每行输出的格式。
import logging
import sys
logging.basicConfig(
level=logging.INFO,
format="%(levelname)s: %(message)s",
stream=sys.stdout,
)
logging.info("Application started")
INFO: Application started
basicConfig() 是用于配置根日志记录器的一次性便捷方法。如果应用程序的其他部分已经添加了根处理器,之后调用此函数会保留原有设置,因此在这里更改 stream 不会改变输出流。在 Python 3.8 及更高版本中,force=True 会先移除现有的根处理器,再应用此配置。只有当你的代码负责替换应用程序的日志设置时才使用它;否则,应在应用程序入口处一次性配置日志。
filename 和 filemode 选项用于配置文件输出:filename 指定文件名,filemode 控制文件的打开方式,默认以追加模式("a")打开。不要在 basicConfig() 中同时传入 filename 和 stream;在这里应选择一个输出目标。若要将日志记录同时发送到标准输出和文件,请像下文那样使用独立的处理器。另外,只有在根日志记录器尚无处理器时,basicConfig() 才会对其进行配置,除非使用 force=True(Python 3.8 及更高版本提供)。
在 Python 中使用 logging.StreamHandler() 将日志输出到 stdout
如果需要控制具名日志记录器或组合多个输出目标,请使用显式处理器。logging.StreamHandler() 默认将内容写入 sys.stderr,因此要显式传入 sys.stdout。日志记录器级别和处理器级别都会影响哪些记录能够输出;一条记录必须同时通过这两个级别的筛选。此示例创建一个标准输出处理器和一个文件处理器,并将它们都添加到同一个日志记录器中。
import logging
import sys
import tempfile
from pathlib import Path
log_path = Path(tempfile.gettempdir()) / "python-logging-example.log"
logger = logging.getLogger("example")
logger.setLevel(logging.INFO)
logger.propagate = False
formatter = logging.Formatter("%(levelname)s: %(message)s")
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setLevel(logging.INFO)
stdout_handler.setFormatter(formatter)
file_handler = logging.FileHandler(log_path, mode="w", encoding="utf-8")
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
logger.addHandler(file_handler)
logger.info("Application started")
for handler in (stdout_handler, file_handler):
handler.close()
logger.removeHandler(handler)
INFO: Application started
每个处理器都会分别格式化日志记录,并将其写入自己的目标位置。文件会创建在系统临时目录中,而 mode="w" 会在每次运行时覆盖示例文件。在长期运行的应用程序中,应只配置一次处理器,而不要反复添加;重复的处理器可能导致每条记录输出多次。在生产环境中,应根据应用程序管理文件路径和处理器的生命周期。
总结
若要快速配置根日志记录器,请使用 logging.basicConfig() 并将 stream 设为 sys.stdout。如果需要控制具名日志记录器、自定义处理器设置或使用多个输出目标,请选择 logging.StreamHandler(sys.stdout)。未显式指定输出流的 StreamHandler 会将内容写入 stderr;若要同时记录到文件和控制台,则需要分别使用流处理器和文件处理器。