feat: 添加市场数据检查脚本和日志配置模块
添加 check_market_data.py 脚本用于检查行情数据完整性 实现 Tushare API 管理、交易日历缓存和在线数据检查功能 添加 log_style.py 模块提供灵活的日志配置功能 创建相关批处理文件和日志文件
This commit is contained in:
197
log_style.py
Normal file
197
log_style.py
Normal file
@@ -0,0 +1,197 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
日志配置模块
|
||||
提供灵活的日志系统配置功能
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
from datetime import datetime
|
||||
|
||||
# 默认日志配置
|
||||
DEFAULT_LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
DEFAULT_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
|
||||
DEFAULT_LOG_LEVEL = logging.INFO
|
||||
|
||||
# 全局日志记录器缓存
|
||||
_loggers = {}
|
||||
|
||||
|
||||
def setup_logger(
|
||||
name='backtrader',
|
||||
log_file=None,
|
||||
level=DEFAULT_LOG_LEVEL,
|
||||
log_format=DEFAULT_LOG_FORMAT,
|
||||
date_format=DEFAULT_DATE_FORMAT,
|
||||
console=True,
|
||||
file_level=None,
|
||||
log_dir='logs',
|
||||
backup_count=7
|
||||
):
|
||||
"""
|
||||
配置日志记录器
|
||||
|
||||
Args:
|
||||
name: 日志记录器名称
|
||||
log_file: 日志文件路径,如果为None则自动生成
|
||||
level: 日志级别
|
||||
log_format: 日志格式
|
||||
date_format: 日期格式
|
||||
console: 是否输出到控制台
|
||||
file_level: 文件日志级别,如果为None则使用level
|
||||
log_dir: 日志文件目录
|
||||
backup_count: 日志文件保留数量
|
||||
|
||||
Returns:
|
||||
logging.Logger: 配置好的日志记录器
|
||||
"""
|
||||
# 如果日志记录器已存在,则直接返回
|
||||
if name in _loggers:
|
||||
return _loggers[name]
|
||||
|
||||
# 创建日志记录器
|
||||
logger = logging.getLogger(name)
|
||||
logger.setLevel(level)
|
||||
|
||||
# 避免重复添加处理器
|
||||
if logger.handlers:
|
||||
logger.handlers.clear()
|
||||
|
||||
# 创建格式化器
|
||||
formatter = logging.Formatter(log_format, datefmt=date_format)
|
||||
|
||||
# 添加控制台处理器
|
||||
if console:
|
||||
console_handler = logging.StreamHandler(sys.stdout)
|
||||
console_handler.setLevel(level)
|
||||
console_handler.setFormatter(formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# 添加文件处理器
|
||||
if log_file or log_dir:
|
||||
# 确保日志目录存在
|
||||
if log_dir and not os.path.exists(log_dir):
|
||||
try:
|
||||
os.makedirs(log_dir)
|
||||
except Exception as e:
|
||||
logger.error(f'创建日志目录失败: {str(e)}')
|
||||
|
||||
# 生成日志文件名
|
||||
if not log_file:
|
||||
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||
log_file = os.path.join(log_dir, f'{name}_{timestamp}.log')
|
||||
|
||||
# 使用TimedRotatingFileHandler实现按时间轮换
|
||||
try:
|
||||
file_handler = TimedRotatingFileHandler(
|
||||
log_file,
|
||||
when='midnight',
|
||||
interval=1,
|
||||
backupCount=backup_count,
|
||||
encoding='utf-8'
|
||||
)
|
||||
|
||||
# 设置文件日志级别
|
||||
file_handler.setLevel(file_level or level)
|
||||
file_handler.setFormatter(formatter)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
logger.info(f'日志文件已配置: {log_file}')
|
||||
except Exception as e:
|
||||
logger.error(f'配置日志文件失败: {str(e)}')
|
||||
|
||||
# 保存到缓存
|
||||
_loggers[name] = logger
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
def get_logger(name='backtrader'):
|
||||
"""
|
||||
获取日志记录器
|
||||
|
||||
Args:
|
||||
name: 日志记录器名称
|
||||
|
||||
Returns:
|
||||
logging.Logger: 日志记录器
|
||||
"""
|
||||
if name not in _loggers:
|
||||
# 如果日志记录器不存在,则创建默认配置的日志记录器
|
||||
return setup_logger(name)
|
||||
|
||||
return _loggers[name]
|
||||
|
||||
|
||||
def set_global_level(level):
|
||||
"""
|
||||
设置所有已创建日志记录器的全局级别
|
||||
|
||||
Args:
|
||||
level: 日志级别
|
||||
"""
|
||||
for logger_name, logger in _loggers.items():
|
||||
logger.setLevel(level)
|
||||
# 设置所有处理器的级别
|
||||
for handler in logger.handlers:
|
||||
handler.setLevel(level)
|
||||
|
||||
|
||||
def shutdown_loggers():
|
||||
"""
|
||||
关闭所有日志记录器
|
||||
"""
|
||||
logging.shutdown()
|
||||
_loggers.clear()
|
||||
|
||||
|
||||
def log_exception(logger_name='backtrader', message='发生异常', exc_info=True):
|
||||
"""
|
||||
记录异常信息
|
||||
|
||||
Args:
|
||||
logger_name: 日志记录器名称
|
||||
message: 异常消息
|
||||
exc_info: 是否记录异常堆栈信息
|
||||
"""
|
||||
logger = get_logger(logger_name)
|
||||
logger.error(message, exc_info=exc_info)
|
||||
|
||||
|
||||
def create_specialized_logger(
|
||||
name,
|
||||
log_file=None,
|
||||
level=DEFAULT_LOG_LEVEL,
|
||||
console=True,
|
||||
**kwargs
|
||||
):
|
||||
"""
|
||||
创建专门用途的日志记录器
|
||||
|
||||
Args:
|
||||
name: 日志记录器名称
|
||||
log_file: 日志文件路径
|
||||
level: 日志级别
|
||||
console: 是否输出到控制台
|
||||
**kwargs: 其他参数
|
||||
|
||||
Returns:
|
||||
logging.Logger: 配置好的日志记录器
|
||||
"""
|
||||
# 构建专用日志格式
|
||||
specialized_format = kwargs.get(
|
||||
'log_format',
|
||||
f'[%(asctime)s] [{name.upper()}] [%(levelname)s] %(message)s'
|
||||
)
|
||||
|
||||
return setup_logger(
|
||||
name=name,
|
||||
log_file=log_file,
|
||||
level=level,
|
||||
log_format=specialized_format,
|
||||
console=console,
|
||||
**kwargs
|
||||
)
|
||||
Reference in New Issue
Block a user