mirror of
				https://github.com/PaddlePaddle/FastDeploy.git
				synced 2025-10-31 03:46:40 +08:00 
			
		
		
		
	 5d131485d8
			
		
	
	5d131485d8
	
	
		
			
	
		
	
	
		
			Some checks failed
		
		
	
	Deploy GitHub Pages / deploy (push) Has been cancelled
				
			* feat(log):add_request_and_response_log * feat[log]:add error log to file
		
			
				
	
	
		
			162 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """
 | ||
| # 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.
 | ||
| """
 | ||
| 
 | ||
| """
 | ||
| 日志模块:用于初始化和获取 FastDeploy 日志记录器。
 | ||
| 本模块提供 get_logger 方法,统一管理各子模块的日志记录行为。
 | ||
| """
 | ||
| 
 | ||
| import logging
 | ||
| import os
 | ||
| import threading
 | ||
| from pathlib import Path
 | ||
| 
 | ||
| from fastdeploy import envs
 | ||
| from fastdeploy.logger.formatters import ColoredFormatter
 | ||
| from fastdeploy.logger.handlers import DailyRotatingFileHandler, LazyFileHandler
 | ||
| from fastdeploy.logger.setup_logging import setup_logging
 | ||
| 
 | ||
| 
 | ||
| class FastDeployLogger:
 | ||
|     _instance = None
 | ||
|     _initialized = False
 | ||
|     _lock = threading.RLock()
 | ||
| 
 | ||
|     def __new__(cls):
 | ||
|         """单例模式实现"""
 | ||
|         if cls._instance is None:
 | ||
|             with cls._lock:
 | ||
|                 if cls._instance is None:
 | ||
|                     cls._instance = super().__new__(cls)
 | ||
|         return cls._instance
 | ||
| 
 | ||
|     def _initialize(self):
 | ||
|         """显式初始化日志系统"""
 | ||
|         with self._lock:
 | ||
|             if not self._initialized:
 | ||
|                 setup_logging()
 | ||
|                 self._initialized = True
 | ||
| 
 | ||
|     def get_logger(self, name, file_name=None, without_formater=False, print_to_console=False):
 | ||
|         """
 | ||
|         获取日志记录器(兼容原有接口)
 | ||
| 
 | ||
|         Args:
 | ||
|             name: 日志器名称
 | ||
|             file_name: 日志文件名(保持兼容性)
 | ||
|             without_formater: 是否不使用格式化器
 | ||
|             print_to_console: 是否打印到控制台
 | ||
|         """
 | ||
|         # 如果只有一个参数,使用新的统一命名方式
 | ||
|         if file_name is None and not without_formater and not print_to_console:
 | ||
|             # 延迟初始化
 | ||
|             if not self._initialized:
 | ||
|                 self._initialize()
 | ||
|             return self._get_unified_logger(name)
 | ||
| 
 | ||
|         # 兼容原有接口
 | ||
|         return self._get_legacy_logger(name, file_name, without_formater, print_to_console)
 | ||
| 
 | ||
|     def _get_unified_logger(self, name):
 | ||
|         """
 | ||
|         新的统一日志获取方式
 | ||
|         """
 | ||
|         if name is None:
 | ||
|             return logging.getLogger("fastdeploy")
 | ||
| 
 | ||
|         # 处理 __main__ 特殊情况
 | ||
|         if name == "__main__":
 | ||
|             import __main__
 | ||
| 
 | ||
|             # 获取主模块的 __file__ 属性
 | ||
|             if hasattr(__main__, "__file__"):
 | ||
|                 # 获取主模块的文件名
 | ||
|                 base_name = Path(__main__.__file__).stem
 | ||
|                 # 创建带前缀的日志器
 | ||
|                 return logging.getLogger(f"fastdeploy.main.{base_name}")
 | ||
|             return logging.getLogger("fastdeploy.main")
 | ||
| 
 | ||
|         # 如果已经是fastdeploy命名空间,直接使用
 | ||
|         if name.startswith("fastdeploy.") or name == "fastdeploy":
 | ||
|             return logging.getLogger(name)
 | ||
|         else:
 | ||
|             # 其他情况添加fastdeploy前缀
 | ||
|             return logging.getLogger(f"fastdeploy.{name}")
 | ||
| 
 | ||
|     def _get_legacy_logger(self, name, file_name, without_formater=False, print_to_console=False):
 | ||
|         """
 | ||
|         兼容原有接口的日志获取方式
 | ||
|         """
 | ||
| 
 | ||
|         log_dir = envs.FD_LOG_DIR
 | ||
|         if not os.path.exists(log_dir):
 | ||
|             os.makedirs(log_dir, exist_ok=True)
 | ||
| 
 | ||
|         is_debug = int(envs.FD_DEBUG)
 | ||
|         # logger = logging.getLogger(name)
 | ||
|         # 为了兼容原有接口,使用命名空间进行隔离,避免logger覆盖、混乱等问题
 | ||
|         legacy_name = f"legacy.{name}"
 | ||
|         logger = logging.getLogger(legacy_name)
 | ||
| 
 | ||
|         # 设置日志级别
 | ||
|         if is_debug:
 | ||
|             logger.setLevel(level=logging.DEBUG)
 | ||
|         else:
 | ||
|             logger.setLevel(level=logging.INFO)
 | ||
| 
 | ||
|         # 设置格式化器
 | ||
|         formatter = ColoredFormatter(
 | ||
|             "%(levelname)-8s %(asctime)s %(process)-5s %(filename)s[line:%(lineno)d] %(message)s"
 | ||
|         )
 | ||
| 
 | ||
|         # 清除现有的handlers(保持原有逻辑)
 | ||
|         for handler in logger.handlers[:]:
 | ||
|             logger.removeHandler(handler)
 | ||
| 
 | ||
|         # 创建主日志文件handler
 | ||
|         LOG_FILE = f"{log_dir}/{file_name}"
 | ||
|         backup_count = int(envs.FD_LOG_BACKUP_COUNT)
 | ||
|         # handler = LazyFileHandler(filename=LOG_FILE, backupCount=backup_count, level=hanlder_level)
 | ||
|         handler = DailyRotatingFileHandler(LOG_FILE, backupCount=backup_count)
 | ||
| 
 | ||
|         # 创建ERROR日志文件handler(新增功能)
 | ||
|         if not file_name.endswith(".log"):
 | ||
|             file_name = f"{file_name}.log" if "." not in file_name else file_name.split(".")[0] + ".log"
 | ||
|         ERROR_LOG_FILE = os.path.join(log_dir, file_name.replace(".log", "_error.log"))
 | ||
|         error_handler = LazyFileHandler(
 | ||
|             filename=ERROR_LOG_FILE, backupCount=backup_count, level=logging.ERROR, formatter=None
 | ||
|         )
 | ||
| 
 | ||
|         if not without_formater:
 | ||
|             handler.setFormatter(formatter)
 | ||
|             error_handler.setFormatter(formatter)
 | ||
| 
 | ||
|         # 添加文件handlers
 | ||
|         logger.addHandler(handler)
 | ||
|         logger.addHandler(error_handler)
 | ||
| 
 | ||
|         # 控制台handler
 | ||
|         if print_to_console:
 | ||
|             console_handler = logging.StreamHandler()
 | ||
|             if not without_formater:
 | ||
|                 console_handler.setFormatter(formatter)
 | ||
|             logger.addHandler(console_handler)
 | ||
|             console_handler.propagate = False
 | ||
| 
 | ||
|         # 设置propagate(保持原有逻辑)
 | ||
|         # logger.propagate = False
 | ||
| 
 | ||
|         return logger
 |