Python 的 logging 模块是一个强大的日志记录系统。以下是使用 logging 模块进行日志记录的详细指南:

1. 基础使用

最简单的用法

import logging

# 记录不同级别的日志
logging.debug('调试信息')
logging.info('一般信息')
logging.warning('警告信息')
logging.error('错误信息')
logging.critical('严重错误')

2. 基本配置

配置日志级别和格式

import logging

# 基础配置(通常放在程序开始处)
logging.basicConfig(
    level=logging.DEBUG,  # 设置日志级别
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)

# 使用示例
logging.info('程序开始运行')
try:
    result = 10 / 2
    logging.info(f'计算结果: {result}')
except Exception as e:
    logging.error(f'计算错误: {e}')

3. 高级配置

创建多个日志记录器

import logging

# 创建特定名称的日志记录器
logger = logging.getLogger('my_app')
logger.setLevel(logging.DEBUG)

# 创建控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

# 创建文件处理器
file_handler = logging.FileHandler('app.log', encoding='utf-8')
file_handler.setLevel(logging.DEBUG)

# 设置格式
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s'
)
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

# 添加处理器
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# 使用
logger.debug('调试信息')
logger.info('一般信息')
logger.error('错误信息')

4. 完整示例

import logging
import logging.handlers

def setup_logger():
    """配置日志记录器"""
    logger = logging.getLogger('my_application')
    logger.setLevel(logging.DEBUG)
    
    # 避免重复添加处理器
    if not logger.handlers:
        # 控制台输出
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.INFO)
        
        # 文件输出
        file_handler = logging.FileHandler(
            'app.log', 
            encoding='utf-8',
            mode='a'
        )
        file_handler.setLevel(logging.DEBUG)
        
        # 按文件大小轮转的处理器(可选)
        rotate_handler = logging.handlers.RotatingFileHandler(
            'app_rotate.log',
            maxBytes=1024*1024,  # 1MB
            backupCount=5,
            encoding='utf-8'
        )
        rotate_handler.setLevel(logging.WARNING)
        
        # 格式
        formatter = logging.Formatter(
            '%(asctime)s [%(levelname)s] %(name)s: %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )
        
        console_handler.setFormatter(formatter)
        file_handler.setFormatter(formatter)
        rotate_handler.setFormatter(formatter)
        
        logger.addHandler(console_handler)
        logger.addHandler(file_handler)
        logger.addHandler(rotate_handler)
    
    return logger

# 使用
logger = setup_logger()

def process_data(data):
    """示例函数,展示日志记录"""
    logger.info(f'开始处理数据: {len(data)} 条记录')
    
    try:
        # 业务逻辑
        result = len(data) * 2
        logger.debug(f'计算结果: {result}')
        return result
    except Exception as e:
        logger.error(f'处理数据时出错: {e}', exc_info=True)
        return None

# 测试
if __name__ == '__main__':
    logger.info('程序启动')
    process_data([1, 2, 3, 4, 5])
    logger.info('程序结束')

5. 配置文件方式(推荐)

创建 logging_config.json

{
    "version": 1,
    "disable_existing_loggers": false,
    "formatters": {
        "simple": {
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
        },
        "detailed": {
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(pathname)s:%(lineno)d - %(message)s"
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "simple",
            "stream": "ext://sys.stdout"
        },
        "file": {
            "class": "logging.FileHandler",
            "level": "DEBUG",
            "formatter": "detailed",
            "filename": "app.log",
            "encoding": "utf-8"
        }
    },
    "root": {
        "level": "DEBUG",
        "handlers": ["console", "file"]
    }
}

Python 代码:

import logging
import logging.config
import json

# 加载配置
with open('logging_config.json', 'r') as f:
    config = json.load(f)

logging.config.dictConfig(config)

# 使用
logger = logging.getLogger(__name__)
logger.info('使用配置文件记录日志')

6. 日志级别说明

# 日志级别从低到高
# DEBUG    调试信息,最详细
# INFO     一般信息,确认事情按预期工作
# WARNING  警告,表明一些不期望的事情发生
# ERROR    错误,程序出现严重问题
# CRITICAL 严重错误,程序可能无法继续运行

7. 最佳实践

import logging

class AppLogger:
    def __init__(self, name=__name__):
        self.logger = logging.getLogger(name)
        self.setup_logger()
    
    def setup_logger(self):
        # 避免重复配置
        if not self.logger.handlers:
            self.logger.setLevel(logging.DEBUG)
            
            handler = logging.StreamHandler()
            handler.setLevel(logging.INFO)
            
            formatter = logging.Formatter(
                '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
            )
            handler.setFormatter(formatter)
            
            self.logger.addHandler(handler)
    
    def debug(self, msg, *args, **kwargs):
        self.logger.debug(msg, *args, **kwargs)
    
    def info(self, msg, *args, **kwargs):
        self.logger.info(msg, *args, **kwargs)
    
    def warning(self, msg, *args, **kwargs):
        self.logger.warning(msg, *args, **kwargs)
    
    def error(self, msg, *args, **kwargs):
        self.logger.error(msg, *args, **kwargs)
    
    def critical(self, msg, *args, **kwargs):
        self.logger.critical(msg, *args, **kwargs)

# 使用封装好的日志记录器
log = AppLogger(__name__)
log.info('程序初始化完成')

主要特点总结:

  1. 灵活性强:支持控制台、文件、网络等多种输出方式
  2. 分级记录:支持不同级别的日志记录
  3. 线程安全:多线程环境下安全使用
  4. 模块化:可以为不同模块设置不同的日志级别
  5. 格式定制:可以自定义日志输出的格式
  6. 性能优秀:生产环境中可以关闭调试日志提高性能
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐