import json import logging from colorama import Fore, Style, init from datetime import datetime import numpy as np import sys import inspect import os # 初始化 colorama init(autoreset=True) # 定义日志记录器 class CustomLogger: def __init__(self, log_name=None, propagate=False, precise_time=True): # 配置日志记录器 self.logger = logging.getLogger(f"custom_logger_{log_name}") self.logger.setLevel(logging.INFO) self.logger.propagate = propagate self.log_name = log_name self.precise_time = precise_time # 配置日志格式器,按照指定格式 log_formatter = logging.Formatter( '%(asctime)s - %(log_name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s' ) def __enter__(self): # 上下文管理器进入方法 return self def __exit__(self, exc_type, exc_value, traceback): # 上下文管理器退出方法 pass def log_info(self, message, is_print=True): self._log(message, logging.INFO, Fore.GREEN, is_print) def log_yellow(self, message, is_print=True): self._log(message, logging.INFO, Fore.YELLOW, is_print) def log_blue(self, message, is_print=True): self._log(message, logging.INFO, Fore.CYAN, is_print) def log_warning(self, message, is_print=True): self._log(message, logging.WARNING, Fore.YELLOW, is_print) def log_error(self, message, is_print=True): self._log(message, logging.ERROR, Fore.RED, is_print) def _log(self, message, level, color, is_print=True): # 获取当前时间并格式化,包含毫秒级精度 current_time = datetime.now() formatted_time = current_time.strftime('%Y-%m-%d %H:%M:%S') + '.' + str(current_time.microsecond // 1000).zfill(3) if self.precise_time else current_time.strftime('%Y-%m-%d %H:%M:%S') # 获取调用此方法的栈帧(即调用log_info等方法的代码行) caller_frame = inspect.stack()[2] # 获取调用日志方法的栈帧 filename = os.path.basename(caller_frame.filename) # 获取文件名而非绝对路径 lineno = caller_frame.lineno # 序列化消息 if isinstance(message, (int, float, list, dict, tuple)): try: message = json.dumps(message, ensure_ascii=False) except (TypeError, ValueError): message = str(message) elif isinstance(message, np.ndarray): message = message.tolist() message = json.dumps(message, ensure_ascii=False) else: message = str(message) # 设置日志级别字符串 log_level = logging.getLevelName(level) # 记录彩色日志,使用 colorama if is_print: print(f"{formatted_time} - {self.log_name} - {log_level} - {filename}:{lineno} - {color}{message}{Style.RESET_ALL}") if __name__ == "__main__": # 配置 logging 模块 # log_file = 'log/test.log' # logging.basicConfig( # level=logging.INFO, # format='%(message)s', # 仅保留日志消息 # handlers=[ # logging.FileHandler(log_file, mode='w'), # 覆盖模式,每次运行清空日志 # logging.StreamHandler(sys.stdout) # 输出到终端 # ] # ) # 使用示例 with CustomLogger(log_name="test") as logger: logger.log_info("这是一个绿色的消息") logger.log_warning("这是一个黄色的警告") logger.log_error("这是一个红色的错误") logger.log_blue("这是一个蓝色的消息")