health_check.sh 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. #!/bin/bash
  2. # ===========================================
  3. # 学生状态变更处理服务健康检查脚本
  4. # 用于监控服务运行状态和数据库连接
  5. # ===========================================
  6. set -euo pipefail
  7. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  8. CONFIG_FILE="${SCRIPT_DIR}/data.conf"
  9. CONTROL_SCRIPT="${SCRIPT_DIR}/control_scripts.sh"
  10. # Colors for output
  11. RED='\033[0;31m'
  12. GREEN='\033[0;32m'
  13. YELLOW='\033[1;33m'
  14. BLUE='\033[0;34m'
  15. NC='\033[0m' # No Color
  16. # Load configuration
  17. if [[ ! -f "$CONFIG_FILE" ]]; then
  18. echo -e "${RED}错误:配置文件 $CONFIG_FILE 未找到!${NC}"
  19. exit 1
  20. fi
  21. source "$CONFIG_FILE"
  22. # Functions
  23. log() {
  24. local level="$1"
  25. local message="$2"
  26. local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
  27. echo -e "${timestamp} [$level] $message"
  28. }
  29. success() {
  30. echo -e "${GREEN}✓ $1${NC}"
  31. }
  32. error() {
  33. echo -e "${RED}✗ $1${NC}"
  34. }
  35. warning() {
  36. echo -e "${YELLOW}⚠ $1${NC}"
  37. }
  38. info() {
  39. echo -e "${BLUE}ℹ $1${NC}"
  40. }
  41. # 检查数据库连接
  42. check_database() {
  43. info "正在检查数据库连接..."
  44. local db_test
  45. 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
  46. if echo "$db_test" | grep -q "test"; then
  47. success "数据库连接成功"
  48. return 0
  49. else
  50. error "数据库查询失败"
  51. return 1
  52. fi
  53. else
  54. error "数据库连接失败"
  55. return 1
  56. fi
  57. }
  58. # 检查服务状态
  59. check_service() {
  60. local service_name="$1"
  61. local service_desc="$2"
  62. info "正在检查 $service_desc..."
  63. if [[ ! -x "$CONTROL_SCRIPT" ]]; then
  64. error "控制脚本未找到或不可执行: $CONTROL_SCRIPT"
  65. return 1
  66. fi
  67. local status_output
  68. status_output=$("$CONTROL_SCRIPT" status "$service_name" 2>/dev/null)
  69. if echo "$status_output" | grep -q "is running"; then
  70. success "$service_desc 正在运行"
  71. # 提取PID(如果可用)
  72. local pid
  73. pid=$(echo "$status_output" | grep -o "PID: [0-9]*" | cut -d' ' -f2)
  74. if [[ -n "$pid" ]]; then
  75. info " 进程ID: $pid"
  76. fi
  77. return 0
  78. else
  79. error "$service_desc 未运行"
  80. return 1
  81. fi
  82. }
  83. # 检查日志文件
  84. check_logs() {
  85. info "正在检查日志文件..."
  86. if [[ ! -d "$LOG_DIR" ]]; then
  87. warning "日志目录不存在: $LOG_DIR"
  88. return 1
  89. fi
  90. # 统计日志文件数量
  91. local log_count
  92. log_count=$(find "$LOG_DIR" -name "*.log" -type f | wc -l)
  93. if [[ $log_count -gt 0 ]]; then
  94. success "发现 $log_count 个日志文件"
  95. # 检查最近的错误
  96. local recent_errors
  97. recent_errors=$(find "$LOG_DIR" -name "*.log" -type f -mmin -60 -exec grep -l "ERROR" {} \; | wc -l)
  98. if [[ $recent_errors -gt 0 ]]; then
  99. warning "发现 $recent_errors 个日志文件包含最近的错误 (最近60分钟)"
  100. else
  101. info "日志文件中未发现最近的错误"
  102. fi
  103. return 0
  104. else
  105. warning "未发现日志文件"
  106. return 1
  107. fi
  108. }
  109. # 检查待处理记录
  110. check_pending_records() {
  111. info "正在检查数据库中的待处理记录..."
  112. local pending_changes pending_resume
  113. # Check changes (XIU_XUE, TUI_XUE, BI_YE)
  114. pending_changes=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "
  115. SELECT COUNT(*) as count FROM xg_student_status_change
  116. WHERE process_status = 0
  117. AND change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE')
  118. AND deleted = 0;
  119. " 2>/dev/null | tail -n1)
  120. # Check resume (FU_XUE)
  121. pending_resume=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "
  122. SELECT COUNT(*) as count FROM xg_student_status_change
  123. WHERE process_status = 0
  124. AND change_type = 'FU_XUE'
  125. AND deleted = 0;
  126. " 2>/dev/null | tail -n1)
  127. # Remove potential header
  128. pending_changes=$(echo "$pending_changes" | grep -E '^[0-9]+$')
  129. pending_resume=$(echo "$pending_resume" | grep -E '^[0-9]+$')
  130. if [[ -z "$pending_changes" ]]; then
  131. pending_changes="0"
  132. fi
  133. if [[ -z "$pending_resume" ]]; then
  134. pending_resume="0"
  135. fi
  136. local total_pending=$((pending_changes + pending_resume))
  137. if [[ $total_pending -gt 0 ]]; then
  138. info "发现 $total_pending 条待处理记录 ($pending_changes 条变更, $pending_resume 条复学)"
  139. if [[ $pending_changes -gt 0 ]]; then
  140. warning " $pending_changes 条记录等待变更处理"
  141. fi
  142. if [[ $pending_resume -gt 0 ]]; then
  143. warning " $pending_resume 条记录等待复学处理"
  144. fi
  145. else
  146. success "未发现待处理记录"
  147. fi
  148. return 0
  149. }
  150. # 检查磁盘空间
  151. check_disk_space() {
  152. info "正在检查磁盘空间..."
  153. local log_disk_usage
  154. log_disk_usage=$(df "$LOG_DIR" 2>/dev/null | tail -n1 | awk '{print $5}' | sed 's/%//')
  155. if [[ -z "$log_disk_usage" ]]; then
  156. warning "无法确定日志目录的磁盘使用情况"
  157. return 1
  158. fi
  159. if [[ $log_disk_usage -gt 90 ]]; then
  160. error "日志目录磁盘使用率达到 ${log_disk_usage}% - 建议清理旧日志"
  161. return 1
  162. elif [[ $log_disk_usage -gt 75 ]]; then
  163. warning "日志目录磁盘使用率达到 ${log_disk_usage}%"
  164. else
  165. success "日志目录磁盘使用率 ${log_disk_usage}%"
  166. fi
  167. return 0
  168. }
  169. # Generate health report
  170. generate_report() {
  171. local report_file="${LOG_DIR}/health_check_$(date +%Y%m%d_%H%M%S).log"
  172. {
  173. echo "=== 学生状态变更处理服务健康检查报告 ==="
  174. echo "检查时间: $(date)"
  175. echo "检查主机: $(hostname)"
  176. echo ""
  177. echo "=== 数据库连接检查 ==="
  178. if check_database; then
  179. echo "状态: 正常"
  180. else
  181. echo "状态: 异常"
  182. fi
  183. echo ""
  184. echo "=== 服务状态检查 ==="
  185. echo "学生状态变更处理服务 (休学/退学/毕业):"
  186. if check_service "changes" "学生状态变更处理服务"; then
  187. echo "状态: 运行中"
  188. else
  189. echo "状态: 未运行"
  190. fi
  191. echo "学生复学处理服务:"
  192. if check_service "resume" "学生复学处理服务"; then
  193. echo "状态: 运行中"
  194. else
  195. echo "状态: 未运行"
  196. fi
  197. echo ""
  198. echo "=== 待处理记录检查 ==="
  199. check_pending_records
  200. echo ""
  201. echo "=== 日志文件检查 ==="
  202. check_logs
  203. echo ""
  204. echo "=== 磁盘空间检查 ==="
  205. check_disk_space
  206. echo ""
  207. echo "=== 配置信息 ==="
  208. echo "数据库主机: $DB_HOST:$DB_PORT"
  209. echo "数据库名称: $DB_NAME"
  210. echo "日志目录: $LOG_DIR"
  211. echo "脚本目录: $SCRIPT_DIR"
  212. echo ""
  213. echo "报告生成完成"
  214. } > "$report_file" 2>/dev/null
  215. if [[ -f "$report_file" ]]; then
  216. success "健康检查报告已生成: $report_file"
  217. else
  218. error "生成健康检查报告失败"
  219. fi
  220. }
  221. # Main function
  222. main() {
  223. local generate_report="${1:-false}"
  224. echo ""
  225. echo "========================================"
  226. echo " 学生状态变更处理服务健康检查"
  227. echo "========================================"
  228. echo ""
  229. # Perform all checks
  230. check_database
  231. echo ""
  232. check_service "changes" "学生状态变更处理服务 (休学/退学/毕业)"
  233. check_service "resume" "学生复学处理服务"
  234. echo ""
  235. check_pending_records
  236. echo ""
  237. check_logs
  238. echo ""
  239. check_disk_space
  240. echo ""
  241. # Generate report if requested
  242. if [[ "$generate_report" == "report" ]]; then
  243. generate_report
  244. fi
  245. echo ""
  246. echo "========================================"
  247. success "健康检查完成"
  248. echo ""
  249. if [[ "$generate_report" == "report" ]]; then
  250. echo "详细报告已保存到日志目录"
  251. fi
  252. echo "使用方法:"
  253. echo " $0 # 执行健康检查"
  254. echo " $0 report # 执行检查并生成报告"
  255. echo ""
  256. }
  257. # 显示使用方法
  258. show_usage() {
  259. cat << EOF
  260. 用法: $0 [report]
  261. 执行学生状态变更处理服务的健康检查。
  262. 选项:
  263. report 生成详细的健康检查报告
  264. 检查内容:
  265. - 数据库连接状态
  266. - 服务运行状态
  267. - 待处理记录数量
  268. - 日志文件状态
  269. - 磁盘空间使用情况
  270. EOF
  271. }
  272. # Parse arguments
  273. case "${1:-}" in
  274. report)
  275. main "report"
  276. ;;
  277. -h|--help)
  278. show_usage
  279. ;;
  280. "")
  281. main
  282. ;;
  283. *)
  284. error "未知选项: $1"
  285. show_usage
  286. exit 1
  287. ;;
  288. esac