介绍
Python 内置的 logging 是标准日志模块,替代 print(),用于程序调试、问题排查、运行记录,支持分级输出、文件持久化、格式化、多模块复用等核心功能,是生产环境必备工具。
为什么用 logging,不用 print?
| 特性 | print() | logging |
|---|---|---|
| 日志分级 | 无,全部输出 | 5 个级别,可开关 |
| 持久化 | 需手动写文件 | 自动写入文件 |
| 格式美化 | 无 | 时间、级别、模块、行号 |
| 多模块复用 | 不支持 | 全局单例,随处调用 |
| 生产环境 | 禁用麻烦 | 可直接关闭调试日志 |
结论:只要是正式项目,必须用 logging。
日志 5 个级别(从低到高)
DEBUG < INFO < WARNING < ERROR < CRITICAL
- DEBUG:调试细节,开发时用
- INFO:程序正常运行信息(如启动成功)
- WARNING:警告,不影响运行,但需要注意
- ERROR:错误,部分功能失败
- CRITICAL:严重错误,程序可能崩溃
默认级别:WARNING,低于它的日志不会输出。
入门使用
import logging
# 基础配置
logging.basicConfig(level=logging.DEBUG)
# 输出日志
logging.debug("调试信息")
logging.info("普通信息")
logging.warning("警告信息")
logging.error("错误信息")
logging.critical("严重错误")
输出:
DEBUG:root:调试信息
INFO:root:普通信息
WARNING:root:警告信息
ERROR:root:错误信息
CRITICAL:root:严重错误
进阶使用-基本配置
通过 basicConfig 常用参数
logging.basicConfig(
# 1. 日志级别
level=logging.DEBUG,
# 2. 输出到文件(默认控制台)
filename="app.log",
# 3. 写入模式:w=覆盖,a=追加
filemode="a",
# 4. 日志格式(最关键)
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(lineno)d",
# 5. 时间格式
datefmt="%Y-%m-%d %H:%M:%S"
)
常用 format 字段
| 字段 | 含义 |
|---|---|
%(asctime)s |
时间 |
%(name)s |
日志器名称 |
%(levelname)s |
日志级别 |
%(message)s |
日志内容 |
%(lineno)d |
代码行号 |
%(filename)s |
文件名 |
%(module)s |
模块名 |
logging 四大核心组件
logging 不是简单函数,而是模块化设计,由 4 个组件协作:
1. Logger(日志器)
产生日志的入口,全局唯一,可设置级别。
logger = logging.getLogger("my_app") # 命名日志器
logger.setLevel(logging.DEBUG)
2. Handler(处理器)
决定日志输出到哪:
StreamHandler→ 控制台FileHandler→ 文件RotatingFileHandler→ 按大小切分TimedRotatingFileHandler→ 按时间切分(生产常用)
3. Formatter(格式器)
定义日志长什么样。
4. Filter(过滤器)
过滤不需要的日志(极少用)。
高级使用-企业级标准配置
同时输出到控制台 + 文件 + 自动按天切割
import logging
from logging.handlers import TimedRotatingFileHandler
def get_logger():
# 1. 创建日志器
logger = logging.getLogger("my_project")
logger.setLevel(logging.DEBUG) # 全局最低级别
logger.handlers.clear() # 避免重复添加handler
# 2. 日志格式
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
# 3. 控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(formatter)
# 4. 文件处理器(每天生成一个文件,保留 30 天)
file_handler = TimedRotatingFileHandler(
filename="project.log",
when="midnight", # 每天凌晨切割
interval=1,
backupCount=30,
encoding="utf-8"
)
file_handler.setLevel(logging.INFO) # 文件只记录 INFO 及以上
file_handler.setFormatter(formatter)
# 5. 添加处理器
logger.addHandler(console_handler)
logger.addHandler(file_handler)
return logger
# 全局使用
logger = get_logger()
使用:
logger.debug("连接数据库成功")
logger.info("服务启动")
logger.warning("磁盘空间不足")
logger.error("请求接口失败")
多模块使用
只要名字相同,全局共用一个日志器,不用重复配置。
a.py
from log_config import logger
def test():
logger.info("a 模块运行")
b.py
from log_config import logger
def run():
logger.error("b 模块出错")
main.py
import a
import b
from log_config import logger
logger.info("主程序启动")
a.test()
b.run()
所有日志统一输出,不会混乱。
常见问题与坑
1. 日志重复输出
原因:多次 addHandler
解决:每次获取 logger 前清空
logger.handlers.clear()
2. 中文乱码
文件处理器加 encoding="utf-8"
FileHandler("app.log", encoding="utf-8")
3. 日志不输出
检查级别:
logger.setLevel(logging.DEBUG)
handler.setLevel(logging.DEBUG)
使用建议
- 项目 只配置一次 logger,全局复用
- 开发用
DEBUG,生产用INFO - 文件日志用
TimedRotatingFileHandler按天切割 - 格式必须包含:时间、级别、文件名、行号
- 禁止在生产环境用
print()
总结
logging是 Python 标准日志库,功能强大、生产必备- 5 个级别:
DEBUG/INFO/WARNING/ERROR/CRITICAL - 四大组件:
Logger/Handler/Formatter/Filter - 企业用法:控制台 + 按天切割文件 + 统一格式
- 多项目可直接复制我提供的标准配置使用