Python logging模块核心机制与实战配置指南

山间有风
山间有风
发布时间:2026-10-13| 4人浏览过
原创

本文深入解析Python logging模块的核心组件,包括Logger、Formatter、Handler及Filter的作用与配置方法。详细阐述日志等级数值与名称映射机制,演示如何通过配置文件实现个性化日志输出,并提供封装好的Logger工具类代码。同时指出logging模块在多线程环境下的安全性及多进程写日志的潜在风险,帮助开发者构建稳定可靠的日志系统。

1. logging 简介

Python内置的logging包提供了一套通用的日志记录系统,便于第三方模块或应用程序集成使用。该模块支持多种日志级别,并允许通过文件、HTTP GET/POST请求、SMTP邮件、Socket连接等多种方式记录日志,甚至支持用户自定义日志记录后端。

logging包内部定义了Logger、Formatter、Handler和Filter等核心类,此外还包含用于配置管理的config模块。

Logger是日志记录的核心对象,直接提供记录日志的操作接口。

Formatter负责定义日志输出的格式及具体内容。

Handler决定日志写入的目标位置,例如保存为本地文件、按小时分割生成新日志文件,或通过Socket传输至其他服务器。Python提供了十几种实用的Handler,常用的包括StreamHandler、BaseRotatingHandler、SocketHandler、DatagramHandler和SMTPHandler等。通过Logger对象的addHandler()方法,可以将日志输出到多个不同的目的地。

2. Logging package

在Python编程中引入Logging package后,系统中会存在一个名为root的Logging对象,以及众多其他命名的Logging对象。不同Logger对象的Handler和Formatter配置是相互独立的。

(1)logging.getLogger():若调用getLogger()时不带参数,则返回名为root的Logger对象;若传入参数,则返回以该参数为名称的Logger对象。相同名称的Logger对象指向同一实例。

(2)logging.basicConfig():此方法专门用于配置名为root的Logger对象。

(3)logging.info()、logging.debug()等方法默认使用root Logger对象进行信息输出。若需使用其他命名的Logging对象输出日志,可通过logging.getLogger(name).info()来实现。

(4)日志的等级

CRITICAL = 50 
ERROR = 40 
WARNING = 30 
INFO = 20 
DEBUG = 10 
NOTSET = 0 

Python中定义了0、10、20、30、40、50这6个等级数值,分别对应一个字符串常量作为等级名称(如上述代码所示)。但可以通过logging.addLevelName(20, "NOTICE:")方法修改这种映射关系,从而定制化日志等级名称。

通过Logger对象的setLevel()方法,可以配置Logging对象的默认日志等级。只有当一条日志的等级数值大于或等于该默认等级时,才会被输出到日志文件中。

当使用logging.info(msg)输出日志时,内部封装会使用数字20作为日志等级数值。默认情况下,20对应的是INFO,但如果通过addLevelName()修改了20对应的等级名称,那么日志中打印的将是个性化的等级名称。

3. logging包使用配置文件

在1~2节描述的案例中,对Logger对象的Handler、Formatter等配置均在程序中定义或绑定。实际上,Logging的个性化配置可以移至配置文件中,以实现更灵活的管理。

logging的配置文件举例如下:

[loggers] 
keys=root,simpleExample 
 
[handlers] 
keys=consoleHandler 
 
[formatters] 
keys=simpleFormatter 
 
[logger_root] 
level=DEBUG 
handlers=consoleHandler 
 
[logger_simpleExample] 
level=DEBUG 
handlers=consoleHandler 
qualname=simpleExample 
propagate=0 
 
[handler_consoleHandler] 
class=StreamHandler 
level=DEBUG 
formatter=simpleFormatter 
args=(sys.stdout,) 
 
[formatter_simpleFormatter] 
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s 
datefmt= 

对应程序为:

import logging  
import logging.config  
  
logging.config.fileConfig("logging.conf")  # 采用配置文件   
  
# create logger   
logger = logging.getLogger("simpleExample")  
  
# "application" code   
logger.debug("debug message")  
logger.info("info message")  
logger.warn("warn message")  
logger.error("error message")  
logger.critical("critical message") 

4.一个常用的Logging封装工具

#!/usr/bin/env python 
#-*- coding:utf-8 -*- 
#coding=utf-8 
 
import logging 
import os 
 
class Logger(object): 
  """ 
  封装好的Logger工具 
  """ 
 
  def __init__(self, logPath): 
    """ 
    initial 
    """ 
    log_path = logPath 
    logging.addLevelName(20, "NOTICE:") 
    logging.addLevelName(30, "WARNING:") 
    logging.addLevelName(40, "FATAL:") 
    logging.addLevelName(50, "FATAL:") 
    logging.basicConfig(level=logging.DEBUG, 
        format="%(levelname)s %(asctime)s [pid:%(process)s] %(filename)s %(message)s", 
        datefmt="%Y-%m-%d %H:%M:%S", 
        filename=log_path, 
        filemode="a") 
    console = logging.StreamHandler() 
    console.setLevel(logging.DEBUG) 
    formatter = logging.Formatter("%(levelname)s [pid:%(process)s] %(message)s") 
    console.setFormatter(formatter) 
    logging.getLogger("").addHandler(console) 
 
  def debug(self, msg=""): 
    """ 
    output DEBUG level LOG 
    """ 
    logging.debug(str(msg)) 
 
  def info(self, msg=""): 
    """ 
    output INFO level LOG 
    """ 
    logging.info(str(msg)) 
 
  def warning(self, msg=""): 
    """ 
    output WARN level LOG 
    """ 
    logging.warning(str(msg)) 
 
  def exception(self, msg=""): 
    """ 
    output Exception stack LOG 
    """ 
    logging.exception(str(msg)) 
 
  def error(self, msg=""): 
    """ 
    output ERROR level LOG 
    """ 
    logging.error(str(msg)) 
 
  def critical(self, msg=""): 
    """ 
    output FATAL level LOG 
    """ 
    logging.critical(str(msg)) 
   
 
if __name__ == "__main__": 
  testlog = Logger("oupput.log") 
  testlog.info("info....") 
  testlog.warning("warning....") 
  testlog.critical("critical....") 
  try: 
    lists = [] 
    print lists[1] 
  except Exception as ex: 
    """logging.exception()输出格式: 
    FATAL: [pid:7776] execute task failed. the exception as follows: 
    Traceback (most recent call last): 
      File "logtool.py", line 86, in <module> 
        print lists[1] 
    IndexError: list index out of range 
    """ 
    testlog.exception("execute task failed. the exception as follows:") 
    testlog.info("++++++++++++++++++++++++++++++++++++++++++++++") 
    """logging.error()输出格式: 
    FATAL: [pid:7776] execute task failed. the exception as follows: 
    """ 
    testlog.error("execute task failed. the exception as follows:") 
    exit(1)

备注:exception()方法能够完整打印异常的堆栈信息。而error()方法仅打印参数传入的信息。

备注:

按照官方文档介绍,logging是线程安全的,即在一个进程内的多个线程同时向同一个文件写入日志是安全的。但是,多个进程向同一个文件写入日志是不安全的。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。