目录:
logging 模块的架构基于四个核心组件,它们协同工作以完成日志的记录与输出。
工作流程是:开发者调用 Logger 方法 → Logger 根据自身级别判断是否处理该日志 → 日志记录通过可选的 Filter → 被传递给所有附加的 Handler → 每个 Handler 根据自身级别和 Formatter 的格式,将日志输出到其目标位置。
每个Logger对象都有一个名称,通常与模块名(__name__)相关联,开发者通过调用Logger的方法(如 logger.debug()、logger.info())来产生日志记录。
将Logger产生的日志记录发送到指定的目的地。可以将同一条日志同时输出到控制台和文件等不同位置。
决定了日志记录的最终输出格式。
可以指定日志信息中包含哪些内容,如时间戳、日志级别、模块名、行号以及具体的消息等。开发者可以通过格式化字符串自定义输出样式。
可以基于Logger名称、日志级别或其他自定义条件来决定是否让某条日志记录通过。
INFO 级别用的最多。
对于简单的脚本,可以使用 logging.basicConfig() 进行一次性全局配置。这个函数会为根(root)Logger设置一个默认的Handler(通常是StreamHandler)。
logging.basicConfig() 只在第一次调用时生效。通常应在程序入口(如主函数开始处)进行配置。
import logging
# 基础配置:设置级别和格式,输出到控制台
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
# 使用根Logger记录日志
logging.debug('这是一条调试信息')
logging.info('这是一条普通信息')
logging.warning('这是一条警告信息')
format参数支持丰富的占位符,例如:
在正式的应用程序或项目中,更推荐创建和配置自定义的 Logger 对象,这样可以获得更精细的控制,并避免模块间的日志冲突。
# logger.py
import logging
def setup_logger(name):
# 1. 创建 Logger 对象,通常以模块名命名
logger = logging.getLogger(name)
# 设置 Logger 的捕获级别
logger.setLevel(logging.DEBUG)
# 可选:防止日志向上传递给父 Logger,避免重复输出
logger.propagate = False
# 2. 创建 Handler:一个输出到控制台,一个输出到文件
console_handler = logging.StreamHandler()
file_handler = logging.FileHandler('app.log', encoding='utf-8')
# 3. 为每个 Handler 设置独立的输出级别
# 控制台只显示 INFO 及以上
console_handler.setLevel(logging.INFO)
# 文件记录所有 DEBUG 及以上的日志
file_handler.setLevel(logging.DEBUG)
# 4. 创建 Formatter 并绑定到 Handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 5. 将 Handler 添加到 Logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)
return logger
在其它文件中使用日志:
# sample.py
from logger import setup_logger
logger = setup_logger(__name__)
def do_something():
logger.info('开始搞点事情...')
对于长期运行的服务,日志文件会不断增长。logging.handlers 提供了 RotatingFileHandler 来自动管理日志文件大小,防止磁盘被占满。
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger(__name__)
# 创建按大小轮转的 Handler,每个文件最大 1MB,保留 3 个备份
file_handler = RotatingFileHandler('app.log', maxBytes=1024*1024, backupCount=3)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
对于长期运行的服务,日志文件会不断增长。logging.handlers 提供了 TimedRotatingFileHandler 来按时间归档,防止磁盘被占满。以下是按天轮转日志示例:
import logging
from logging.handlers import TimedRotatingFileHandler
logger = logging.getLogger(__name__)
# 关键参数说明:
# filename: 日志文件的基础名称(前缀)。
# when: 轮转时间单位。'D'代表天,其他选项包括:'S'(秒), 'M'(分), 'H'(小时), 'W0'-'W6'(周), 'midnight'(每天零点)
# interval: 轮转间隔数。when='D', interval=1 表示每天轮转一次。
# backupCount: 保留的历史日志文件数量。设为 7 表示保留最近 7 天的日志,更早的自动删除
# encoding: 确保日志文件能正确记录中文等非ASCII字符
file_handler = TimedRotatingFileHandler(
filename='app.log',
when='D',
interval=1,
backupCount=7,
encoding='utf-8'
)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s - %(funcName)s - Line %(lineno)d - %(message)s')
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)
↶ 返回首页 ↶