1. logging日志处理
1.1. logging库日志级别
|----------|----------|---------------------------|
| 级别 | 级别数值 | 使用时机 |
| DEBUG | 10 | 详细信息,常用于调试。 |
| INFO | 20 | 程序正常运行过程中产生的一些信息。 |
| WARNING | 30 | 警告用户,虽然程序还在正常工作,但有可能发生错误。 |
| ERROR | 40 | 由于更严重的问题,程序已不能执行一些功能了。 |
| CRITICAL | 50 | 严重错误,程序已不能继续运行。 |
-
默认的日志级别为warning
import logging
默认是warning级别的输出
logging.debug("This is a debug message")
logging.info("This is an info message")
logging.warning("This is a warning message")
logging.error("This is an error message")
logging.critical("This is a critical message")

baseconfig()方法:
(1) 设置日志级别
import logging
# 默认是warning级别的输出
# 使用baseconfig()方法设置级别
logging.basicConfig(level=logging.DEBUG)
logging.debug("This is a debug message")
logging.info("This is an info message")
logging.warning("This is a warning message")
logging.error("This is an error message")
logging.critical("This is a critical message")

(2) 将日志保存到文件系统
logging.basicConfig(level=logging.DEBUG,filemode='w',filename='debug.log')

filemode = 'a':追加filemode = 'w':写入
(3) 向日志输出变量
import logging
# 默认是warning级别的输出
# 使用baseconfig()方法设置级别
logging.basicConfig(level=logging.DEBUG,filemode='w',filename='debug.log')
logging.debug("姓名:%s,年龄:%d","张三",18)
logging.debug("姓名:{},年龄:{}".format("张三",18))
logging.debug(f"姓名:{'张三'},年龄:{18}")
1.2. 输出时间
logging 日志专用的格式化语法,和字符串格式化是同一个意思:
-
%(asctime)s→ 时间 -
%(levelname)s→ 日志级别 -
%(filename)s→ 文件名 -
%(lineno)s→ 行号 -
%(message)s→ 你输出的日志内容-- coding: utf-8 --
import logging
%()s
logging.basicConfig(
format="%(asctime)s|%(levelname)s|%(filename)s|%(lineno)s|%(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
level=logging.DEBUG # 设置级别
)name = "张三"
age = 18正确:小写 debug
logging.debug(f"姓名:{name},年龄:{age}")
1.3. 高级应用:Loggers
Loggers:记录器,提供应用程序代码能直接使用的接口

1. 提供应用程序的调用接口
-
核心代码:
import logging
logger = logging.getLogger(name) -
关键特性:
-
logger是单例模式:同一个名称的 Logger 在整个程序中只会创建一个实例,避免重复配置和日志重复输出。__name__是 Python 内置变量,代表当前模块名,用它命名 Logger 可以精准区分不同模块的日志来源。
- 使用场景 :在代码中通过
logger.debug()、logger.info()等方法记录日志。
2. 决定日志记录的级别
-
核心代码:
logger.setLevel(logging.DEBUG)
-
作用:
-
- 设置 Logger 的最低日志级别,只有级别≥当前设置的日志才会被处理。
- 例如设置为
DEBUG时,DEBUG/INFO/WARNING/ERROR/CRITICAL级别的日志都会被传递;若设置为INFO,则DEBUG级别的日志会被直接过滤。
- 优先级:Logger 的级别会优先于 Handler 的级别,是日志过滤的第一道关卡。
3. 将日志内容传递到关联的 Handlers 中
-
核心代码:
添加处理器
logger.addHandler(file_handler)
logger.addHandler(console_handler)移除处理器
logger.removeHandler(console_handler)
-
作用:
-
- 通过
addHandler()绑定一个或多个处理器(Handler),让 Logger 产生的日志可以同时输出到多个目的地(比如控制台 + 文件)。 - 通过
removeHandler()可以解绑不再需要的处理器,灵活控制日志输出渠道。
- 通过
- 流程:Logger 过滤后的日志,会被分发到所有绑定的 Handlers 中,再由 Handlers 完成最终的输出。
1.4. 高级应用:Handlers
核心作用:负责将记录器产生的日志发送到指定目的地。
1. StreamHandler(流处理器)
-
核心作用 :将日志输出到标准输出流(stdout,如控制台 / 显示器),适合开发调试时实时查看日志。
-
创建语法:
import logging
sh = logging.StreamHandler(stream=None) -
stream参数:指定输出流,默认None表示使用sys.stdout(控制台)。
- 典型场景:开发阶段,快速查看日志输出,不需要持久化到文件。
2. FileHandler(文件处理器)
-
核心作用 :将日志持久化保存到磁盘文件中,适合生产环境留存日志记录。
-
创建语法:python运行
fh = logging.FileHandler(
filename, # 日志文件名(含路径)
mode='a', # 文件打开模式:'a'=追加写入,'w'=覆盖写入
encoding=None,# 文件编码(推荐设为 'utf-8' 避免中文乱码)
delay=False # 是否延迟打开文件,True 表示第一次 emit 时才打开
) -
关键参数说明:
-
mode='a':默认追加模式,不会覆盖之前的日志内容,生产环境推荐使用。encoding='utf-8':必须显式指定,否则中文日志可能出现乱码。
3. setFormatter ():绑定格式化器
-
核心作用:为 Handler 设置日志的输出格式,决定日志最终的展示结构。
-
使用示例:python运行
创建格式化器
formatter = logging.Formatter("%(asctime)s|%(levelname)s|%(message)s")
为处理器绑定格式化器
sh.setFormatter(formatter)
fh.setFormatter(formatter) -
注意:每个 Handler 可以绑定独立的 Formatter,实现 "控制台和文件输出不同格式日志" 的需求。
日志级别 ≥ logger 级别 并且 日志级别 ≥ handler 级别 才会输出
1.5. 高级应用:Formatter
Formatter 是 Python logging 模块中最终决定日志输出结构的组件,负责定义日志的顺序、字段和格式。
1. 构造方法解析
ft = logging.Formatter(fmt=None, datefmt=None, style='%')
|-----------|------------------------------------|-----------------------------------------------|
| 参数 | 作用 | 默认值 |
| fmt | 日志格式字符串,定义日志包含的字段(如 %(asctime)s) | None(默认仅输出日志内容) |
| datefmt | 时间字段 %(asctime)s的格式字符串 | %Y-%m-%d %H:%M:%S (如 2026-03-26 15:30:00) |
| style | 格式化语法风格,可选 %/{/$ | % |
2. 关键参数详解
- datefmt**(时间格式)**
-
-
默认格式:
%Y-%m-%d %H:%M:%S(年 - 月 - 日 时:分: 秒) -
自定义示例:
时间格式改为:年/月/日 时:分
formatter = logging.Formatter("%(asctime)s|%(message)s", datefmt="%Y/%m/%d %H:%M")
-
-
style**(语法风格)**
-
style='%':默认旧式%()语法,如%(asctime)s|%(levelname)sstyle='{':支持str.format()语法,如{asctime}|{levelname}style='$':支持string.Template语法,如${asctime}|${levelname}
3. 完整使用示例
# -*- coding: utf-8 -*-
import logging
# 1. 创建记录器并设置日志级别
logger = logging.getLogger('applog')
logger.setLevel(logging.DEBUG)
# 2. 控制台处理器
consolehandler = logging.StreamHandler()
consolehandler.setLevel(logging.DEBUG)
# 3. 文件处理器(使用 logger 的级别)
fh = logging.FileHandler(filename='appDemo.log', encoding='utf-8', mode='a')
# 4. 日志格式
formatter = logging.Formatter(
"%(asctime)s|%(levelname)8s|%(filename)s|%(lineno)s|%(message)s"
)
# 5. 给两个处理器都设置格式 ✅
consolehandler.setFormatter(formatter)
fh.setFormatter(formatter)
# 6. 把处理器添加到记录器
logger.addHandler(consolehandler)
logger.addHandler(fh)
# ------------------- 正确输出日志 -------------------
# 三种格式化方式都正确
logger.debug("姓名:%s,年龄:%d", "张三", 18)
logger.debug("姓名:{},年龄:{}".format("张三", 18))
logger.debug(f"姓名:{'张三'},年龄:{18}")
1.6. 高级应用:Filters
只有日志来源(logger 名称)以 cn.cccb****开头的日志,才会被输出!不是这个来源的日志,全部被过滤掉,不输出!
# 7. 定义一个过滤器
filter = logging.Filter("cn.cccb")
logger.addFilter(filter)
1.7. 高级应用:配置文件
#./logging.conf
#记录器:提供应用程序代码直接使用的接口
#设置记录器名称,root必须存在!!!
[loggers]
keys=root,applog
#处理器,将记录器产生的日志发送至目的地
#设置处理器类型
[handlers]
keys=fileHandler,consoleHandler
#格式化器,设置日志内容的组成结构和消息字段
#设置格式化器的种类
[formatters]
keys=simpleFormatter
#设置记录器root的级别与种类
[logger_root]
level=DEBUG
handlers=consoleHandler
#设置记录器applog的级别与种类
[logger_applog]
level=DEBUG
handlers=fileHandler,consoleHandler
#起个对外的名字
qualname=applog
#继承关系
propagate=0
#设置
[handler_consoleHandler]
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter
[handler_fileHandler]
class=handlers.TimedRotatingFileHandler
#在午夜1点(3600s)开启下一个log文件,第四个参数0表示保留历史文件
args=('applog.log','midnight',3600,0)
level=DEBUG
formatter=simpleFormatter
[formatter_simpleFormatter]
format=%(asctime)s|%(levelname)8s|%(filename)s[:%(lineno)d]|%(message)s
#设置时间输出格式
datefmt=%Y-%m-%d %H:%M:%S