360 lines
8.7 KiB
Bash
Executable File
360 lines
8.7 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# ===========================================
|
||
# 学生状态变更处理服务健康检查脚本
|
||
# 用于监控服务运行状态和数据库连接
|
||
# ===========================================
|
||
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
CONFIG_FILE="${SCRIPT_DIR}/data.conf"
|
||
CONTROL_SCRIPT="${SCRIPT_DIR}/control_scripts.sh"
|
||
|
||
# Colors for output
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Load configuration
|
||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||
echo -e "${RED}错误:配置文件 $CONFIG_FILE 未找到!${NC}"
|
||
exit 1
|
||
fi
|
||
|
||
source "$CONFIG_FILE"
|
||
|
||
# Functions
|
||
log() {
|
||
local level="$1"
|
||
local message="$2"
|
||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||
echo -e "${timestamp} [$level] $message"
|
||
}
|
||
|
||
success() {
|
||
echo -e "${GREEN}✓ $1${NC}"
|
||
}
|
||
|
||
error() {
|
||
echo -e "${RED}✗ $1${NC}"
|
||
}
|
||
|
||
warning() {
|
||
echo -e "${YELLOW}⚠ $1${NC}"
|
||
}
|
||
|
||
info() {
|
||
echo -e "${BLUE}ℹ $1${NC}"
|
||
}
|
||
|
||
# 检查数据库连接
|
||
check_database() {
|
||
info "正在检查数据库连接..."
|
||
|
||
local db_test
|
||
if db_test=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "SELECT 1 as test;" 2>/dev/null); then
|
||
if echo "$db_test" | grep -q "test"; then
|
||
success "数据库连接成功"
|
||
return 0
|
||
else
|
||
error "数据库查询失败"
|
||
return 1
|
||
fi
|
||
else
|
||
error "数据库连接失败"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# 检查服务状态
|
||
check_service() {
|
||
local service_name="$1"
|
||
local service_desc="$2"
|
||
|
||
info "正在检查 $service_desc..."
|
||
|
||
if [[ ! -x "$CONTROL_SCRIPT" ]]; then
|
||
error "控制脚本未找到或不可执行: $CONTROL_SCRIPT"
|
||
return 1
|
||
fi
|
||
|
||
local status_output
|
||
status_output=$("$CONTROL_SCRIPT" status "$service_name" 2>/dev/null)
|
||
|
||
if echo "$status_output" | grep -q "is running"; then
|
||
success "$service_desc 正在运行"
|
||
|
||
# 提取PID(如果可用)
|
||
local pid
|
||
pid=$(echo "$status_output" | grep -o "PID: [0-9]*" | cut -d' ' -f2)
|
||
if [[ -n "$pid" ]]; then
|
||
info " 进程ID: $pid"
|
||
fi
|
||
|
||
return 0
|
||
else
|
||
error "$service_desc 未运行"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# 检查日志文件
|
||
check_logs() {
|
||
info "正在检查日志文件..."
|
||
|
||
if [[ ! -d "$LOG_DIR" ]]; then
|
||
warning "日志目录不存在: $LOG_DIR"
|
||
return 1
|
||
fi
|
||
|
||
# 统计日志文件数量
|
||
local log_count
|
||
log_count=$(find "$LOG_DIR" -name "*.log" -type f | wc -l)
|
||
|
||
if [[ $log_count -gt 0 ]]; then
|
||
success "发现 $log_count 个日志文件"
|
||
|
||
# 检查最近的错误
|
||
local recent_errors
|
||
recent_errors=$(find "$LOG_DIR" -name "*.log" -type f -mmin -60 -exec grep -l "ERROR" {} \; | wc -l)
|
||
|
||
if [[ $recent_errors -gt 0 ]]; then
|
||
warning "发现 $recent_errors 个日志文件包含最近的错误 (最近60分钟)"
|
||
else
|
||
info "日志文件中未发现最近的错误"
|
||
fi
|
||
|
||
return 0
|
||
else
|
||
warning "未发现日志文件"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# 检查待处理记录
|
||
check_pending_records() {
|
||
info "正在检查数据库中的待处理记录..."
|
||
|
||
local pending_changes pending_resume
|
||
|
||
# Check changes (XIU_XUE, TUI_XUE, BI_YE)
|
||
pending_changes=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "
|
||
SELECT COUNT(*) as count FROM xg_student_status_change
|
||
WHERE process_status = 0
|
||
AND change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE')
|
||
AND deleted = 0;
|
||
" 2>/dev/null | tail -n1)
|
||
|
||
# Check resume (FU_XUE)
|
||
pending_resume=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "
|
||
SELECT COUNT(*) as count FROM xg_student_status_change
|
||
WHERE process_status = 0
|
||
AND change_type = 'FU_XUE'
|
||
AND deleted = 0;
|
||
" 2>/dev/null | tail -n1)
|
||
|
||
# Remove potential header
|
||
pending_changes=$(echo "$pending_changes" | grep -E '^[0-9]+$')
|
||
pending_resume=$(echo "$pending_resume" | grep -E '^[0-9]+$')
|
||
|
||
if [[ -z "$pending_changes" ]]; then
|
||
pending_changes="0"
|
||
fi
|
||
|
||
if [[ -z "$pending_resume" ]]; then
|
||
pending_resume="0"
|
||
fi
|
||
|
||
local total_pending=$((pending_changes + pending_resume))
|
||
|
||
if [[ $total_pending -gt 0 ]]; then
|
||
info "发现 $total_pending 条待处理记录 ($pending_changes 条变更, $pending_resume 条复学)"
|
||
if [[ $pending_changes -gt 0 ]]; then
|
||
warning " $pending_changes 条记录等待变更处理"
|
||
fi
|
||
if [[ $pending_resume -gt 0 ]]; then
|
||
warning " $pending_resume 条记录等待复学处理"
|
||
fi
|
||
else
|
||
success "未发现待处理记录"
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
# 检查磁盘空间
|
||
check_disk_space() {
|
||
info "正在检查磁盘空间..."
|
||
|
||
local log_disk_usage
|
||
log_disk_usage=$(df "$LOG_DIR" 2>/dev/null | tail -n1 | awk '{print $5}' | sed 's/%//')
|
||
|
||
if [[ -z "$log_disk_usage" ]]; then
|
||
warning "无法确定日志目录的磁盘使用情况"
|
||
return 1
|
||
fi
|
||
|
||
if [[ $log_disk_usage -gt 90 ]]; then
|
||
error "日志目录磁盘使用率达到 ${log_disk_usage}% - 建议清理旧日志"
|
||
return 1
|
||
elif [[ $log_disk_usage -gt 75 ]]; then
|
||
warning "日志目录磁盘使用率达到 ${log_disk_usage}%"
|
||
else
|
||
success "日志目录磁盘使用率 ${log_disk_usage}%"
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
# Generate health report
|
||
generate_report() {
|
||
local report_file="${LOG_DIR}/health_check_$(date +%Y%m%d_%H%M%S).log"
|
||
|
||
{
|
||
echo "=== 学生状态变更处理服务健康检查报告 ==="
|
||
echo "检查时间: $(date)"
|
||
echo "检查主机: $(hostname)"
|
||
echo ""
|
||
|
||
echo "=== 数据库连接检查 ==="
|
||
if check_database; then
|
||
echo "状态: 正常"
|
||
else
|
||
echo "状态: 异常"
|
||
fi
|
||
echo ""
|
||
|
||
echo "=== 服务状态检查 ==="
|
||
echo "学生状态变更处理服务 (休学/退学/毕业):"
|
||
if check_service "changes" "学生状态变更处理服务"; then
|
||
echo "状态: 运行中"
|
||
else
|
||
echo "状态: 未运行"
|
||
fi
|
||
|
||
echo "学生复学处理服务:"
|
||
if check_service "resume" "学生复学处理服务"; then
|
||
echo "状态: 运行中"
|
||
else
|
||
echo "状态: 未运行"
|
||
fi
|
||
echo ""
|
||
|
||
echo "=== 待处理记录检查 ==="
|
||
check_pending_records
|
||
echo ""
|
||
|
||
echo "=== 日志文件检查 ==="
|
||
check_logs
|
||
echo ""
|
||
|
||
echo "=== 磁盘空间检查 ==="
|
||
check_disk_space
|
||
echo ""
|
||
|
||
echo "=== 配置信息 ==="
|
||
echo "数据库主机: $DB_HOST:$DB_PORT"
|
||
echo "数据库名称: $DB_NAME"
|
||
echo "日志目录: $LOG_DIR"
|
||
echo "脚本目录: $SCRIPT_DIR"
|
||
echo ""
|
||
|
||
echo "报告生成完成"
|
||
|
||
} > "$report_file" 2>/dev/null
|
||
|
||
if [[ -f "$report_file" ]]; then
|
||
success "健康检查报告已生成: $report_file"
|
||
else
|
||
error "生成健康检查报告失败"
|
||
fi
|
||
}
|
||
|
||
# Main function
|
||
main() {
|
||
local generate_report="${1:-false}"
|
||
|
||
echo ""
|
||
echo "========================================"
|
||
echo " 学生状态变更处理服务健康检查"
|
||
echo "========================================"
|
||
echo ""
|
||
|
||
# Perform all checks
|
||
check_database
|
||
echo ""
|
||
|
||
check_service "changes" "学生状态变更处理服务 (休学/退学/毕业)"
|
||
check_service "resume" "学生复学处理服务"
|
||
echo ""
|
||
|
||
check_pending_records
|
||
echo ""
|
||
|
||
check_logs
|
||
echo ""
|
||
|
||
check_disk_space
|
||
echo ""
|
||
|
||
# Generate report if requested
|
||
if [[ "$generate_report" == "report" ]]; then
|
||
generate_report
|
||
fi
|
||
|
||
echo ""
|
||
echo "========================================"
|
||
success "健康检查完成"
|
||
echo ""
|
||
|
||
if [[ "$generate_report" == "report" ]]; then
|
||
echo "详细报告已保存到日志目录"
|
||
fi
|
||
|
||
echo "使用方法:"
|
||
echo " $0 # 执行健康检查"
|
||
echo " $0 report # 执行检查并生成报告"
|
||
echo ""
|
||
}
|
||
|
||
# 显示使用方法
|
||
show_usage() {
|
||
cat << EOF
|
||
用法: $0 [report]
|
||
|
||
执行学生状态变更处理服务的健康检查。
|
||
|
||
选项:
|
||
report 生成详细的健康检查报告
|
||
|
||
检查内容:
|
||
- 数据库连接状态
|
||
- 服务运行状态
|
||
- 待处理记录数量
|
||
- 日志文件状态
|
||
- 磁盘空间使用情况
|
||
|
||
EOF
|
||
}
|
||
|
||
# Parse arguments
|
||
case "${1:-}" in
|
||
report)
|
||
main "report"
|
||
;;
|
||
-h|--help)
|
||
show_usage
|
||
;;
|
||
"")
|
||
main
|
||
;;
|
||
*)
|
||
error "未知选项: $1"
|
||
show_usage
|
||
exit 1
|
||
;;
|
||
esac
|