参考
核心概念
1. Logging模块的基本组成
- Logger: 日志记录器,负责捕获日志消息
- Handler: 处理器,指定日志输出的目标(如控制台、文件、远程服务器)
- Formatter: 格式化器,定义输出格式
- Filter: 过滤器,用于日志消息进行筛选
2. 日志级别
- DEBUG: 调试消息,用于开发阶段使用
- INFO: 程序正常运行时的消息
- WARRING: 程序运行中出现潜在问题,但是不会影响程序运行
- ERROR: 程序运行中出现错误
- CRITICAL: 严重错误,可能导致程序崩溃
3. 配置文件的使用与动态调整
通过配置文件(如 JSON 或 YAML)可以灵活地管理日志设置,支持动态调整日志级别和输出目标。
4. 日志轮转与存储优化
日志文件可能会迅速增长,导致磁盘空间不足。RotatingFileHandler
和 TimedRotatingFileHandler
提供了日志轮转功能,可按大小或时间分割日志文件。
应用场景
1. 代码配置本地终端日志和文件日志
import logging
from logging.handlers import RotatingFileHandler
def setup_logger():
logger = logging.getLogger("web_logger")
logger.setLevel(logging.DEBUG)
handler = RotatingFileHandler("access.log", maxBytes=1024 * 1024, backupCount=5)
handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
logger.addHandler(handler)
logger.addHandler(console_handler)
return logger
logger = setup_logger()
if __name__ == "__main__":
logger.info("Info")
2. 通过配置文件配置
import json
import logging
import logging.config
import os
import sys
# 加载日志配置文件
def setup_logging(config_file):
"""
从 JSON 配置文件加载日志设置。
"""
try:
if not os.path.exists(config_file):
raise FileNotFoundError(f"配置文件 {config_file} 未找到。")
with open(config_file, "r", encoding="utf-8") as f:
config = json.load(f)
# 应用配置
logging.config.dictConfig(config)
print(f"成功加载日志配置: {config_file}")
except json.JSONDecodeError as e:
sys.stderr.write(f"配置文件格式错误: {e}\n")
sys.exit(1)
except Exception as e:
sys.stderr.write(f"设置日志时出错: {e}\n")
sys.exit(1)
# 使用更安全的方式初始化日志
def initialize_logging():
try:
setup_logging("docs\logger_config.json")
return logging.getLogger("app_logger")
except Exception as e:
# 如果配置失败,设置基本日志
print(f"使用默认日志配置: {e}")
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
return logging.getLogger("app_logger")
# 初始化日志
logger = initialize_logging()
# 示例函数:模拟程序运行
def simulate_application():
try:
logger.debug("这是一条调试信息。") # 控制台和文件中可见
logger.info("这是一条信息消息。") # 控制台和文件中可见
logger.warning("这是一条警告消息。") # 控制台和文件中可见
logger.error("这是一条错误消息。") # 控制台、文件和远程服务器中可见
logger.critical("这是一条严重错误消息。") # 控制台、文件和远程服务器中可见
# 模拟一个异常情况
try:
result = 10 / 0
except Exception as e:
logger.exception(f"发生异常: {e}")
except Exception as e:
print(f"记录日志时出错: {e}")
if __name__ == "__main__":
simulate_application()
print("日志测试完成。请检查日志文件和远程服务器。")
# 为了确保所有日志都被发送,特别是通过网络
logging.shutdown()
配置文件
{
"version": 1,
"disable_existing_loggers": false,
"formatters": {
"detailed": {
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
},
"simple": {
"format": "%(levelname)s - %(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "simple",
"stream": "ext://sys.stdout"
},
"file": {
"class": "logging.handlers.RotatingFileHandler",
"level": "INFO",
"formatter": "detailed",
"filename": "app.log",
"maxBytes": 1048576,
"backupCount": 3
},
"remote": {
"class": "logging.handlers.SocketHandler",
"level": "ERROR",
"host": "localhost",
"port": 9020
}
},
"loggers": {
"app_logger": {
"level": "DEBUG",
"handlers": ["console", "file", "remote"],
"propagate": false
}
},
"root": {
"level": "WARNING",
"handlers": ["console"]
}
}
这里的app_logger是 对应return logging.getLogger("app_logger")
这两个名字要填对,不然就是使用 root
的配置
格式输出
1.输出线程号+日期+代码位置
配置文件:
{
"version": 1,
"disable_existing_loggers": false,
"formatters": {
"detailed": {
"format": "%(asctime)s | %(threadName)s | %(filename)s:%(lineno)d | %(levelname)s | %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S"
},
"simple": {
"format": "[%(levelname)s] %(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "detailed",
"stream": "ext://sys.stdout"
},
"file": {
"class": "logging.handlers.TimedRotatingFileHandler",
"level": "INFO",
"formatter": "detailed",
"filename": "app.log",
"when": "midnight",
"backupCount": 7,
"encoding": "utf8"
},
"remote": {
"class": "logging.handlers.SocketHandler",
"level": "ERROR",
"host": "localhost",
"port": 9020
}
},
"loggers": {
"app_logger": {
"level": "DEBUG",
"handlers": ["console", "file", "remote"],
"propagate": false
}
},
"root": {
"level": "WARNING",
"handlers": ["console"]
}
}
2025-03-22 17:52:56 | MainThread | logger.py:50 | DEBUG | 这是一条调试信息。
2025-03-22 17:52:56 | MainThread | logger.py:51 | INFO | 这是一条信息消息。
2025-03-22 17:52:56 | MainThread | logger.py:52 | WARNING | 这是一条警告消息。
2025-03-22 17:52:56 | MainThread | logger.py:53 | ERROR | 这是一条错误消息。
2025-03-22 17:52:58 | MainThread | logger.py:54 | CRITICAL | 这是一条严重错误消息。
2025-03-22 17:53:00 | MainThread | logger.py:60 | ERROR | 发生异常: division by zero