Files
FastDeploy/fastdeploy/logger/setup_logging.py
T

190 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
"""
配置日志系统
"""
import json
import logging
import logging.config
import os
from pathlib import Path
from fastdeploy import envs
class MaxLevelFilter(logging.Filter):
"""过滤低于指定级别的日志记录。
用于将 INFO/DEBUG 路由到 stdoutERROR/CRITICAL 路由到 stderr。
"""
def __init__(self, level):
super().__init__()
self.level = logging._nameToLevel.get(level, level)
def filter(self, record):
return record.levelno < self.level
def setup_logging(log_dir=None, config_file=None):
"""
设置FastDeploy的日志配置
Args:
log_dir: 日志文件存储目录,如果不提供则使用环境变量
config_file: JSON配置文件路径,如果不提供则使用默认配置
"""
# 避免重复配置
if getattr(setup_logging, "_configured", False):
return logging.getLogger("fastdeploy")
# 使用环境变量中的日志目录,如果没有则使用传入的参数或默认值
if log_dir is None:
log_dir = getattr(envs, "FD_LOG_DIR", "log")
# 确保日志目录存在
Path(log_dir).mkdir(parents=True, exist_ok=True)
# 从环境变量获取日志级别和备份数量
is_debug = int(getattr(envs, "FD_DEBUG", 0))
FASTDEPLOY_LOGGING_LEVEL = "DEBUG" if is_debug else "INFO"
backup_count = int(getattr(envs, "FD_LOG_BACKUP_COUNT", 7))
# 定义日志输出格式
_FORMAT = "%(levelname)-8s %(asctime)s %(process)-5s %(filename)s[line:%(lineno)d] %(message)s"
# 默认配置
default_config = {
"version": 1,
"disable_existing_loggers": False,
"filters": {
"below_error": {
"()": "fastdeploy.logger.setup_logging.MaxLevelFilter",
"level": "ERROR",
}
},
"formatters": {
"standard": {
"class": "logging.Formatter",
"format": _FORMAT,
"datefmt": "%Y-%m-%d %H:%M:%S",
},
"colored": {
"class": "fastdeploy.logger.formatters.ColoredFormatter",
"format": _FORMAT,
"datefmt": "%Y-%m-%d %H:%M:%S",
},
},
"handlers": {
# 控制台标准输出,用于 INFO/DEBUG(低于 ERROR 级别)
"console_stdout": {
"class": "logging.StreamHandler",
"level": FASTDEPLOY_LOGGING_LEVEL,
"filters": ["below_error"],
"formatter": "colored",
"stream": "ext://sys.stdout",
},
# 控制台错误输出,用于 ERROR/CRITICAL
"console_stderr": {
"class": "logging.StreamHandler",
"level": "ERROR",
"formatter": "colored",
"stream": "ext://sys.stderr",
},
# 默认错误日志,保留最新1个小时的日志,位置在log/error.log
"error_file": {
"class": "logging.handlers.TimedRotatingFileHandler",
"level": "ERROR",
"formatter": "standard",
"filename": os.path.join(log_dir, "error.log"),
"when": "H",
"interval": 1,
"backupCount": 1,
},
# 全量日志,保留最新1小时的日志,位置在log/default.log
"default_file": {
"class": "logging.handlers.TimedRotatingFileHandler",
"level": FASTDEPLOY_LOGGING_LEVEL,
"formatter": "standard",
"filename": os.path.join(log_dir, "default.log"),
"when": "H",
"interval": 1,
"backupCount": 1,
},
# 错误日志归档,保留7天内的日志,每隔1小时一个文件,形式如:FastDeploy/log/2025-08-14/error_2025-08-14-18.log
"error_archive": {
"class": "fastdeploy.logger.handlers.IntervalRotatingFileHandler",
"level": "ERROR",
"formatter": "standard",
"filename": os.path.join(log_dir, "error.log"),
"backupDays": 7,
"interval": 1,
"encoding": "utf-8",
},
# 全量日志归档,保留7天内的日志,每隔1小时一个文件,形式如:FastDeploy/log/2025-08-14/default_2025-08-14-18.log
"default_archive": {
"class": "fastdeploy.logger.handlers.IntervalRotatingFileHandler",
"level": FASTDEPLOY_LOGGING_LEVEL,
"formatter": "standard",
"filename": os.path.join(log_dir, "default.log"),
"backupDays": 7,
"interval": 1,
"encoding": "utf-8",
},
},
"loggers": {
# 默认日志记录器,全局共享
"fastdeploy": {
"level": "DEBUG",
"handlers": [
"console_stdout",
"console_stderr",
"error_file",
"default_file",
"error_archive",
"default_archive",
],
"propagate": False,
}
},
}
# 如果提供了配置文件,则加载配置文件
if config_file and os.path.exists(config_file):
with open(config_file, "r", encoding="utf-8") as f:
config = json.load(f)
# 合并环境变量配置到用户配置中,环境变量的优先级高于自定义的优先级
if "handlers" in config:
for handler_name, handler_config in config["handlers"].items():
if "backupCount" not in handler_config and "DailyRotating" in handler_config.get("class", ""):
handler_config["backupCount"] = backup_count
if handler_config.get("level") == "INFO" and is_debug:
handler_config["level"] = "DEBUG"
else:
config = default_config
# 应用日志配置
logging.config.dictConfig(config)
# 避免重复加载
setup_logging._configured = True
# 返回fastdeploy的logger
return logging.getLogger("fastdeploy")