Python日志配置用Logging吗

wen python案例 5

本文目录导读:

Python日志配置用Logging吗

  1. 为什么要用 logging 而不是 print
  2. 推荐的配置方式(生产环境)
  3. 常见问题 & 最佳实践

是的,Python 标准库中的 logging 模块是配置日志最常用、最强大的工具,它非常灵活,适用于从简单脚本到大型系统的各种场景。

下面是一个快速、规范的日志配置示例,涵盖了控制台输出文件输出

import logging
# 1. 配置日志(通常在程序入口处配置一次)
logging.basicConfig(
    level=logging.INFO,                     # 设置最低日志级别(DEBUG, INFO, WARNING, ERROR, CRITICAL)
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',  # 日志格式
    datefmt='%Y-%m-%d %H:%M:%S',            # 时间格式
    handlers=[
        logging.StreamHandler(),            # 输出到控制台
        logging.FileHandler('app.log', encoding='utf-8')   # 输出到文件
    ]
)
# 2. 获取一个日志记录器(推荐每个模块用 __name__)
logger = logging.getLogger(__name__)
# 3. 使用日志
logger.debug('这是一个调试信息')   # 不会输出(因为 level=INFO)
logger.info('应用启动成功')
logger.warning('磁盘空间不足')
logger.error('数据库连接失败')
logger.critical('系统崩溃')

为什么要用 logging 而不是 print

场景 print logging
控制输出开关 ❌ 需注释/删除代码 ✅ 设置 level 即可过滤
区分严重程度 ❌ 无法区分 ✅ DEBUG / INFO / WARNING / ERROR
输出到文件 ❌ 需手动重定向 ✅ 原生支持文件、网络、邮件等
包含时间/行号 ❌ 需手动拼接 ✅ 通过 format 自动附加
多模块支持 ❌ 混乱 ✅ 每个模块独立 logger

推荐的配置方式(生产环境)

对于复杂系统,建议使用配置文件(如 logging.conflogging.yaml),避免硬编码:

使用 dictConfig(推荐)

import logging.config
LOGGING_CONFIG = {
    'version': 1,
    'formatters': {
        'default': {
            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        }
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'INFO',
            'formatter': 'default'
        },
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'app.log',
            'maxBytes': 10*1024*1024,  # 10MB 轮转
            'backupCount': 5,
            'encoding': 'utf-8',
            'formatter': 'default'
        }
    },
    'root': {
        'level': 'INFO',
        'handlers': ['console', 'file']
    }
}
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger(__name__)

使用 YAML 配置文件

# logging.yaml
version: 1
formatters:
  default:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: INFO
    formatter: default
  file:
    class: logging.handlers.TimedRotatingFileHandler
    filename: app.log
    when: midnight
    backupCount: 7
    encoding: utf-8
    formatter: default
root:
  level: INFO
  handlers: [console, file]
import yaml
import logging.config
with open('logging.yaml', 'r') as f:
    config = yaml.safe_load(f)
    logging.config.dictConfig(config)

常见问题 & 最佳实践

✅ 推荐做法

  • 每个模块用自己的 loggerlogger = logging.getLogger(__name__)
  • 避免在库代码中配置 logging:库只应提供 logger,由主程序配置
  • 使用 RotatingFileHandler 防止日志文件无限增长
  • 从 DEBUG 级别开始,生产环境通过配置文件调整到 INFO/WARNING

❌ 不要这样做

# 坏实践:在库/模块顶层配置
import logging
logging.basicConfig(level=logging.DEBUG)  # 这会干扰使用者的配置

场景 推荐方案
简单脚本 logging.basicConfig(level=logging.INFO)
中型项目 使用 dictConfig 配置控制台+文件输出
大型系统 YAML 配置文件 + 轮转文件处理器
分布式系统 配合 loguru 或 ELK 堆栈使用

需要更高级的功能(如彩色输出、异步日志、结构化日志)时,可以考虑 loguru 库,但标准库 logging 已经能满足 90% 的场景。

抱歉,评论功能暂时关闭!