截图识别飞书个人任务清单
This commit is contained in:
185
utils/logger.py
Normal file
185
utils/logger.py
Normal file
@@ -0,0 +1,185 @@
|
||||
"""
|
||||
日志记录工具
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def setup_logger(
|
||||
name: str = 'screen2feishu',
|
||||
log_file: Optional[str] = None,
|
||||
level: str = 'INFO',
|
||||
format: str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
) -> logging.Logger:
|
||||
"""
|
||||
设置日志记录器
|
||||
|
||||
Args:
|
||||
name: 日志记录器名称
|
||||
log_file: 日志文件路径,如果为None则只输出到控制台
|
||||
level: 日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
||||
format: 日志格式
|
||||
|
||||
Returns:
|
||||
配置好的日志记录器
|
||||
"""
|
||||
# 创建日志记录器
|
||||
logger = logging.getLogger(name)
|
||||
|
||||
# 避免重复配置
|
||||
if logger.handlers:
|
||||
return logger
|
||||
|
||||
# 设置日志级别
|
||||
level_map = {
|
||||
'DEBUG': logging.DEBUG,
|
||||
'INFO': logging.INFO,
|
||||
'WARNING': logging.WARNING,
|
||||
'ERROR': logging.ERROR,
|
||||
'CRITICAL': logging.CRITICAL
|
||||
}
|
||||
|
||||
log_level = level_map.get(level.upper(), logging.INFO)
|
||||
logger.setLevel(log_level)
|
||||
|
||||
# 创建格式化器
|
||||
formatter = logging.Formatter(format, datefmt='%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# 创建控制台处理器
|
||||
# 在Windows系统上,确保使用UTF-8编码输出
|
||||
if sys.platform == 'win32':
|
||||
import io
|
||||
console_handler = logging.StreamHandler(io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8'))
|
||||
else:
|
||||
console_handler = logging.StreamHandler(sys.stdout)
|
||||
console_handler.setFormatter(formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# 创建文件处理器(如果指定了日志文件)
|
||||
if log_file:
|
||||
log_path = Path(log_file)
|
||||
|
||||
# 确保日志目录存在
|
||||
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
file_handler = logging.FileHandler(log_path, encoding='utf-8')
|
||||
file_handler.setFormatter(formatter)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
def get_logger(name: str = 'screen2feishu') -> logging.Logger:
|
||||
"""
|
||||
获取已配置的日志记录器
|
||||
|
||||
Args:
|
||||
name: 日志记录器名称
|
||||
|
||||
Returns:
|
||||
日志记录器
|
||||
"""
|
||||
return logging.getLogger(name)
|
||||
|
||||
|
||||
def log_function_call(logger: logging.Logger, func_name: str, *args, **kwargs):
|
||||
"""
|
||||
记录函数调用日志
|
||||
|
||||
Args:
|
||||
logger: 日志记录器
|
||||
func_name: 函数名
|
||||
*args: 位置参数
|
||||
**kwargs: 关键字参数
|
||||
"""
|
||||
args_str = ', '.join(repr(arg) for arg in args)
|
||||
kwargs_str = ', '.join(f'{k}={repr(v)}' for k, v in kwargs.items())
|
||||
all_args = ', '.join(filter(None, [args_str, kwargs_str]))
|
||||
|
||||
logger.debug(f"调用函数: {func_name}({all_args})")
|
||||
|
||||
|
||||
def log_function_result(logger: logging.Logger, func_name: str, result):
|
||||
"""
|
||||
记录函数返回结果日志
|
||||
|
||||
Args:
|
||||
logger: 日志记录器
|
||||
func_name: 函数名
|
||||
result: 函数返回结果
|
||||
"""
|
||||
logger.debug(f"函数 {func_name} 返回: {repr(result)}")
|
||||
|
||||
|
||||
def log_error_with_context(logger: logging.Logger, error: Exception, context: str = ""):
|
||||
"""
|
||||
记录错误日志,包含上下文信息
|
||||
|
||||
Args:
|
||||
logger: 日志记录器
|
||||
error: 异常对象
|
||||
context: 错误上下文信息
|
||||
"""
|
||||
if context:
|
||||
logger.error(f"{context}: {str(error)}")
|
||||
else:
|
||||
logger.error(f"错误: {str(error)}")
|
||||
|
||||
|
||||
def create_log_rotation_handler(
|
||||
log_file: str,
|
||||
max_bytes: int = 10 * 1024 * 1024, # 10MB
|
||||
backup_count: int = 5
|
||||
) -> logging.Handler:
|
||||
"""
|
||||
创建支持日志轮转的文件处理器
|
||||
|
||||
Args:
|
||||
log_file: 日志文件路径
|
||||
max_bytes: 单个日志文件最大字节数
|
||||
backup_count: 备份文件数量
|
||||
|
||||
Returns:
|
||||
文件处理器
|
||||
"""
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
log_path = Path(log_file)
|
||||
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
handler = RotatingFileHandler(
|
||||
log_file,
|
||||
maxBytes=max_bytes,
|
||||
backupCount=backup_count,
|
||||
encoding='utf-8'
|
||||
)
|
||||
|
||||
formatter = logging.Formatter(
|
||||
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
return handler
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试日志功能
|
||||
logger = setup_logger(
|
||||
name='test_logger',
|
||||
log_file='test.log',
|
||||
level='DEBUG'
|
||||
)
|
||||
|
||||
logger.debug("这是一条调试信息")
|
||||
logger.info("这是一条普通信息")
|
||||
logger.warning("这是一条警告信息")
|
||||
logger.error("这是一条错误信息")
|
||||
|
||||
# 测试函数调用日志
|
||||
log_function_call(logger, "test_function", "arg1", "arg2", key="value")
|
||||
log_function_result(logger, "test_function", {"result": "success"})
|
||||
log_error_with_context(logger, Exception("测试错误"), "处理数据时")
|
||||
Reference in New Issue
Block a user