logging 日志模块笔记

一、logging 介绍

logging 是 Python 标准库中的一个模块,它提供了灵活的日志记录功能。

主要特点:

  • 可以方便地将日志信息输出到控制台、文件、网络等多种目标

  • 支持不同级别的日志记录,满足不同场景下的需求

  • 是标准库,无需额外安装


二、日志级别

日志级别从低到高(金字塔结构):

级别 数值 说明
DEBUG 10 调试信息,最详细
INFO 20 一般信息
WARNING 30 警告信息(默认级别)
ERROR 40 错误信息
CRITICAL 50 严重错误

规则: 只有高于或等于设定级别的日志才会被处理

复制代码
DEBUG < INFO < WARNING < ERROR < CRITICAL
(低)                                           (高)

三、基本使用

示例1:全局 logging 基本配置
复制代码
import logging
​
logging.basicConfig(level=logging.INFO)
​
logging.debug('This is a debug message')    # 不会输出(级别低于INFO)
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:自定义 logger 并输出到控制台
复制代码
import logging
​
# 基本配置
logging.basicConfig(level=logging.INFO)
​
# 获取一个日志记录器对象,名称为当前模块的名称
logger = logging.getLogger(__name__)
​
# 设置日志记录器的级别为 DEBUG
logger.setLevel(logging.DEBUG)
​
if __name__ == "__main__":
    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('This is a critical message')
示例3:自定义 logger 并输出到日志文件
复制代码
import logging
​
# 获取日志记录器对象
logger = logging.getLogger(__name__)
​
# 设置日志级别
logger.setLevel(logging.DEBUG)
​
# 创建 FileHandler 对象,指定日志文件名
handler = logging.FileHandler(filename="test.log")
​
# 将处理器添加到日志记录器
logger.addHandler(handler)
​
if __name__ == "__main__":
    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('This is a critical message')

输出结果(test.log 文件内容):

复制代码
This is a debug message
This is an info message
This is a warning message
This is an error message
This is a critical message

四、核心组件说明

组件 说明
Logger 日志记录器,负责生成日志。通过 logging.getLogger(name) 获取
Handler 处理器,决定日志输出到哪里(文件、控制台等)
Formatter 格式器,定义日志的输出格式
Filter 过滤器,决定哪些日志需要输出

五、设置日志格式(Formatter)

复制代码
import logging
​
# 获取日志记录器
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
​
# 创建文件处理器
handler = logging.FileHandler(filename="test.log")
​
# 创建格式器
formatter = logging.Formatter(
    "%(asctime)s %(levelname)s [%(name)s] [%(filename)s (%(funcName)s:%(lineno)d)] - %(message)s"
)
​
# 将格式器设置到处理器上
handler.setFormatter(formatter)
​
# 添加处理器到日志记录器
logger.addHandler(handler)
​
if __name__ == "__main__":
    logger.debug('This is a debug message')

输出结果示例:

复制代码
2025-01-06 19:17:42,753 DEBUG [__main__] [test.py (<module>:13)] - This is a debug message

六、格式占位符详解

占位符 说明
%(asctime)s 日志记录的时间戳
%(levelname)s 日志级别(DEBUG、INFO、WARNING、ERROR、CRITICAL)
%(name)s 日志记录器的名称
%(filename)s 日志记录发生的文件名
%(funcName)s 日志记录发生的函数名
%(lineno)d 日志记录发生的行号
%(message)s 日志消息本身

七、高级用法:多处理器 + 日志分离

在接口自动化测试项目中,通常需要将不同级别的日志输出到不同文件:

复制代码
import logging
import os
import time
​
class InfoFilter(logging.Filter):
    """只过滤 INFO 级别的日志"""
    def filter(self, record):
        return record.levelno == logging.INFO
​
class ErrorFilter(logging.Filter):
    """只过滤 ERROR 级别的日志"""
    def filter(self, record):
        return record.levelno == logging.ERROR
​
class Logger:
    logger = None
    
    @classmethod
    def getlog(cls):
        if cls.logger is None:
            # 创建 logger
            cls.logger = logging.getLogger(__name__)
            cls.logger.setLevel(logging.DEBUG)
            
            # 创建日志目录
            now = time.strftime("%Y-%m-%d")
            LOG_PATH = 'logs'
            if not os.path.exists(LOG_PATH):
                os.mkdir(LOG_PATH)
            
            # 定义日志文件路径
            info_log_name = LOG_PATH + now + '_info.log'
            error_log_name = LOG_PATH + now + '_error.log'
            log_name = LOG_PATH + now + '.log'
            
            # 创建 handler(所有日志)
            handler = logging.FileHandler(log_name, encoding="utf-8")
            handler.setLevel(logging.INFO)
            
            # 创建 info handler(仅 INFO 级别)
            info_handler = logging.FileHandler(info_log_name, encoding="utf-8")
            info_handler.setLevel(logging.INFO)
            info_handler.addFilter(InfoFilter())
            
            # 创建 error handler(仅 ERROR 级别)
            error_handler = logging.FileHandler(error_log_name, encoding="utf-8")
            error_handler.setLevel(logging.ERROR)
            error_handler.addFilter(ErrorFilter())
            
            # 设置格式器
            formatter = logging.Formatter(
                "%(asctime)s %(levelname)s [%(name)s] [%(filename)s (%(funcName)s:%(lineno)d)] - %(message)s"
            )
            handler.setFormatter(formatter)
            info_handler.setFormatter(formatter)
            error_handler.setFormatter(formatter)
            
            # 添加处理器
            cls.logger.addHandler(handler)
            cls.logger.addHandler(info_handler)
            cls.logger.addHandler(error_handler)
            
        return cls.logger

效果:

  • 2024-12-20.log:记录所有 INFO 及以上级别的日志

  • 2024-12-20_info.log:只记录 INFO 级别的日志

  • 2024-12-20_error.log:只记录 ERROR 级别的日志


八、在接口自动化框架中的实际应用

复制代码
# utils/request_util.py
from utils.logger_util import Logger

class Request:
    def __init__(self):
        self.logger = Logger.getlog()
    
    def get(self, url, **kwargs):
        self.logger.info('准备开始发起get请求, url:' + url)
        self.logger.info('接口信息是:{}'.format(kwargs))
        s = requests.get(url, **kwargs)
        self.logger.info('接口响应状态码:{}'.format(s.status_code))
        self.logger.info('接口响应内容是:{}'.format(s.text))
        return s
    
    def post(self, url, **kwargs):
        self.logger.info('准备开始发起post请求, url:' + url)
        self.logger.info('接口信息是:{}'.format(kwargs))
        s = requests.post(url, **kwargs)
        self.logger.info('接口响应状态码是:{}'.format(s.status_code))
        self.logger.info('接口响应内容是:{}'.format(s.text))
        return s

九、总结对比

特性 普通 print logging
日志级别控制 ❌ 不支持 ✅ 支持(DEBUG/INFO/WARNING/ERROR/CRITICAL)
输出目标 仅控制台 文件、控制台、网络等
格式定制 手动拼接 Formatter 灵活配置
持久化 ❌ 不保存 ✅ 保存到文件
生产环境 不推荐 ✅ 推荐
调试信息 手动添加 自动记录文件名、行号、函数名

十、快速上手模板

复制代码
import logging

# 1. 创建 logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# 2. 创建 handler(控制台 + 文件)
console_handler = logging.StreamHandler()
file_handler = logging.FileHandler('test.log', encoding='utf-8')

# 3. 创建 formatter
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

# 4. 添加 handler
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# 5. 使用
logger.debug("调试信息")
logger.info("一般信息")
logger.warning("警告信息")
logger.error("错误信息")
相关推荐
cqbelt2 小时前
Python 并发编程实战学习笔记
笔记·python·学习
智算菩萨2 小时前
【论文复现】Applied Intelligence 2025:Auto-PU正例无标签学习的自动化实现与GPT-5.4辅助编程实战
论文阅读·python·gpt·学习·自动化·复现
小陈工3 小时前
2026年3月31日技术资讯洞察:AI智能体安全、异步编程突破与Python运行时演进
开发语言·jvm·数据库·人工智能·python·安全·oracle
老李的勺子3 小时前
Agent 记忆失效的 5 种方式:完整排查复盘
python·llm
Leo655354 小时前
动态透视报表 + 查询接口 + Excel导出
开发语言·windows·python
清水白石0084 小时前
pytest Fixture 设计实战指南:作用域、依赖链、自动清理与测试资源高效复用
python·pytest
tottoramen4 小时前
如何安装龙虾
python
QC·Rex4 小时前
AI Agent 任务规划实战:从 ReAct 到 Plan-and-Solve 的完整指南
人工智能·python·react
kcuwu.5 小时前
Python面向对象:封装、继承、多态
开发语言·python