以下是 Python 中 logging
库的详细介绍,包含基础到进阶的完整用法:
一、核心组件
组件 | 作用 | 特点 |
---|---|---|
Logger | 记录日志的入口对象 | 支持分级(DEBUG/INFO等) |
Handler | 控制日志输出目标(文件/控制台) | 可多路分发 |
Filter | 过滤特定日志 | 细粒度控制 |
Formatter | 定义日志格式 | 支持时间/文件名等变量 |
LogRecord | 自动生成的日志记录对象 | 包含调用位置等信息 |
二、基础使用
1. 快速入门
import logging
# 默认输出到控制台
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug("调试信息") # 输出:DEBUG:__main__:调试信息
logger.info("状态通知") # 输出:INFO:__main__:状态通知
logger.warning("潜在问题") # 输出:WARNING:__main__:潜在问题
以下是 Python 中 logging
库的详细介绍,包含基础到进阶的完整用法:
一、核心组件
组件 | 作用 | 特点 |
---|---|---|
Logger | 记录日志的入口对象 | 支持分级(DEBUG/INFO等) |
Handler | 控制日志输出目标(文件/控制台) | 可多路分发 |
Filter | 过滤特定日志 | 细粒度控制 |
Formatter | 定义日志格式 | 支持时间/文件名等变量 |
LogRecord | 自动生成的日志记录对象 | 包含调用位置等信息 |
二、基础使用
1. 快速入门
import logging
# 默认输出到控制台
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug("调试信息") # 输出:DEBUG:__main__:调试信息
logger.info("状态通知") # 输出:INFO:__main__:状态通知
logger.warning("潜在问题") # 输出:WARNING:__main__:潜在问题
2. 日志等级
等级 | 数值 | 触发条件 |
---|---|---|
DEBUG | 10 | 调试详细信息 |
INFO | 20 | 确认程序按预期运行 |
WARNING | 30 | 表明潜在问题(默认等级) |
ERROR | 40 | 严重错误,影响部分功能 |
CRITICAL | 50 | 致命错误,程序可能崩溃 |
三、高级配置
1. 多Handler配置
logger = logging.getLogger("app")
logger.setLevel(logging.DEBUG)
# 文件Handler(每天轮换)
file_handler = logging.handlers.TimedRotatingFileHandler(
"app.log", when="midnight", backupCount=7
)
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
# 控制台Handler
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
logger.addHandler(file_handler)
logger.addHandler(console_handler)
2. 格式定制
formatter = logging.Formatter(
"[%(asctime)s] [%(levelname)8s] [%(filename)s:%(lineno)d] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
handler.setFormatter(formatter)
可用字段:
%(name)s
Logger名称%(pathname)s
完整路径%(module)s
模块名%(funcName)s
函数名%(thread)d
线程ID
四、实用技巧
1. 异常记录
try:
1 / 0
except Exception as e:
logger.exception("发生异常: ") # 自动附加堆栈信息
# 等效于 logger.error("发生异常", exc_info=True)
2. 日志过滤
class ThresholdFilter(logging.Filter):
def filter(self, record):
return record.msg.startswith("IMPORTANT") # 只保留重要日志
logger.addFilter(ThresholdFilter())
3. 文件轮换
from logging.handlers import RotatingFileHandler
# 每个文件最大10MB,保留3个备份
handler = RotatingFileHandler("app.log", maxBytes=10 * 1024 * 1024, backupCount=3)
五、性能优化
1. 惰性求值
# 避免先拼接字符串(无论是否记录)
logger.debug("数据详情: %s", expensive_data_generator())
2. 异步日志
from concurrent.futures import ThreadPoolExecutor
class AsyncHandler(logging.Handler):
def __init__(self, target_handler):
super().__init__()
self.executor = ThreadPoolExecutor(max_workers=1)
self.target_handler = target_handler
def emit(self, record):
self.executor.submit(self.target_handler.emit, record)
六、常见问题
1. 重复日志
原因:多次调用basicConfig
或多次添加Handler
解决:
logger.propagate = False # 阻止向父Logger传播
2. 多进程日志
使用QueueHandler
和QueueListener
:
import multiprocessing
from logging.handlers import QueueHandler, QueueListener
log_queue = multiprocessing.Queue()
listener = QueueListener(log_queue, handler)
listener.start()
def worker():
qh = QueueHandler(log_queue)
logger = logging.getLogger()
logger.addHandler(qh)
七、最佳实践
-
模块化日志:每个模块使用独立Logger
logger = logging.getLogger(__package__ + ".database")
2.动态配置:通过字典配置(Python 3.2+)
config = {
'version': 1,
'formatters': {'detailed': {'format': '%(asctime)s %(message)s'}},
'handlers': {'file': {'class': 'logging.FileHandler',
'filename': 'app.log',
'formatter': 'detailed'}},
'root': {'level': 'INFO', 'handlers': ['file']}
}
logging.config.dictConfig(config)
3. 第三方集成:
- 使用
structlog
增强结构化日志 - 结合
Sentry
实现错误监控
八、扩展工具
工具 | 功能 |
---|---|
loguru | 更简洁的API设计 |
json-logging | 生成JSON格式日志 |
watchtower | 直接写入AWS CloudWatch |