Python3入门指南Python语言的特点和实际应用Python3环境搭建配置VSCode进行Python开发Python基础语法Python变量与数据类型Python数据类型转换Python解释器使用Python注释使用Python运算符Python数字类型Python字符串操作Python列表操作Python元组使用Python字典使用Python集合使用Python条件控制详解Python循环语句详解Python编程入门实践Python推导式详解Python迭代器和生成器Python with语句详解Python函数详解Python lambda(匿名函数)Python装饰器Python数据结构Python模块和包使用Python中__name__和__main__的用法Python输入输出:从基础到文件操作Python文件操作Python OS模块使用Python错误和异常处理Python面向对象编程Python命名空间和作用域Python虚拟环境:venv详细教程Python类型注解Python标准库常用模块Python正则表达式Python CGI编程Python MySQL(mysql-connector驱动)Python MySQL(PyMySQL驱动)Python网络编程Python发送邮件Python多线程编程Python XML解析Python JSON解析Python日期和时间处理Python操作MongoDBPython urllib库使用Python uWSGI 安装与配置Python pip包管理工具Python operator模块Python math模块Python requests模块HTTP请求Python random模块Python OpenAI库Python AI绘画制作Python statistics模块Python hashlib模块:哈希加密Python量化交易Python pyecharts数据可视化Python Selenium网页自动化Python BeautifulSoup网页数据提取Python Scrapy爬虫框架Python Markdown转HTMLPython sys模块Python Pickle模块:数据存储Python subprocess模块Python queue队列模块Python StringIO内存文件操作Python logging日志记录Python datetime日期时间处理Python re正则表达式Python csv表格数据处理Python threading 多线程编程Python asyncio 异步编程Python PyQt 图形界面开发Python 应用方向和常用库框架

Python logging日志记录

logging模块是Python中专业的日志记录工具。相比简单的print语句,logging提供了更强大、更灵活的日志功能,适合从开发调试到生产部署的各种场景。


为什么需要logging模块

使用logging模块的好处:

  1. 分级记录:不同重要程度的日志可以分开处理

  2. 多种输出:可以同时输出到控制台、文件、网络等

  3. 格式统一:所有日志保持一致的格式

  4. 性能更好:比print更适合生产环境

  5. 方便排查:出现问题时有完整的日志可查


快速开始

基础配置和使用

import logging

# 基本配置
logging.basicConfig(level=logging.INFO)

# 记录不同级别的日志
logging.debug("这是调试信息")    # 不会显示,因为级别是INFO
logging.info("程序启动完成")
logging.warning("内存使用较高")
logging.error("数据库连接失败")
logging.critical("系统即将崩溃")

运行结果:

INFO:root:程序启动完成
WARNING:root:内存使用较高
ERROR:root:数据库连接失败
CRITICAL:root:系统即将崩溃

保存日志到文件

import logging

# 配置日志保存到文件
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='app.log',  # 日志文件名
    filemode='w'         # 写入模式:'w'覆盖,'a'追加
)

# 记录日志
logging.info("应用程序启动")
logging.debug("加载配置文件")
logging.warning("配置文件不存在,使用默认配置")
logging.info("应用程序初始化完成")

查看生成的app.log文件,内容类似:

2024-01-20 10:30:15,123 - INFO - 应用程序启动
2024-01-20 10:30:15,124 - DEBUG - 加载配置文件
2024-01-20 10:30:15,125 - WARNING - 配置文件不存在,使用默认配置
2024-01-20 10:30:15,126 - INFO - 应用程序初始化完成


日志级别详解

Python定义了6个日志级别:

import logging

# 查看各级别的数值
print(f"DEBUG: {logging.DEBUG}")
print(f"INFO: {logging.INFO}")
print(f"WARNING: {logging.WARNING}")
print(f"ERROR: {logging.ERROR}")
print(f"CRITICAL: {logging.CRITICAL}")

# 设置级别为DEBUG,记录所有日志
logging.basicConfig(level=logging.DEBUG)

def test_levels():
    logging.debug("详细的调试信息")
    logging.info("程序运行状态")
    logging.warning("需要注意的情况")
    logging.error("错误信息")
    logging.critical("严重错误")

test_levels()


自定义日志格式

常用格式字段

import logging

# 详细配置日志格式
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)-8s - [%(filename)s:%(lineno)d] - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)

# 创建不同模块的日志记录器
logger1 = logging.getLogger("database")
logger2 = logging.getLogger("web_server")

logger1.info("数据库连接成功")
logger2.warning("请求超时")

输出示例:

2024-01-20 10:30:15 - database - INFO     - [example.py:15] - 数据库连接成功
2024-01-20 10:30:16 - web_server - WARNING  - [example.py:16] - 请求超时


高级配置方法

多处理器配置

import logging

def setup_logger():
    """创建自定义日志记录器"""
    
    # 创建记录器
    logger = logging.getLogger("my_app")
    logger.setLevel(logging.DEBUG)  # 设置记录器级别
    
    # 避免重复添加处理器
    if logger.handlers:
        return logger
    
    # 创建控制台处理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)  # 控制台只显示INFO及以上
    
    # 创建文件处理器
    file_handler = logging.FileHandler("debug.log")
    file_handler.setLevel(logging.DEBUG)  # 文件记录所有DEBUG及以上日志
    
    # 创建格式器
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )
    
    # 为处理器设置格式
    console_handler.setFormatter(formatter)
    file_handler.setFormatter(formatter)
    
    # 为记录器添加处理器
    logger.addHandler(console_handler)
    logger.addHandler(file_handler)
    
    return logger

# 使用自定义记录器
logger = setup_logger()
logger.debug("调试信息")  # 只写入文件
logger.info("普通信息")   # 同时输出到控制台和文件
logger.error("错误信息")  # 同时输出到控制台和文件

不同模块使用不同记录器

import logging

# 配置基础格式
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

class DatabaseManager:
    def __init__(self):
        self.logger = logging.getLogger("app.database")
    
    def connect(self):
        self.logger.info("连接数据库")
        # 模拟连接过程
        self.logger.debug("数据库连接参数: host=localhost, port=5432")
    
    def query(self, sql):
        self.logger.info(f"执行SQL查询: {sql}")
        self.logger.debug(f"查询详情: {sql}")

class WebServer:
    def __init__(self):
        self.logger = logging.getLogger("app.webserver")
    
    def handle_request(self, path):
        self.logger.info(f"处理请求: {path}")
        self.logger.debug(f"请求头信息: ...")

# 使用不同模块的记录器
db = DatabaseManager()
server = WebServer()

db.connect()
db.query("SELECT * FROM users")
server.handle_request("/api/users")


实际应用场景

应用程序日志配置

import logging
import logging.handlers
import os

def setup_application_logging(app_name="my_app"):
    """设置应用程序日志"""
    
    # 创建日志目录
    log_dir = "logs"
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    
    # 主记录器
    logger = logging.getLogger(app_name)
    logger.setLevel(logging.DEBUG)
    
    # 避免重复配置
    if logger.handlers:
        return logger
    
    # 1. 控制台处理器 - 显示重要信息
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    
    # 2. 详细文件处理器 - 记录所有调试信息
    debug_handler = logging.FileHandler(
        os.path.join(log_dir, f"{app_name}_debug.log")
    )
    debug_handler.setLevel(logging.DEBUG)
    
    # 3. 错误文件处理器 - 只记录错误和严重错误
    error_handler = logging.FileHandler(
        os.path.join(log_dir, f"{app_name}_error.log")
    )
    error_handler.setLevel(logging.ERROR)
    
    # 4. 轮转文件处理器 - 自动分割大文件
    rotating_handler = logging.handlers.RotatingFileHandler(
        os.path.join(log_dir, f"{app_name}.log"),
        maxBytes=10*1024*1024,  # 10MB
        backupCount=5
    )
    rotating_handler.setLevel(logging.INFO)
    
    # 创建格式器
    detailed_formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)-8s - %(filename)s:%(lineno)d - %(message)s'
    )
    simple_formatter = logging.Formatter(
        '%(asctime)s - %(levelname)s - %(message)s'
    )
    
    # 设置格式
    console_handler.setFormatter(simple_formatter)
    debug_handler.setFormatter(detailed_formatter)
    error_handler.setFormatter(detailed_formatter)
    rotating_handler.setFormatter(simple_formatter)
    
    # 添加处理器
    logger.addHandler(console_handler)
    logger.addHandler(debug_handler)
    logger.addHandler(error_handler)
    logger.addHandler(rotating_handler)
    
    return logger

# 使用应用程序日志
app_logger = setup_application_logging("my_application")

def process_data(data):
    app_logger.info(f"开始处理数据,大小: {len(data)}")
    app_logger.debug(f"数据内容: {data[:100]}...")
    
    try:
        # 模拟数据处理
        result = len(data) * 2
        app_logger.info(f"数据处理完成,结果: {result}")
        return result
    except Exception as e:
        app_logger.error(f"数据处理失败: {e}")
        raise

# 测试日志记录
data = "这是一些测试数据" * 10
process_data(data)

异常日志记录

import logging
import traceback

# 配置日志
logging.basicConfig(
    level=logging.ERROR,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='error.log'
)

logger = logging.getLogger("error_tracker")

def safe_divide(a, b):
    """安全除法,记录异常"""
    try:
        result = a / b
        logger.info(f"除法计算: {a} / {b} = {result}")
        return result
    except ZeroDivisionError:
        logger.error(f"除零错误: {a} / {b}")
        return None
    except Exception as e:
        # 记录完整的异常信息
        logger.error(f"计算错误: {e}")
        logger.error(f"异常详情:\n{traceback.format_exc()}")
        return None

def process_calculation():
    """处理计算任务"""
    logger.info("开始处理计算任务")
    
    results = []
    calculations = [(10, 2), (8, 0), ("10", 2), (15, 3)]
    
    for a, b in calculations:
        result = safe_divide(a, b)
        if result is not None:
            results.append(result)
            logger.info(f"计算结果: {result}")
        else:
            logger.warning(f"计算失败: {a} / {b}")
    
    logger.info(f"计算任务完成,成功: {len(results)}/{len(calculations)}")
    return results

# 运行测试
process_calculation()


日志轮转和分割

按大小轮转

import logging
from logging.handlers import RotatingFileHandler

def setup_rotating_log():
    """设置轮转日志"""
    
    logger = logging.getLogger("rotating_log")
    logger.setLevel(logging.INFO)
    
    # 创建轮转处理器
    handler = RotatingFileHandler(
        "app.log",
        maxBytes=1024,      # 1KB,实际使用时应该设置更大
        backupCount=3       # 保留3个备份文件
    )
    
    formatter = logging.Formatter('%(asctime)s - %(message)s')
    handler.setFormatter(formatter)
    
    logger.addHandler(handler)
    return logger

# 测试轮转日志
logger = setup_rotating_log()
for i in range(100):
    logger.info(f"这是第{i}条日志记录,用于测试日志轮转功能")

按时间轮转

import logging
from logging.handlers import TimedRotatingFileHandler
import time

def setup_timed_rotating_log():
    """设置按时间轮转的日志"""
    
    logger = logging.getLogger("timed_log")
    logger.setLevel(logging.INFO)
    
    # 创建时间轮转处理器
    handler = TimedRotatingFileHandler(
        "timed_app.log",
        when='S',        # 每秒轮转,实际可用 'H'(小时)、'D'(天)、'W0'(周)
        interval=5,      # 每5秒
        backupCount=3
    )
    
    formatter = logging.Formatter('%(asctime)s - %(message)s')
    handler.setFormatter(formatter)
    
    logger.addHandler(handler)
    return logger

# 测试时间轮转
logger = setup_timed_rotating_log()
start_time = time.time()
while time.time() - start_time < 20:  # 运行20秒
    logger.info("时间轮转日志测试")
    time.sleep(1)


最佳实践

生产环境配置

import logging
import sys

def setup_production_logging():
    """生产环境日志配置"""
    
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    
    # 清除现有处理器
    for handler in logger.handlers[:]:
        logger.removeHandler(handler)
    
    # JSON格式处理器(便于日志分析)
    json_handler = logging.StreamHandler(sys.stdout)
    json_handler.setLevel(logging.INFO)
    
    # 错误邮件处理器(实际使用时需要配置SMTP)
    # error_mail_handler = logging.handlers.SMTPHandler(
    #     mailhost=('smtp.example.com', 587),
    #     fromaddr='app@example.com',
    #     toaddrs=['admin@example.com'],
    #     subject='Application Error',
    #     credentials=('username', 'password')
    # )
    # error_mail_handler.setLevel(logging.ERROR)
    
    # 设置格式
    formatter = logging.Formatter(
        '{"time": "%(asctime)s", "level": "%(levelname)s", '
        '"logger": "%(name)s", "message": "%(message)s"}'
    )
    json_handler.setFormatter(formatter)
    # error_mail_handler.setFormatter(formatter)
    
    # 添加处理器
    logger.addHandler(json_handler)
    # logger.addHandler(error_mail_handler)
    
    return logger

# 生产环境使用
setup_production_logging()
logging.info("应用程序在生产环境启动")

日志性能优化

import logging

# 在调试时使用,生产环境应该关闭
DEBUG_MODE = False

class OptimizedLogger:
    """优化性能的日志记录器"""
    
    def __init__(self, name):
        self.logger = logging.getLogger(name)
        self.debug_mode = DEBUG_MODE
    
    def debug(self, message, *args):
        """只在调试模式记录DEBUG日志"""
        if self.debug_mode:
            self.logger.debug(message, *args)
    
    def info(self, message, *args):
        self.logger.info(message, *args)
    
    def error(self, message, *args):
        self.logger.error(message, *args)

# 使用优化后的记录器
app_log = OptimizedLogger("optimized_app")

def expensive_operation():
    # 昂贵的调试信息计算
    debug_info = "详细的调试数据..."  # 这个计算在非调试模式下也会执行
    app_log.debug(debug_info)  # 但只在调试模式下记录

def better_expensive_operation():
    # 更好的方式:使用lambda延迟计算
    app_log.debug(lambda: "详细的调试数据..." + expensive_calculation())
    
    # 或者在方法内判断
    if app_log.debug_mode:
        debug_info = "详细的调试数据..." + expensive_calculation()
        app_log.logger.debug(debug_info)

def expensive_calculation():
    return "计算结果"


logging 模块常用的属性和方法

1. 核心类

说明示例
logging.Logger记录器,用于发出日志消息(通过 logging.getLogger(name) 获取)logger = logging.getLogger("my_logger")
logging.Handler处理器,决定日志输出位置(如文件、控制台等)handler = logging.FileHandler("app.log")
logging.Formatter格式化器,控制日志输出的格式formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
logging.Filter过滤器,用于更精细地控制日志记录filter = logging.Filter("module.name")

2. Logger 对象常用方法

方法说明示例
logger.setLevel(level)设置日志级别(如 logging.DEBUG、logging.INFO)logger.setLevel(logging.DEBUG)
logger.debug(msg)记录 DEBUG 级别日志logger.debug("调试信息")
logger.info(msg)记录 INFO 级别日志logger.info("程序启动")
logger.warning(msg)记录 WARNING 级别日志logger.warning("磁盘空间不足")
logger.error(msg)记录 ERROR 级别日志logger.error("操作失败")
logger.critical(msg)记录 CRITICAL 级别日志logger.critical("系统崩溃")
logger.addHandler(handler)添加处理器logger.addHandler(handler)
logger.addFilter(filter)添加过滤器logger.addFilter(filter)

3. Handler 常用类型

Handler 类型说明示例
StreamHandler输出到流(如控制台)handler = logging.StreamHandler()
FileHandler输出到文件handler = logging.FileHandler("app.log")
RotatingFileHandler按文件大小分割日志handler = logging.RotatingFileHandler("app.log", maxBytes=1e6, backupCount=3)
TimedRotatingFileHandler按时间分割日志handler = logging.TimedRotatingFileHandler("app.log", when="midnight")
SMTPHandler通过邮件发送日志handler = logging.SMTPHandler("mail.example.com", "from@example.com", "to@example.com", "Error Log")

4. 日志级别(常量)

级别数值说明
CRITICAL50严重错误,程序可能无法继续运行
ERROR40错误,但程序仍可运行
WARNING30警告信息(默认级别)
INFO20程序运行信息
DEBUG10调试信息
NOTSET0继承父记录器的级别

5. Formatter 常用格式字段

字段说明示例输出
%(asctime)s日志创建时间2023-01-01 12:00:00,123
%(levelname)s日志级别名称INFO
%(message)s日志消息内容程序启动成功
%(name)s记录器名称my_logger
%(filename)s生成日志的文件名app.py
%(lineno)d生成日志的行号42
%(funcName)s生成日志的函数main

6. 快速配置方法

方法说明示例
logging.basicConfig()一键配置日志级别、处理器和格式(通常在程序入口调用)logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s')

常用参数

  • level:设置根记录器级别

  • filename:输出到文件

  • filemode:文件模式(如 'w' 覆盖)

  • format:格式字符串

  • datefmt:日期格式(如 "%Y-%m-%d %H:%M:%S")


总结

logging模块是Python中专业的日志记录解决方案:

  • 分级管理:DEBUG、INFO、WARNING、ERROR、CRITICAL五个级别

  • 灵活输出:可以输出到控制台、文件、网络等

  • 格式自定义:完全控制日志的显示格式

  • 性能优化:适合生产环境使用

  • 异常跟踪:完整记录异常信息

使用建议:

  • 开发时使用DEBUG级别,生产环境使用INFO或WARNING

  • 为不同模块创建不同的记录器

  • 重要应用配置日志轮转,避免日志文件过大

  • 记录异常时要包含完整的堆栈信息

合理的日志记录是程序可维护性的重要保障。

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!

链接: https://fly63.com/course/36_2142

目录选择