| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- #!/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
|