Python进阶(1)- logging

1. logging日志处理

1.1. logging库日志级别

|----------|----------|---------------------------|
| 级别 | 级别数值 | 使用时机 |
| DEBUG | 10 | 详细信息,常用于调试。 |
| INFO | 20 | 程序正常运行过程中产生的一些信息。 |
| WARNING | 30 | 警告用户,虽然程序还在正常工作,但有可能发生错误。 |
| ERROR | 40 | 由于更严重的问题,程序已不能执行一些功能了。 |
| CRITICAL | 50 | 严重错误,程序已不能继续运行。 |


  1. 默认的日志级别为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)s
    • style='{':支持 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
相关推荐
笨鸟先飞,勤能补拙3 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能3 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂4 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study4 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境5 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境5 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1235 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102166 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb006 小时前
一个项目带你入门AI应用开发01
python
0566466 小时前
Python康复训练——常用标准库
开发语言·python·学习