Files
ljwx-k8s/verify-p0-complete.sh
2026-02-20 22:50:45 +08:00

363 lines
11 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
set -e
echo "======================================"
echo "可观测性 P0 任务完整验收"
echo "======================================"
echo ""
# 颜色定义
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 计数器
TOTAL_CHECKS=0
PASSED_CHECKS=0
FAILED_CHECKS=0
check_result() {
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
if [ $1 -eq 0 ]; then
echo -e " ${GREEN}✅ $2${NC}"
PASSED_CHECKS=$((PASSED_CHECKS + 1))
else
echo -e " ${RED}❌ $2${NC}"
FAILED_CHECKS=$((FAILED_CHECKS + 1))
fi
}
echo "======================================"
echo "T1: Prometheus Scrape Configs 验证"
echo "======================================"
echo ""
echo "1. 检查 Prometheus ConfigMap..."
kubectl get configmap prometheus-config -n monitoring > /dev/null 2>&1
check_result $? "prometheus-config ConfigMap 存在"
kubectl get configmap prometheus-config -n monitoring -o yaml | grep -q "postgres-exporter"
check_result $? "配置包含 postgres-exporter job"
kubectl get configmap prometheus-config -n monitoring -o yaml | grep -q "redis-exporter"
check_result $? "配置包含 redis-exporter job"
kubectl get configmap prometheus-config -n monitoring -o yaml | grep -q "business-services"
check_result $? "配置包含 business-services job"
echo ""
echo "======================================"
echo "T2: Exporter 部署验证"
echo "======================================"
echo ""
echo "2. 检查 Exporter Pods..."
kubectl get pods -n data | grep -q "postgres.*metrics.*Running"
check_result $? "Postgres Exporter Pod 运行中"
kubectl get pods -n data | grep -q "redis.*metrics.*Running"
check_result $? "Redis Exporter Pod 运行中"
echo ""
echo "3. 检查 Exporter Services..."
kubectl get svc postgres-postgresql-metrics -n data > /dev/null 2>&1
check_result $? "Postgres Exporter Service 存在"
kubectl get svc redis-metrics -n data > /dev/null 2>&1
check_result $? "Redis Exporter Service 存在"
echo ""
echo "======================================"
echo "T3: Grafana Dashboard 验证"
echo "======================================"
echo ""
echo "4. 检查 Grafana Pod..."
kubectl get pods -n monitoring -l app=grafana | grep -q "Running"
check_result $? "Grafana Pod 运行中"
echo ""
echo "5. 启动端口转发(如需)..."
# 检查端口是否已被占用
if lsof -Pi :3000 -sTCP:LISTEN -t >/dev/null 2>&1; then
echo " ℹ️ 端口 3000 已被使用,跳过端口转发"
else
kubectl port-forward -n monitoring svc/grafana 3000:3000 > /tmp/grafana-pf-verify.log 2>&1 &
GRAFANA_PF_PID=$!
sleep 5
echo " ✅ Grafana 端口转发已启动 (PID: $GRAFANA_PF_PID)"
fi
echo ""
echo "6. 验证 Grafana 可访问..."
GRAFANA_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/api/health)
if [ "$GRAFANA_STATUS" = "200" ]; then
check_result 0 "Grafana API 可访问 (HTTP 200)"
else
check_result 1 "Grafana API 不可访问 (HTTP $GRAFANA_STATUS)"
fi
echo ""
echo "7. 验证 Dashboards..."
DASHBOARDS=$(curl -s -u admin:admin123 http://localhost:3000/api/search?type=dash-db | jq -r '.[].title' 2>/dev/null)
if echo "$DASHBOARDS" | grep -q "PostgreSQL"; then
check_result 0 "PostgreSQL Dashboard 已导入"
else
check_result 1 "PostgreSQL Dashboard 未找到"
fi
if echo "$DASHBOARDS" | grep -q "Redis"; then
check_result 0 "Redis Dashboard 已导入"
else
check_result 1 "Redis Dashboard 未找到"
fi
if echo "$DASHBOARDS" | grep -q "Kubernetes"; then
check_result 0 "Kubernetes Dashboard 已导入"
else
check_result 1 "Kubernetes Dashboard 未找到"
fi
echo ""
echo "======================================"
echo "T4: Loki ↔ Tempo 关联验证"
echo "======================================"
echo ""
echo "8. 检查 Loki 数据源..."
LOKI_DS=$(curl -s -u admin:admin123 http://localhost:3000/api/datasources/name/Loki 2>/dev/null)
if echo "$LOKI_DS" | jq -e '.jsonData.derivedFields' > /dev/null 2>&1; then
DERIVED_FIELDS_COUNT=$(echo "$LOKI_DS" | jq '.jsonData.derivedFields | length')
if [ "$DERIVED_FIELDS_COUNT" -ge 1 ]; then
check_result 0 "Loki Derived Fields 已配置 ($DERIVED_FIELDS_COUNT 个)"
else
check_result 1 "Loki Derived Fields 未配置"
fi
else
check_result 1 "Loki Derived Fields 配置未找到"
fi
echo ""
echo "9. 检查 Tempo 数据源..."
TEMPO_DS=$(curl -s -u admin:admin123 http://localhost:3000/api/datasources/name/Tempo 2>/dev/null)
if echo "$TEMPO_DS" | jq -e '.jsonData.tracesToLogs' > /dev/null 2>&1; then
check_result 0 "Tempo tracesToLogs 已配置"
else
check_result 1 "Tempo tracesToLogs 未配置"
fi
if echo "$TEMPO_DS" | jq -e '.jsonData.tracesToMetrics' > /dev/null 2>&1; then
check_result 0 "Tempo tracesToMetrics 已配置"
else
check_result 1 "Tempo tracesToMetrics 未配置"
fi
echo ""
echo "======================================"
echo "T5 & T6: 业务应用集成文档验证"
echo "======================================"
echo ""
echo "10. 检查集成文档..."
if [ -f "docs/observability/business-instrumentation-spring-boot.md" ]; then
check_result 0 "Spring Boot 集成文档存在"
else
check_result 1 "Spring Boot 集成文档未找到"
fi
if [ -f "docs/observability/business-instrumentation-python.md" ]; then
check_result 0 "Python 集成文档存在"
else
check_result 1 "Python 集成文档未找到"
fi
if [ -f "docs/observability/pg-stat-statements-setup.md" ]; then
check_result 0 "pg_stat_statements 设置文档存在"
else
check_result 1 "pg_stat_statements 设置文档未找到"
fi
echo ""
echo "======================================"
echo "Prometheus Targets & Metrics 验证"
echo "======================================"
echo ""
echo "11. 启动 Prometheus 端口转发..."
if lsof -Pi :9090 -sTCP:LISTEN -t >/dev/null 2>&1; then
echo " ℹ️ 端口 9090 已被使用,跳过端口转发"
else
kubectl port-forward -n monitoring svc/prometheus 9090:9090 > /tmp/prometheus-pf-verify.log 2>&1 &
PROMETHEUS_PF_PID=$!
sleep 5
echo " ✅ Prometheus 端口转发已启动 (PID: $PROMETHEUS_PF_PID)"
fi
echo ""
echo "12. 验证 Prometheus Targets..."
# Postgres Exporter
PG_TARGET=$(curl -s http://localhost:9090/api/v1/targets | jq -r '.data.activeTargets[] | select(.labels.job=="postgres-exporter") | .health' | head -1)
if [ "$PG_TARGET" = "up" ]; then
check_result 0 "Postgres Exporter Target UP"
else
check_result 1 "Postgres Exporter Target 不正常 ($PG_TARGET)"
fi
# Redis Exporter
REDIS_TARGET=$(curl -s http://localhost:9090/api/v1/targets | jq -r '.data.activeTargets[] | select(.labels.job=="redis-exporter") | .health' | head -1)
if [ "$REDIS_TARGET" = "up" ]; then
check_result 0 "Redis Exporter Target UP"
else
check_result 1 "Redis Exporter Target 不正常 ($REDIS_TARGET)"
fi
echo ""
echo "13. 验证 Prometheus Metrics..."
# pg_up
PG_UP=$(curl -s 'http://localhost:9090/api/v1/query?query=pg_up' | jq -r '.data.result | length')
if [ "$PG_UP" -gt 0 ]; then
check_result 0 "pg_up 指标存在 ($PG_UP 个实例)"
else
check_result 1 "pg_up 指标未找到"
fi
# redis_up
REDIS_UP=$(curl -s 'http://localhost:9090/api/v1/query?query=redis_up' | jq -r '.data.result | length')
if [ "$REDIS_UP" -gt 0 ]; then
check_result 0 "redis_up 指标存在 ($REDIS_UP 个实例)"
else
check_result 1 "redis_up 指标未找到"
fi
# kube_pod_info
K8S_PODS=$(curl -s 'http://localhost:9090/api/v1/query?query=kube_pod_info' | jq -r '.data.result | length')
if [ "$K8S_PODS" -gt 0 ]; then
check_result 0 "kube_pod_info 指标存在 ($K8S_PODS 个 Pod)"
else
check_result 1 "kube_pod_info 指标未找到"
fi
echo ""
echo "14. 验证关键 Postgres 指标..."
PG_CONNECTIONS=$(curl -s 'http://localhost:9090/api/v1/query?query=pg_stat_database_numbackends' | jq -r '.data.result | length')
if [ "$PG_CONNECTIONS" -gt 0 ]; then
check_result 0 "pg_stat_database_numbackends (连接数) 存在"
else
check_result 1 "pg_stat_database_numbackends 未找到"
fi
PG_TRANSACTIONS=$(curl -s 'http://localhost:9090/api/v1/query?query=pg_stat_database_xact_commit' | jq -r '.data.result | length')
if [ "$PG_TRANSACTIONS" -gt 0 ]; then
check_result 0 "pg_stat_database_xact_commit (事务数) 存在"
else
check_result 1 "pg_stat_database_xact_commit 未找到"
fi
echo ""
echo "15. 验证关键 Redis 指标..."
REDIS_MEMORY=$(curl -s 'http://localhost:9090/api/v1/query?query=redis_memory_used_bytes' | jq -r '.data.result | length')
if [ "$REDIS_MEMORY" -gt 0 ]; then
check_result 0 "redis_memory_used_bytes (内存使用) 存在"
else
check_result 1 "redis_memory_used_bytes 未找到"
fi
REDIS_CLIENTS=$(curl -s 'http://localhost:9090/api/v1/query?query=redis_connected_clients' | jq -r '.data.result | length')
if [ "$REDIS_CLIENTS" -gt 0 ]; then
check_result 0 "redis_connected_clients (连接数) 存在"
else
check_result 1 "redis_connected_clients 未找到"
fi
echo ""
echo "======================================"
echo "告警规则验证"
echo "======================================"
echo ""
echo "16. 检查告警规则 ConfigMap..."
kubectl get configmap prometheus-rules -n monitoring > /dev/null 2>&1
check_result $? "prometheus-rules ConfigMap 存在"
RULES_FILES=$(kubectl get configmap prometheus-rules -n monitoring -o jsonpath='{.data}' | grep -o '\.yml' | wc -l | tr -d ' ')
echo " 发现 $RULES_FILES 个规则文件"
echo ""
echo "17. 检查 Prometheus 规则加载状态..."
RULES_COUNT=$(curl -s http://localhost:9090/api/v1/rules | jq -r '.data.groups | length' 2>/dev/null || echo "0")
if [ "$RULES_COUNT" -gt 0 ]; then
check_result 0 "Prometheus 已加载 $RULES_COUNT 个规则组"
else
echo -e " ${YELLOW}⚠️ Prometheus 未加载告警规则(需运行 enable-prometheus-alerts.sh)${NC}"
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
fi
echo ""
# 清理端口转发
if [ -n "$GRAFANA_PF_PID" ]; then
kill $GRAFANA_PF_PID 2>/dev/null || true
fi
if [ -n "$PROMETHEUS_PF_PID" ]; then
kill $PROMETHEUS_PF_PID 2>/dev/null || true
fi
echo "======================================"
echo "验收结果汇总"
echo "======================================"
echo ""
echo "总检查项: $TOTAL_CHECKS"
echo -e "${GREEN}通过: $PASSED_CHECKS${NC}"
echo -e "${RED}失败: $FAILED_CHECKS${NC}"
echo ""
PASS_RATE=$((PASSED_CHECKS * 100 / TOTAL_CHECKS))
echo "通过率: $PASS_RATE%"
echo ""
if [ $FAILED_CHECKS -eq 0 ]; then
echo -e "${GREEN}======================================"
echo "✅ 所有检查通过!P0 任务完成!"
echo "======================================${NC}"
echo ""
echo "🎉 可观测性监控系统已就绪!"
echo ""
echo "快速访问:"
echo "- Grafana: http://grafana.omniverseai.net:31080 (admin/admin123)"
echo "- Prometheus: http://localhost:9090"
echo ""
echo "Dashboards:"
echo "- PostgreSQL: http://grafana.omniverseai.net:31080/d/000000039/postgresql-database"
echo "- Redis: http://grafana.omniverseai.net:31080/d/xDLNRKUWz/4b82829"
echo "- Kubernetes: http://grafana.omniverseai.net:31080/d/k8s_views_pods/kubernetes-views-pods"
echo ""
exit 0
else
echo -e "${YELLOW}======================================"
echo "⚠️ 部分检查未通过"
echo "======================================${NC}"
echo ""
echo "建议操作:"
echo "1. 检查失败项的详细日志"
echo "2. 参考 OBSERVABILITY-P0-COMPLETE.md 进行排查"
echo "3. 如需启用告警规则,运行: ./enable-prometheus-alerts.sh"
echo ""
exit 1
fi