diff --git a/app.py b/app.py index 1ebf6ec..9152406 100644 --- a/app.py +++ b/app.py @@ -9,6 +9,7 @@ import json import subprocess import signal import threading +import sys from datetime import datetime from flask import Flask, render_template_string, jsonify, request import urllib.request @@ -20,11 +21,58 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__)) WORKSPACE_DIR = os.path.dirname(BASE_DIR) # works目录 ROOT_DIR = os.path.dirname(WORKSPACE_DIR) # workspace-coder目录 PROJECTS_FILE = os.path.join(BASE_DIR, 'projects.json') +LOG_FILE = os.path.join(BASE_DIR, 'logs', 'app.log') # 进程状态缓存 process_cache = {} +def log_message(msg): + """写入日志""" + timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + log_line = f"[{timestamp}] {msg}\n" + # 同时输出到控制台和日志文件 + print(log_line.strip()) + try: + os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True) + with open(LOG_FILE, 'a') as f: + f.write(log_line) + except: + pass + + +def signal_handler(signum, frame): + """处理信号,记录kill来源""" + signal_names = { + signal.SIGTERM: 'SIGTERM', + signal.SIGINT: 'SIGINT', + signal.SIGHUP: 'SIGHUP', + } + sig_name = signal_names.get(signum, f'SIGNAL_{signum}') + + # 尝试获取kill来源 + try: + import psutil + proc = psutil.Process() + parent = proc.parent() + parent_info = f"父进程: {parent.pid} ({parent.name()})" + except: + parent_info = "无法获取父进程信息" + + log_message(f"⚠️ 进程收到 {sig_name} 信号,即将退出! {parent_info}") + log_message(f"信号来源可能是: 手动kill命令、systemd、OOM killer、或其他进程") + sys.exit(0) + + +# 注册信号处理 +signal.signal(signal.SIGTERM, signal_handler) +signal.signal(signal.SIGINT, signal_handler) +try: + signal.signal(signal.SIGHUP, signal_handler) +except: + pass # Windows不支持SIGHUP + + def load_projects(): """加载项目配置""" with open(PROJECTS_FILE, 'r', encoding='utf-8') as f: @@ -1322,8 +1370,9 @@ def api_crons(): if __name__ == '__main__': os.makedirs(os.path.join(BASE_DIR, 'logs'), exist_ok=True) - print("=" * 50) - print("项目服务管理面板") - print("访问地址: http://localhost:19013") - print("=" * 50) + log_message("=" * 50) + log_message("项目服务管理面板启动") + log_message("访问地址: http://localhost:19013") + log_message(f"进程PID: {os.getpid()}") + log_message("=" * 50) app.run(host='0.0.0.0', port=19013, debug=False) \ No newline at end of file