diff --git a/config/__init__.py b/config/__init__.py index ff1d8a2..ed9449a 100644 --- a/config/__init__.py +++ b/config/__init__.py @@ -12,7 +12,7 @@ from .field_mappings import TABLE_SCHEMA, CONTRACT_MAPPING # 应用设置 from .app_settings import ( - LOG_TABLE_CONFIG, NTFY_CONFIG, + LOG_TABLE_CONFIG, NTFY_CONFIG, UPTIME_KUMA_CONFIG, POLL_INTERVAL, BATCH_SIZE, CACHE_DIR, TEMP_DIR, EXECUTION_CARD_FIELDS, CONTRACT_DATA_FIELDS, CONTRACT_DATA_MAPPING ) @@ -26,7 +26,7 @@ __all__ = [ # Field Mappings 'TABLE_SCHEMA', 'CONTRACT_MAPPING', # App Settings - 'LOG_TABLE_CONFIG', 'NTFY_CONFIG', + 'LOG_TABLE_CONFIG', 'NTFY_CONFIG', 'UPTIME_KUMA_CONFIG', 'POLL_INTERVAL', 'BATCH_SIZE', 'CACHE_DIR', 'TEMP_DIR', 'EXECUTION_CARD_FIELDS', 'CONTRACT_DATA_FIELDS', 'CONTRACT_DATA_MAPPING' ] diff --git a/config/app_settings.py b/config/app_settings.py index 7f73d5c..744e7f3 100644 --- a/config/app_settings.py +++ b/config/app_settings.py @@ -28,6 +28,13 @@ NTFY_CONFIG = { } } +# ================= Uptime Kuma 心跳配置 ================= +UPTIME_KUMA_CONFIG = { + 'enabled': True, + 'push_url': 'https://uptimekuma.server10086.icu/api/push/clMSgOQs4CJeF7DJAOiHaFaaZzoL8eB9', + 'heartbeat_interval': 60 # 心跳间隔(秒),需要与 Uptime Kuma 设置一致 +} + # ================= 运行参数 ================= # 合并原 config.py 和 update_config.py 的配置 POLL_INTERVAL = 5 # 轮询间隔(秒) diff --git a/run_incremental_sync.py b/run_incremental_sync.py index b438ea0..39463fa 100644 --- a/run_incremental_sync.py +++ b/run_incremental_sync.py @@ -2,7 +2,8 @@ import time import os import sys import pyodbc -from config import SQL_SERVER_CONN, ACCESS_DRIVER, SYNC_MAPPING, POLL_INTERVAL, LOG_TABLE_CONFIG +import requests +from config import SQL_SERVER_CONN, ACCESS_DRIVER, SYNC_MAPPING, POLL_INTERVAL, LOG_TABLE_CONFIG, UPTIME_KUMA_CONFIG import db_utils from log_utils import (LoggerManager, log_success, log_error, log_warning, log_info, log_processing, log_skip, log_critical, log_start, log_stop, log_file, log_database, log_sync) @@ -183,22 +184,69 @@ def process_sync_task(): try: sql_conn.close() except: pass +# ================= Uptime Kuma 心跳 ================= + +_last_heartbeat_time = 0 + +def send_heartbeat(): + """发送心跳信号到 Uptime Kuma""" + global _last_heartbeat_time + + if not UPTIME_KUMA_CONFIG.get('enabled', False): + return + + try: + url = UPTIME_KUMA_CONFIG['push_url'] + params = { + 'status': 'up', + 'msg': 'OK', + 'ping': '' + } + response = requests.get(url, params=params, timeout=5) + response.raise_for_status() + _last_heartbeat_time = time.time() + except Exception as e: + # 心跳失败不影响主逻辑,仅记录日志 + log_warning(f"心跳发送失败: {e}") + if __name__ == "__main__": log_start("增量同步服务已启动 (配置驱动模式)") log_info(f"轮询间隔: {POLL_INTERVAL} 秒") log_info(f"监控配置: {len(SYNC_MAPPING)} 个文件") + if UPTIME_KUMA_CONFIG.get('enabled', False): + log_info(f"心跳间隔: {UPTIME_KUMA_CONFIG['heartbeat_interval']} 秒") log_info("=" * 70) - - while True: - try: - has_work = process_sync_task() - # 如果有工作,说明可能还有积压,休息短一点(0.1s) - # 如果没工作,休息标准间隔(5s) - time.sleep(0.1 if has_work else POLL_INTERVAL) - except KeyboardInterrupt: - log_info("=" * 70) - log_stop("收到停止信号,服务正在关闭...") - break - except Exception as e: - log_critical(f"主循环崩溃: {e}") - time.sleep(5) \ No newline at end of file + + # 启动时发送第一次心跳 + send_heartbeat() + + try: + while True: + try: + has_work = process_sync_task() + + # 检查是否需要发送心跳 + time_since_last_heartbeat = time.time() - _last_heartbeat_time + if time_since_last_heartbeat >= UPTIME_KUMA_CONFIG['heartbeat_interval']: + send_heartbeat() + + # 如果有工作,说明可能还有积压,休息短一点(0.1s) + # 如果没工作,休息标准间隔(5s) + time.sleep(0.1 if has_work else POLL_INTERVAL) + + except KeyboardInterrupt: + log_info("=" * 70) + log_stop("收到停止信号,服务正在关闭...") + break + except Exception as e: + log_critical(f"主循环崩溃: {e}") + time.sleep(5) + finally: + # 停止时发送心跳停止信号(可选) + if UPTIME_KUMA_CONFIG.get('enabled', False): + try: + url = UPTIME_KUMA_CONFIG['push_url'] + params = {'status': 'down', 'msg': 'Service stopped'} + requests.get(url, params=params, timeout=5) + except: + pass \ No newline at end of file