#!/usr/bin/env python3 """ NAC Auto Summary Daemon 后台守护进程,监控编译活动,45分钟无活动后自动生成日志 """ import os import sys import time import signal import argparse from datetime import datetime from pathlib import Path # 添加当前目录到Python路径 sys.path.insert(0, str(Path(__file__).parent)) from activity_monitor import ActivityMonitor from summary_generator import SummaryGenerator class AutoSummaryDaemon: def __init__(self, workspace_path, idle_timeout=2700, check_interval=60): """ 初始化守护进程 Args: workspace_path: NAC工作区路径 idle_timeout: 空闲超时时间(秒),默认2700秒(45分钟) check_interval: 检查间隔(秒),默认60秒 """ self.workspace_path = Path(workspace_path) self.idle_timeout = idle_timeout self.check_interval = check_interval self.running = True self.summary_generated_today = False # 初始化组件 self.monitor = ActivityMonitor(workspace_path, idle_timeout) self.generator = SummaryGenerator(workspace_path) # 日志文件 log_dir = self.workspace_path / 'memory' / 'logs' log_dir.mkdir(parents=True, exist_ok=True) self.log_file = log_dir / 'daemon.log' def log(self, message): """ 记录日志 Args: message: 日志消息 """ timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') log_message = f"[{timestamp}] {message}" # 输出到控制台 print(log_message) # 写入日志文件 with open(self.log_file, 'a') as f: f.write(log_message + '\n') def signal_handler(self, sig, frame): """ 处理退出信号 Args: sig: 信号编号 frame: 当前栈帧 """ self.log(f"收到信号 {sig},正在停止守护进程...") self.running = False def check_new_day(self): """ 检查是否进入新的一天 如果是新的一天,重置标志 """ current_date = datetime.now().strftime('%Y-%m-%d') last_check_file = self.workspace_path / 'memory' / 'logs' / 'last_summary_date.txt' last_date = None if last_check_file.exists(): with open(last_check_file, 'r') as f: last_date = f.read().strip() if last_date != current_date: self.summary_generated_today = False with open(last_check_file, 'w') as f: f.write(current_date) return True return False def generate_summary_if_needed(self): """ 如果需要,生成日志总结 """ # 检查是否进入新的一天 if self.check_new_day(): self.log("进入新的一天,重置总结标志") # 检查是否已经生成过今日总结 if self.summary_generated_today: return # 检查是否空闲 if self.monitor.is_idle(): idle_minutes = int(self.monitor.get_idle_time() / 60) self.log(f"检测到空闲 {idle_minutes} 分钟,开始生成今日工作日志...") try: summary, markdown = self.generator.generate_summary() self.log("✅ 今日工作日志生成成功") self.log(f" - Git提交: {summary['statistics']['total_commits']}") self.log(f" - 代码变更: +{summary['statistics']['total_lines_added']} -{summary['statistics']['total_lines_deleted']}") self.log(f" - 新增记忆: {summary['statistics']['new_documents'] + summary['statistics']['new_problems'] + summary['statistics']['new_decisions']}") self.summary_generated_today = True # 重置空闲计时器(避免重复生成) self.monitor.reset_idle_timer() except Exception as e: self.log(f"❌ 生成日志失败: {e}") import traceback self.log(traceback.format_exc()) def run(self): """ 运行守护进程 """ # 注册信号处理器 signal.signal(signal.SIGINT, self.signal_handler) signal.signal(signal.SIGTERM, self.signal_handler) self.log("="*60) self.log("NAC Auto Summary Daemon 已启动") self.log(f"工作区: {self.workspace_path}") self.log(f"空闲超时: {self.idle_timeout}秒 ({self.idle_timeout/60:.0f}分钟)") self.log(f"检查间隔: {self.check_interval}秒") self.log("="*60) iteration = 0 while self.running: try: iteration += 1 # 扫描活动 self.monitor.scan_all_activities() # 获取统计信息 stats = self.monitor.get_activity_statistics() idle_time = self.monitor.get_idle_time() idle_minutes = int(idle_time / 60) # 每10次迭代输出一次状态(10分钟) if iteration % 10 == 0: self.log(f"状态: 空闲 {idle_minutes} 分钟 | 今日活动: {stats['total_activities']} | 提交: {stats['commits_count']}") # 检查是否需要生成总结 self.generate_summary_if_needed() # 等待下一次检查 time.sleep(self.check_interval) except Exception as e: self.log(f"❌ 运行出错: {e}") import traceback self.log(traceback.format_exc()) time.sleep(self.check_interval) self.log("NAC Auto Summary Daemon 已停止") def main(): """主函数""" parser = argparse.ArgumentParser(description='NAC Auto Summary Daemon') parser.add_argument( '--workspace', default='/home/ubuntu/nac-workspace', help='NAC工作区路径(默认: /home/ubuntu/nac-workspace)' ) parser.add_argument( '--timeout', type=int, default=2700, help='空闲超时时间(秒,默认: 2700秒=45分钟)' ) parser.add_argument( '--interval', type=int, default=60, help='检查间隔(秒,默认: 60秒)' ) parser.add_argument( '--test', action='store_true', help='测试模式(使用较短的超时时间)' ) args = parser.parse_args() # 测试模式:使用2分钟超时 if args.test: args.timeout = 120 print("⚠️ 测试模式:空闲超时设置为2分钟") # 创建并运行守护进程 daemon = AutoSummaryDaemon( workspace_path=args.workspace, idle_timeout=args.timeout, check_interval=args.interval ) daemon.run() if __name__ == '__main__': main()