feat: 添加信号处理,记录进程被kill的来源信息

This commit is contained in:
2026-04-17 22:45:18 +08:00
parent f245bf73c5
commit d1b01ad9c7

57
app.py
View File

@@ -9,6 +9,7 @@ import json
import subprocess import subprocess
import signal import signal
import threading import threading
import sys
from datetime import datetime from datetime import datetime
from flask import Flask, render_template_string, jsonify, request from flask import Flask, render_template_string, jsonify, request
import urllib.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目录 WORKSPACE_DIR = os.path.dirname(BASE_DIR) # works目录
ROOT_DIR = os.path.dirname(WORKSPACE_DIR) # workspace-coder目录 ROOT_DIR = os.path.dirname(WORKSPACE_DIR) # workspace-coder目录
PROJECTS_FILE = os.path.join(BASE_DIR, 'projects.json') PROJECTS_FILE = os.path.join(BASE_DIR, 'projects.json')
LOG_FILE = os.path.join(BASE_DIR, 'logs', 'app.log')
# 进程状态缓存 # 进程状态缓存
process_cache = {} 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(): def load_projects():
"""加载项目配置""" """加载项目配置"""
with open(PROJECTS_FILE, 'r', encoding='utf-8') as f: with open(PROJECTS_FILE, 'r', encoding='utf-8') as f:
@@ -1322,8 +1370,9 @@ def api_crons():
if __name__ == '__main__': if __name__ == '__main__':
os.makedirs(os.path.join(BASE_DIR, 'logs'), exist_ok=True) os.makedirs(os.path.join(BASE_DIR, 'logs'), exist_ok=True)
print("=" * 50) log_message("=" * 50)
print("项目服务管理面板") log_message("项目服务管理面板启动")
print("访问地址: http://localhost:19013") log_message("访问地址: http://localhost:19013")
print("=" * 50) log_message(f"进程PID: {os.getpid()}")
log_message("=" * 50)
app.run(host='0.0.0.0', port=19013, debug=False) app.run(host='0.0.0.0', port=19013, debug=False)