99 lines
3.6 KiB
Python
Executable File
99 lines
3.6 KiB
Python
Executable File
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("这是一个蓝色的消息")
|