#!/usr/bin/env python
# -*- coding=utf-8 -*-
class Logger:
_instances = {}
_current_date = date.today()
def __new__(cls, log_file_suffix="api.log"):
# 检查当前日期是否与上次实例化时的日期不同
current_date = date.today()
if current_date != cls._current_date:
cls._instances = {} # 清空实例字典
cls._current_date = current_date
# 添加日期前缀
log_file_name = f"{current_date}_{log_file_suffix}"
if log_file_name not in cls._instances:
cls._instances[log_file_name] = super(Logger, cls).__new__(cls)
cls._instances[log_file_name]._initialized = False
return cls._instances[log_file_name]
def __init__(self, log_file_suffix="api.log"):
if self._initialized:
return
# 创建当天日期的文件夹
log_directory = os.path.join("/root/apiLog", str(date.today()))
if not os.path.exists(log_directory):
os.makedirs(log_directory)
# 添加日期前缀
log_file_name = f"{date.today()}_{log_file_suffix}"
self.log_file_path = os.path.join(log_directory, log_file_name)
self.logger = logging.getLogger(log_file_name)
self.logger.setLevel(logging.DEBUG)
# 使用 TimedRotatingFileHandler 进行日志轮询
file_handler = TimedRotatingFileHandler(self.log_file_path, when="midnight", interval=1, backupCount=7)
file_handler.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(filename)s:%(lineno)d - %(levelname)s - %(message)s")
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
self.logger.addHandler(file_handler)
self.logger.addHandler(console_handler)
self._initialized = True
def debug(self, message):
self.logger.debug(self._get_caller_info() + message)
def info(self, message):
self.logger.info(self._get_caller_info() + message)
def warning(self, message):
self.logger.warning(self._get_caller_info() + message)
def error(self, message):
self.logger.error(self._get_caller_info() + message)
def critical(self, message):
self.logger.critical(self._get_caller_info() + message)
def _get_caller_info(self):
frame = inspect.currentframe().f_back.f_back
file_name = os.path.basename(frame.f_code.co_filename)
line_number = frame.f_lineno
method_name = frame.f_code.co_name
return f"{file_name}:{method_name}:{line_number} - "
def _create_log_file(self):
log_directory = os.path.dirname(self.log_file_path)
if not os.path.exists(log_directory):
os.makedirs(log_directory)
if not os.path.exists(self.log_file_path):
with open(self.log_file_path, "w"):
pass
from functools import wraps
def print_args_and_return(func):
api_arg = Logger(log_file_suffix='api_arg.log')
@wraps(func)
def wrapper(*args, **kwargs):
# 打印函数名称和传递的参数
api_arg.info(f"Calling function: {func.__name__}")
api_arg.info(f"Arguments: args={args}, kwargs={kwargs}")
# 调用被装饰的函数并获取返回值
result = func(*args, **kwargs)
# 打印返回值
api_arg.info(f"Return value: {result}")
return result
return wrapper