截图识别飞书个人任务清单

This commit is contained in:
2026-03-18 15:15:52 +08:00
parent cb5efbe3ca
commit 69f92205e9
23 changed files with 5835 additions and 0 deletions

185
utils/logger.py Normal file
View 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("测试错误"), "处理数据时")