import logging import os from logging.handlers import RotatingFileHandler from queue import Queue import threading from apscheduler.schedulers.background import BackgroundScheduler from urllib.parse import unquote class AppTools: def __init__(self, config): self.config = config self.task_queue = Queue() self.logger = self._setup_logger() self.scheduler = self._setup_scheduler() self._start_task_thread() def _setup_logger(self): log_dir = self.config.LOGS_DIRECTORY if not os.path.exists(log_dir): os.makedirs(log_dir) log_file = self.config.LOG_FILE logger = logging.getLogger("app") logger.setLevel(logging.INFO) if not any(isinstance(h, RotatingFileHandler) and getattr(h, 'baseFilename', None) == str(log_file) for h in logger.handlers): file_handler = RotatingFileHandler(log_file, maxBytes=1024 * 1024 * 5, backupCount=5, encoding='utf-8') file_handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s:%(message)s') file_handler.setFormatter(formatter) logger.addHandler(file_handler) return logger def _setup_scheduler(self): scheduler = BackgroundScheduler() import atexit atexit.register(lambda: scheduler.shutdown(wait=False)) return scheduler def _start_task_thread(self): task_thread = threading.Thread(target=self.process_tasks, daemon=True) task_thread.start() def process_tasks(self): while True: task = self.task_queue.get() if task is None: self.logger.error("任务处理线程已终止") break try: result = task['handler'](task['data']) task['response'].put(result) except Exception as e: self.logger.error(f"任务执行失败: {str(e)}") task['response'].put({'msg': f'任务执行失败: {str(e)}'}) finally: self.task_queue.task_done() self.logger.info("任务处理完成") def enqueue_task(self, handler, data): response_queue = Queue() self.task_queue.put({ 'handler': handler, 'data': data, 'response': response_queue }) return response_queue @staticmethod def decode_headers(headers): return {key: unquote(value, encoding='utf-8') for key, value in headers.items()} logger = None def setup_global_logger(config): global logger if logger is None: app_tools = AppTools(config) logger = app_tools.logger return logger