#!/bin/bash # 系统监控脚本 # 使用方法: ./scripts/monitor.sh set -e echo "🔍 开始系统监控检查..." # 检查服务状态 check_service() { local service=$1 local url=$2 echo "检查 $service..." if curl -f -s -o /dev/null --max-time 10 "$url"; then echo "✅ $service 正常运行" return 0 else echo "❌ $service 服务异常" return 1 fi } # 检查磁盘空间 check_disk() { echo "💾 检查磁盘空间..." local usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//') echo "磁盘使用率: $usage%" if [ "$usage" -gt 80 ]; then echo "⚠️ 磁盘空间不足 ($usage%)" return 1 else echo "✅ 磁盘空间充足" return 0 fi } # 检查内存使用 check_memory() { echo "🧠 检查内存使用..." local usage=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}') echo "内存使用率: $usage%" if (( $(echo "$usage > 90" | bc -l) )); then echo "⚠️ 内存使用率过高 ($usage%)" return 1 else echo "✅ 内存使用正常" return 0 fi } # 检查 CPU 使用 check_cpu() { echo "⚡ 检查 CPU 使用..." local usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F% '{print $1}') echo "CPU 使用率: $usage%" if (( $(echo "$usage > 80" | bc -l) )); then echo "⚠️ CPU 使用率过高 ($usage%)" return 1 else echo "✅ CPU 使用正常" return 0 fi } # 检查 Docker 容器 check_docker() { echo "🐳 检查 Docker 容器..." # 检查后端容器 if docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "photography_backend.*Up"; then echo "✅ 后端容器运行正常" else echo "❌ 后端容器异常" return 1 fi # 检查数据库容器 if docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "photography_postgres.*Up"; then echo "✅ 数据库容器运行正常" else echo "❌ 数据库容器异常" return 1 fi # 检查 Redis 容器 if docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "photography_redis.*Up"; then echo "✅ Redis 容器运行正常" else echo "❌ Redis 容器异常" return 1 fi } # 检查 Caddy 服务 check_caddy() { echo "🌐 检查 Caddy 服务..." if systemctl is-active --quiet caddy; then echo "✅ Caddy 服务运行正常" return 0 else echo "❌ Caddy 服务异常" return 1 fi } # 检查 SSL 证书 check_ssl() { echo "🔒 检查 SSL 证书..." local domains=("photography.iriver.top" "admin.photography.iriver.top" "api.photography.iriver.top") local all_ok=true for domain in "${domains[@]}"; do local expiry=$(echo | openssl s_client -servername "$domain" -connect "$domain:443" 2>/dev/null | openssl x509 -noout -dates | grep notAfter | cut -d= -f2) local expiry_seconds=$(date -d "$expiry" +%s) local current_seconds=$(date +%s) local days_left=$(( (expiry_seconds - current_seconds) / 86400 )) if [ "$days_left" -gt 30 ]; then echo "✅ $domain SSL 证书有效 (剩余 $days_left 天)" else echo "⚠️ $domain SSL 证书即将过期 (剩余 $days_left 天)" all_ok=false fi done if [ "$all_ok" = true ]; then return 0 else return 1 fi } # 生成监控报告 generate_report() { echo "📊 生成监控报告..." local report_file="/tmp/monitor-report-$(date +%Y%m%d-%H%M%S).txt" { echo "# 系统监控报告" echo "时间: $(date)" echo "主机: $(hostname)" echo "" echo "## 系统资源" echo "- 磁盘使用: $(df -h / | tail -1 | awk '{print $5}')" echo "- 内存使用: $(free | grep Mem | awk '{printf "%.1f%%", $3/$2 * 100.0}')" echo "- CPU 使用: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F% '{print $1}')%" echo "- 负载平均: $(uptime | awk -F'load average:' '{print $2}')" echo "" echo "## 服务状态" echo "- 前端网站: $(curl -s -o /dev/null -w "%{http_code}" https://photography.iriver.top)" echo "- 管理后台: $(curl -s -o /dev/null -w "%{http_code}" https://admin.photography.iriver.top)" echo "- API 服务: $(curl -s -o /dev/null -w "%{http_code}" https://api.photography.iriver.top/health)" echo "" echo "## Docker 容器" docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep photography echo "" echo "## 磁盘空间" df -h echo "" echo "## 内存使用" free -h } > "$report_file" echo "📋 报告已生成: $report_file" } # 主检查流程 main() { local exit_code=0 echo "🚀 开始执行系统监控..." echo "时间: $(date)" echo "主机: $(hostname)" echo "" # 执行各项检查 check_service "前端网站" "https://photography.iriver.top" || exit_code=1 check_service "管理后台" "https://admin.photography.iriver.top" || exit_code=1 check_service "API 服务" "https://api.photography.iriver.top/health" || exit_code=1 echo "" check_disk || exit_code=1 check_memory || exit_code=1 check_cpu || exit_code=1 echo "" check_docker || exit_code=1 check_caddy || exit_code=1 check_ssl || exit_code=1 echo "" generate_report echo "" if [ $exit_code -eq 0 ]; then echo "✅ 系统监控检查完成 - 所有服务正常" else echo "⚠️ 系统监控检查完成 - 发现问题" fi return $exit_code } # 运行主程序 main "$@"