#!/bin/bash
# 修复版监控脚本 - 针对cron环境优化

LOG_FILE="/opt/agents/ai-analysis/server-monitor.log"
PROCESS_PATTERN="/opt/agents/ai-analysis/.venv/bin/python3 server.py"
START_SCRIPT="/opt/agents/ai-analysis/start-server.sh"

# 设置环境变量(cron执行时需要的)
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export HOME=/root
export USER=root
export LOGNAME=root
export SHELL=/bin/bash
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

# 如果使用虚拟环境,设置Python相关环境
export VIRTUAL_ENV=/opt/agents/ai-analysis/.venv
export PATH="$VIRTUAL_ENV/bin:$PATH"

# 切换到工作目录
cd /opt/agents/ai-analysis/

# 确保日志目录存在
mkdir -p $(dirname "$LOG_FILE")

log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}

# 更精确的进程检查函数
check_process() {
    # 使用pgrep精确匹配进程
    pgrep -f "^$(echo "$PROCESS_PATTERN" | sed 's/[\/&]/\\&/g')" >/dev/null 2>&1
    return $?
}

# 主监控逻辑
main() {
    log_message "=== 开始进程检查 ==="
    log_message "当前目录: $(pwd)"
    log_message "PATH: $PATH"
    log_message "Python路径: $(which python3 2>/dev/null || echo '未找到')"
    
    # 检查进程是否存在
    if check_process; then
        PIDS=$(pgrep -f "^$(echo "$PROCESS_PATTERN" | sed 's/[\/&]/\\&/g')")
        for PID in $PIDS; do
            if [ -d "/proc/$PID" ]; then
                log_message "✅ 进程运行正常 - PID: $PID"
            fi
        done
        log_message "=== 进程检查结束 ===\n"
        return 0
    else
        log_message "❌ 进程不存在"
        
        # 执行启动脚本
        if [ -f "$START_SCRIPT" ]; then
            log_message "🚀 正在执行启动脚本: $START_SCRIPT"
            
            # 直接在前台执行启动脚本,并捕获所有输出
            START_TIME=$(date +%s)
            
            # 执行启动脚本
            log_message "📝 启动脚本输出:"
            {
                echo "=== 环境变量检查 ==="
                echo "当前目录: $(pwd)"
                echo "PATH: $PATH"
                echo "Python路径: $(which python3)"
                echo "Python版本: $(python3 --version 2>&1 || echo '无法执行python3')"
                echo "虚拟环境: $VIRTUAL_ENV"
                echo ""
                echo "=== 执行启动脚本 ==="
                
                # 以source方式执行,确保环境变量生效
                source "$START_SCRIPT" 2>&1 || sh "$START_SCRIPT" 2>&1
                
                echo "=== 启动脚本执行完成 ==="
            } >> "$LOG_FILE" 2>&1
            
            EXIT_CODE=$?
            END_TIME=$(date +%s)
            DURATION=$((END_TIME - START_TIME))
            
            log_message "启动脚本执行完成,耗时 ${DURATION}秒,退出码: $EXIT_CODE"
            
            # 等待并检查进程
            sleep 5
            if check_process; then
                NEW_PID=$(pgrep -f "^$(echo "$PROCESS_PATTERN" | sed 's/[\/&]/\\&/g')" | head -1)
                log_message "✅ 进程启动成功!PID: $NEW_PID"
            else
                log_message "❌ 进程启动失败"
                log_message "尝试直接启动进程..."
                
                # 尝试直接启动进程
                nohup /opt/agents/ai-analysis/.venv/bin/python3 server.py >> /opt/agents/ai-analysis/server.log 2>&1 &
                DIRECT_PID=$!
                log_message "直接启动进程,PID: $DIRECT_PID"
                
                sleep 3
                if check_process; then
                    log_message "✅ 直接启动成功"
                else
                    log_message "❌ 直接启动也失败"
                fi
            fi
        else
            log_message "❌ 错误: 启动脚本不存在: $START_SCRIPT"
        fi
    fi
    log_message "=== 进程检查结束 ===\n"
}

# 添加锁机制
LOCK_FILE="/tmp/monitor-server.lock"
if [ -e "$LOCK_FILE" ]; then
    LOCK_PID=$(cat "$LOCK_FILE")
    if [ -n "$LOCK_PID" ] && kill -0 "$LOCK_PID" 2>/dev/null; then
        log_message "⚠️  监控脚本已在运行 (PID: $LOCK_PID),跳过本次执行"
        exit 0
    else
        rm -f "$LOCK_FILE"
    fi
fi

echo $$ > "$LOCK_FILE"
trap "rm -f '$LOCK_FILE'" EXIT

# 运行主函数
main

 

*/3 * * * * /opt/agents/ai-analysis/monitor-server.sh

 

posted on 2026-02-12 09:25  小油2018  阅读(24)  评论(0)    收藏  举报