run_scheduler.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. # -*- coding: utf-8 -*-
  2. # Author : Charley
  3. # Python : 3.12.10
  4. # Date : 2026/08/24
  5. """得卡 DECA · 报告统一调度启动器(一个进程同时跑:每日报告 + 魔都周报)。
  6. 背景:daily_report.py 与 weekly_report.py 各自有独立的 schedule 阻塞循环,原需分别起两个进程。
  7. 本文件把两者的 run_once 注册到同一个 schedule,单进程单循环统一调度:
  8. - 每日报告 daily_report.run_once :每天 09:10(生成 + 发企微,口径见 daily_report.py)
  9. - 魔都周报 weekly_report.run_once:每周一 09:20(生成 + 发企微,口径见 weekly_report.py)
  10. 不改动 daily_report.py / weekly_report.py,只复用它们的 run_once(各报告仍可单独 python 直接跑)。
  11. 日志:统一写 stats/logs/scheduler_YYYYMMDD.log(单进程一份,便于排障)。两个报告脚本各自
  12. standalone 运行时仍写自己的日志文件,互不影响。
  13. 运行:python run_scheduler.py(从 stats 目录启动;本文件会 chdir 到自身目录,保证 mysql_pool
  14. 读 stats/application.yml、每日报告产出也落 stats)。Ctrl+C 退出。
  15. """
  16. import os
  17. import sys
  18. import time
  19. # 固定工作目录到本文件所在的 stats:mysql_pool 读此目录 application.yml,daily 报告(cwd 相对)产出也落此
  20. BASE_DIR = os.path.dirname(os.path.abspath(__file__))
  21. os.chdir(BASE_DIR)
  22. sys.path.insert(0, os.path.dirname(BASE_DIR)) # 根目录加入 path(auto_send_wx_msg 等公共模块在根目录)
  23. import schedule
  24. from loguru import logger
  25. # 导入两个报告模块(复用其 run_once)。导入会触发各模块级 logger 配置,下面再统一覆盖为调度器日志。
  26. import daily_report
  27. import weekly_report
  28. # 统一日志:覆盖两个模块 import 时各自加的 sink,调度器只留一份合并日志
  29. logger.remove()
  30. logger.add(os.path.join(BASE_DIR, "logs", "scheduler_{time:YYYYMMDD}.log"),
  31. encoding="utf-8", rotation="00:00",
  32. format="[{time:YYYY-MM-DD HH:mm:ss.SSS}] {level} {message}",
  33. level="INFO", retention="7 day")
  34. def _run_daily():
  35. """调度回调:跑每日报告;异常内部兜底,避免单次失败拖垮整个调度循环。"""
  36. try:
  37. daily_report.run_once(logger)
  38. except Exception as e:
  39. logger.error(f"每日报告运行异常: {e}")
  40. def _run_weekly():
  41. """调度回调:跑魔都周报;异常内部兜底,避免单次失败拖垮整个调度循环。"""
  42. try:
  43. weekly_report.run_once(logger)
  44. except Exception as e:
  45. logger.error(f"魔都周报运行异常: {e}")
  46. def main():
  47. """注册两个定时任务到同一 schedule 并进入单循环调度。"""
  48. # 调试:需启动时立即各跑一次,取消下面两行注释
  49. _run_daily()
  50. # _run_weekly()
  51. schedule.every().day.at("09:10").do(_run_daily) # 每日报告:每天 09:10
  52. schedule.every().monday.at("09:20").do(_run_weekly) # 魔都周报:每周一 09:20(错开 10 分钟)
  53. logger.info("调度器启动:每日报告 每天 09:10 / 魔都周报 每周一 09:20(Ctrl+C 退出)")
  54. while True:
  55. schedule.run_pending()
  56. time.sleep(1)
  57. if __name__ == "__main__":
  58. main()