asemxin commited on
Commit ·
2902034
1
Parent(s): 59fe96c
fix: image_daemon 加心跳日志+异常捕获+进程守护自动重启
Browse files- entrypoint.sh +15 -4
- image_daemon.py +40 -30
entrypoint.sh
CHANGED
|
@@ -268,12 +268,22 @@ echo " Gateway PID: $GATEWAY_PID"
|
|
| 268 |
sleep 5
|
| 269 |
|
| 270 |
# ============================================
|
| 271 |
-
# 启动图片预处理守护进程(后台)
|
| 272 |
# ============================================
|
| 273 |
-
echo "🖼️ 启动图片预处理守护进程..."
|
| 274 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
IMAGE_DAEMON_PID=$!
|
| 276 |
-
echo " Image Daemon PID: $IMAGE_DAEMON_PID"
|
| 277 |
|
| 278 |
# ============================================
|
| 279 |
# 启动状态监控网页(前台,端口 7860)
|
|
@@ -282,3 +292,4 @@ echo "📊 启动状态监控网页 (端口 7860)..."
|
|
| 282 |
exec python3 /app/status_page.py
|
| 283 |
|
| 284 |
|
|
|
|
|
|
| 268 |
sleep 5
|
| 269 |
|
| 270 |
# ============================================
|
| 271 |
+
# 启动图片预处理守护进程(后台,带自动重启守护)
|
| 272 |
# ============================================
|
| 273 |
+
echo "🖼️ 启动图片预处理守护进程(带自动重启)..."
|
| 274 |
+
(
|
| 275 |
+
RESTART_COUNT=0
|
| 276 |
+
while true; do
|
| 277 |
+
RESTART_COUNT=$((RESTART_COUNT + 1))
|
| 278 |
+
echo "[image_daemon_guard] 🚀 启动 image_daemon (第 ${RESTART_COUNT} 次)"
|
| 279 |
+
python3 /app/image_daemon.py
|
| 280 |
+
EXIT_CODE=$?
|
| 281 |
+
echo "[image_daemon_guard] ⚠️ image_daemon 退出 (code=${EXIT_CODE}), 3 秒后重启..."
|
| 282 |
+
sleep 3
|
| 283 |
+
done
|
| 284 |
+
) &
|
| 285 |
IMAGE_DAEMON_PID=$!
|
| 286 |
+
echo " Image Daemon Guard PID: $IMAGE_DAEMON_PID"
|
| 287 |
|
| 288 |
# ============================================
|
| 289 |
# 启动状态监控网页(前台,端口 7860)
|
|
|
|
| 292 |
exec python3 /app/status_page.py
|
| 293 |
|
| 294 |
|
| 295 |
+
|
image_daemon.py
CHANGED
|
@@ -41,38 +41,46 @@ def get_tenant_token():
|
|
| 41 |
|
| 42 |
def get_bot_chats(token):
|
| 43 |
"""获取 bot 参与的所有聊天"""
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
return []
|
| 54 |
-
items = data.get("data", {}).get("items", [])
|
| 55 |
-
return [c["chat_id"] for c in items]
|
| 56 |
|
| 57 |
def get_recent_messages(token, chat_id, limit=10):
|
| 58 |
"""获取聊天中最近的消息"""
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
return []
|
| 75 |
-
return data.get("data", {}).get("items", [])
|
| 76 |
|
| 77 |
def extract_image_keys(msg):
|
| 78 |
"""从消息中提取所有 image_key"""
|
|
@@ -225,9 +233,11 @@ def main():
|
|
| 225 |
|
| 226 |
chats = get_bot_chats(token)
|
| 227 |
|
| 228 |
-
#
|
| 229 |
-
if cycle == 1 or cycle %
|
| 230 |
-
log(f"
|
|
|
|
|
|
|
| 231 |
|
| 232 |
if not chats and cycle == 1:
|
| 233 |
log("⚠️ 未找到任何聊天!可能原因:")
|
|
|
|
| 41 |
|
| 42 |
def get_bot_chats(token):
|
| 43 |
"""获取 bot 参与的所有聊天"""
|
| 44 |
+
try:
|
| 45 |
+
headers = {"Authorization": f"Bearer {token}"}
|
| 46 |
+
resp = requests.get(f"{FEISHU_BASE}/im/v1/chats",
|
| 47 |
+
headers=headers, params={"page_size": 20}, timeout=10)
|
| 48 |
+
data = resp.json()
|
| 49 |
+
code = data.get("code", -1)
|
| 50 |
+
if code != 0:
|
| 51 |
+
msg = data.get("msg", "unknown")
|
| 52 |
+
log(f"❌ 获取聊天列表失败 (code={code}): {msg}")
|
| 53 |
+
log(f" 需要权限: im:chat / im:chat:readonly")
|
| 54 |
+
return []
|
| 55 |
+
items = data.get("data", {}).get("items", [])
|
| 56 |
+
return [c["chat_id"] for c in items]
|
| 57 |
+
except Exception as e:
|
| 58 |
+
log(f"❌ get_bot_chats 异常: {type(e).__name__}: {e}")
|
| 59 |
return []
|
|
|
|
|
|
|
| 60 |
|
| 61 |
def get_recent_messages(token, chat_id, limit=10):
|
| 62 |
"""获取聊天中最近的消息"""
|
| 63 |
+
try:
|
| 64 |
+
headers = {"Authorization": f"Bearer {token}"}
|
| 65 |
+
resp = requests.get(f"{FEISHU_BASE}/im/v1/messages",
|
| 66 |
+
headers=headers,
|
| 67 |
+
params={
|
| 68 |
+
"container_id_type": "chat",
|
| 69 |
+
"container_id": chat_id,
|
| 70 |
+
"sort_type": "ByCreateTimeDesc",
|
| 71 |
+
"page_size": limit
|
| 72 |
+
}, timeout=10)
|
| 73 |
+
data = resp.json()
|
| 74 |
+
code = data.get("code", -1)
|
| 75 |
+
if code != 0:
|
| 76 |
+
msg = data.get("msg", "unknown")
|
| 77 |
+
log(f"❌ 获取消息失败 chat={chat_id} (code={code}): {msg}")
|
| 78 |
+
log(f" 需要权限: im:message / im:message:readonly")
|
| 79 |
+
return []
|
| 80 |
+
return data.get("data", {}).get("items", [])
|
| 81 |
+
except Exception as e:
|
| 82 |
+
log(f"❌ get_recent_messages 异常: {type(e).__name__}: {e}")
|
| 83 |
return []
|
|
|
|
| 84 |
|
| 85 |
def extract_image_keys(msg):
|
| 86 |
"""从消息中提取所有 image_key"""
|
|
|
|
| 233 |
|
| 234 |
chats = get_bot_chats(token)
|
| 235 |
|
| 236 |
+
# 每轮打印心跳(每 20 轮详细,其余简短)
|
| 237 |
+
if cycle == 1 or cycle % 20 == 0:
|
| 238 |
+
log(f"💓 轮询中... {len(chats)} 个聊天, 已处理 {len(processed)} 条 (第 {cycle} 轮)")
|
| 239 |
+
else:
|
| 240 |
+
log(f"💓 #{cycle} ok, {len(chats)} chats")
|
| 241 |
|
| 242 |
if not chats and cycle == 1:
|
| 243 |
log("⚠️ 未找到任何聊天!可能原因:")
|