提交 6c84387c authored 作者: 陈泽健's avatar 陈泽健

feat(service-monitor): 新增 13 个检测模块(EMQX/Java/Python/Nginx/Nacos/安全合规/系统日志/时间同步/综合诊断/应用日志)

- P1 核心服务: EMQX 基础/深度、Java 应用检测(含进程列表)、Nginx 深度
- P2 辅助服务: Python 应用检测(含进程列表)、Nginx/Nacos 基础、Nacos 深度、应用日志分析
- P3 系统深度: 综合诊断、安全合规、系统日志、时间同步
Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
上级 0ee7ef8d
#!/bin/bash
################################################################################
# EMQX基础检测模块
# 功能: 检测EMQX容器状态、版本、连接数、会话数等
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
fi
# EMQX容器名称
EMQX_CONTAINER="${CONTAINERS[emqx]}"
# ==================== 辅助函数 ====================
# 在EMQX容器中执行命令
emqx_exec() {
docker exec "$EMQX_CONTAINER" $@ 2>/dev/null
}
# ==================== 检测函数 ====================
# 检测EMQX容器状态(使用模糊匹配)
check_emqx_container() {
local container_status="未运行"
local level="严重"
local matched_container=""
if command -v docker &> /dev/null; then
# 尝试精确匹配
matched_container=$(docker ps --format "{{.Names}}" | grep -x "${EMQX_CONTAINER}" | head -1)
# 如果精确匹配失败,尝试模糊匹配
if [ -z "$matched_container" ] && [ -n "$EMQX_CONTAINER" ]; then
matched_container=$(docker ps --format "{{.Names}}" | grep -i "${EMQX_CONTAINER}" | head -1)
fi
if [ -n "$matched_container" ]; then
container_status="运行中 (${matched_container})"
level="正常"
# 更新全局变量
eval "EMQX_CONTAINER='${matched_container}'"
else
# 检查容器是否存在但未运行
matched_container=$(docker ps -a --format "{{.Names}}" | grep -i "${EMQX_CONTAINER}" | head -1)
if [ -n "$matched_container" ]; then
container_status="已停止 (${matched_container})"
level="警告"
fi
fi
fi
output_result "EMQX_CONTAINER_STATUS" "$container_status"
output_result "EMQX_CONTAINER_LEVEL" "$level"
if [ "$level" != "正常" ]; then
return 1
fi
return 0
}
# 检测EMQX版本
check_emqx_version() {
local version=""
version=$(emqx_exec emqx_ctl broker 2>/dev/null | grep "version" | cut -d: -f2 | tr -d ' ')
if [ -n "$version" ]; then
output_result "EMQX_VERSION" "$version"
fi
}
# 检测EMQX状态
check_emqx_status() {
local status="未知"
if emqx_exec emqx_ctl status 2>/dev/null | grep -q "is running\|Node"; then
status="运行中"
output_result "EMQX_STATUS" "$status"
output_result "EMQX_STATUS_LEVEL" "正常"
else
status="异常"
output_result "EMQX_STATUS" "$status"
output_result "EMQX_STATUS_LEVEL" "严重"
fi
}
# 检测EMQX客户端连接
check_emqx_clients() {
local client_count=0
client_count=$(emqx_exec emqx_ctl clients list 2>/dev/null | wc -l)
if [ -n "$client_count" ]; then
output_result "EMQX_CLIENTS" "$client_count"
fi
}
# 检测EMQX会话数
check_emqx_sessions() {
local session_count=0
session_count=$(emqx_exec emqx_ctl sessions list 2>/dev/null | wc -l)
if [ -n "$session_count" ]; then
output_result "EMQX_SESSIONS" "$session_count"
fi
}
# 检测EMQX订阅数
check_emqx_subscriptions() {
local sub_count=0
sub_count=$(emqx_exec emqx_ctl subscriptions list 2>/dev/null | wc -l)
if [ -n "$sub_count" ]; then
output_result "EMQX_SUBSCRIPTIONS" "$sub_count"
fi
}
# 检测EMQX主题数
check_emqx_topics() {
local topic_count=0
topic_count=$(emqx_exec emqx_ctl topics list 2>/dev/null | wc -l)
if [ -n "$topic_count" ]; then
output_result "EMQX_TOPICS" "$topic_count"
fi
}
# 检测EMQX路由数
check_emqx_routes() {
local route_count=0
route_count=$(emqx_exec emqx_ctl routes list 2>/dev/null | wc -l)
if [ -n "$route_count" ]; then
output_result "EMQX_ROUTES" "$route_count"
fi
}
# 检测EMQX监听端口
check_emqx_listeners() {
local listeners=""
listeners=$(emqx_exec emqx_ctl listeners list 2>/dev/null | grep "running" | wc -l)
if [ -n "$listeners" ]; then
output_result "EMQX_LISTENERS" "$listeners"
fi
}
# 检测EMQX集群状态
check_emqx_cluster() {
local cluster_status="未知"
if emqx_exec emqx_ctl cluster status 2>/dev/null | grep -q "is running\|Cluster"; then
cluster_status="正常"
else
cluster_status="未配置"
fi
output_result "EMQX_CLUSTER" "$cluster_status"
}
# ==================== 主检测流程 ====================
main() {
log_info "开始EMQX基础检测..."
# 检查容器状态
if ! check_emqx_container; then
log_warn "EMQX容器未运行,跳过其他检测"
return
fi
# 执行各项检测
check_emqx_version
check_emqx_status
check_emqx_clients
check_emqx_sessions
check_emqx_subscriptions
check_emqx_topics
check_emqx_routes
check_emqx_listeners
check_emqx_cluster
log_info "EMQX基础检测完成"
}
# 执行主函数
main
#!/bin/bash
################################################################################
# Python应用检测模块
# 功能: 检测Python容器状态、进程、资源使用等
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
fi
# Python容器名称
PYTHON_CONTAINER="${CONTAINERS[python]}"
# ==================== 辅助函数 ====================
python_exec() {
docker exec "$PYTHON_CONTAINER" $@ 2>/dev/null
}
# ==================== 检测函数 ====================
# 检测Python容器状态
check_python_container() {
local matched_container=""
if command -v docker &> /dev/null; then
# 尝试精确匹配
matched_container=$(docker ps --format "{{.Names}}" | grep -x "${PYTHON_CONTAINER}" | head -1)
# 如果精确匹配失败,尝试模糊匹配
if [ -z "$matched_container" ] && [ -n "$PYTHON_CONTAINER" ]; then
matched_container=$(docker ps --format "{{.Names}}" | grep -i "${PYTHON_CONTAINER}" | head -1)
fi
fi
if [ -n "$matched_container" ]; then
eval "PYTHON_CONTAINER='${matched_container}'"
output_result "PYTHON_CONTAINER_STATUS" "运行中 (${PYTHON_CONTAINER})"
output_result "PYTHON_CONTAINER_LEVEL" "正常"
return 0
else
# 检查容器是否存在但未运行
matched_container=$(docker ps -a --format "{{.Names}}" | grep -i "${PYTHON_CONTAINER}" | head -1)
if [ -n "$matched_container" ]; then
output_result "PYTHON_CONTAINER_STATUS" "已停止 (${matched_container})"
output_result "PYTHON_CONTAINER_LEVEL" "警告"
else
output_result "PYTHON_CONTAINER_STATUS" "未运行"
output_result "PYTHON_CONTAINER_LEVEL" "严重"
fi
return 1
fi
}
# 检测Python版本
check_python_version() {
local py_version
py_version=$(python_exec python --version 2>&1 | awk '{print $2}')
[ -n "$py_version" ] && output_result "PYTHON_VERSION" "$py_version"
}
# 检测Python进程数
check_python_processes() {
local py_count
py_count=$(python_exec ps aux 2>/dev/null | grep -c "python" || echo "0")
output_result "PYTHON_PROCESSES" "$py_count"
}
# 检测容器内进程列表
check_python_process_list() {
local process_list
process_list=$(python_exec ps aux 2>/dev/null | grep -v "PID" | grep -v "ps aux" | awk '{print $1, $2, $3, $4, $11}' | head -20)
if [ -n "$process_list" ]; then
# 统计进程数
local total_processes
total_processes=$(echo "$process_list" | wc -l)
output_result "PYTHON_PROCESS_COUNT" "$total_processes"
# 格式化进程列表(USER PID CPU% MEM% COMMAND)
local formatted
formatted=$(echo "$process_list" | tr '\n' '|' | sed 's/|$//')
output_result "PYTHON_PROCESS_LIST" "$formatted"
# 获取Python进程详情
local py_processes
py_processes=$(echo "$process_list" | grep -i "python" | head -10)
if [ -n "$py_processes" ]; then
output_result "PYTHON_PROCESSES_DETAIL" "$(echo "$py_processes" | tr '\n' '|' | sed 's/|$//')"
fi
fi
}
# 检测Python容器资源使用
check_python_resources() {
# 内存使用
local py_mem
py_mem=$(docker stats --no-stream --format "{{.MemUsage}}" "$PYTHON_CONTAINER" 2>/dev/null | head -1)
[ -n "$py_mem" ] && output_result "PYTHON_MEMORY" "$py_mem"
# CPU使用率
local py_cpu
py_cpu=$(docker stats --no-stream --format "{{.CPUPerc}}" "$PYTHON_CONTAINER" 2>/dev/null | head -1)
[ -n "$py_cpu" ] && output_result "PYTHON_CPU" "$py_cpu"
}
# 检测Python应用日志
check_python_logs() {
local log_errors=0
log_errors=$(docker logs --tail 500 "$PYTHON_CONTAINER" 2>&1 | grep -ciE "ERROR|Exception|Traceback" || echo "0")
log_errors=$(echo "$log_errors" | tail -1)
output_result "PYTHON_LOG_ERRORS" "$log_errors"
if [ "$log_errors" -gt 20 ]; then
output_result "PYTHON_LOG_LEVEL" "警告"
else
output_result "PYTHON_LOG_LEVEL" "正常"
fi
}
# ==================== 主检测流程 ====================
main() {
log_info "开始Python应用检测..."
if ! check_python_container; then
log_warn "Python容器未运行,跳过其他检测"
return
fi
check_python_version
check_python_processes
check_python_resources
check_python_logs
check_python_process_list
log_info "Python应用检测完成"
}
main
#!/bin/bash
################################################################################
# Nginx基础检测模块
# 功能: 检测Nginx容器状态、配置、连接数等
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
fi
# Nginx容器名称
NGINX_CONTAINER="${CONTAINERS[nginx]}"
# ==================== 辅助函数 ====================
nginx_exec() {
docker exec "$NGINX_CONTAINER" $@ 2>/dev/null
}
# ==================== 检测函数 ====================
# 检测Nginx容器状态
check_nginx_container() {
local matched_container=""
if command -v docker &> /dev/null; then
matched_container=$(docker ps --format "{{.Names}}" | grep -x "${NGINX_CONTAINER}" | head -1)
if [ -z "$matched_container" ] && [ -n "$NGINX_CONTAINER" ]; then
matched_container=$(docker ps --format "{{.Names}}" | grep -i "${NGINX_CONTAINER}" | head -1)
fi
fi
if [ -n "$matched_container" ]; then
eval "NGINX_CONTAINER='${matched_container}'"
output_result "NGINX_CONTAINER_STATUS" "运行中 (${NGINX_CONTAINER})"
output_result "NGINX_CONTAINER_LEVEL" "正常"
return 0
else
matched_container=$(docker ps -a --format "{{.Names}}" | grep -i "${NGINX_CONTAINER}" | head -1)
if [ -n "$matched_container" ]; then
output_result "NGINX_CONTAINER_STATUS" "已停止 (${matched_container})"
output_result "NGINX_CONTAINER_LEVEL" "警告"
else
output_result "NGINX_CONTAINER_STATUS" "未运行"
output_result "NGINX_CONTAINER_LEVEL" "严重"
fi
return 1
fi
}
# 检测Nginx版本
check_nginx_version() {
local nginx_version
nginx_version=$(nginx_exec sh -c "nginx -v 2>&1" | grep "nginx version" | sed 's/.*nginx\///')
[ -n "$nginx_version" ] && output_result "NGINX_VERSION" "$nginx_version"
}
# 检测Nginx配置
check_nginx_config() {
local nginx_conf
nginx_conf=$(nginx_exec nginx -t 2>&1 | grep "successful")
if [ -n "$nginx_conf" ]; then
output_result "NGINX_CONFIG" "正常"
else
output_result "NGINX_CONFIG" "异常"
fi
}
# 检测Nginx状态页
check_nginx_status() {
local nginx_status
nginx_status=$(nginx_exec curl -s localhost/nginx_status 2>/dev/null | head -1)
[ -n "$nginx_status" ] && output_result "NGINX_STATUS" "$nginx_status"
}
# 检测Nginx容器资源
check_nginx_resources() {
local mem_usage
mem_usage=$(docker stats --no-stream --format "{{.MemUsage}}" "$NGINX_CONTAINER" 2>/dev/null)
[ -n "$mem_usage" ] && output_result "NGINX_MEMORY" "$mem_usage"
}
# ==================== 主检测流程 ====================
main() {
log_info "开始Nginx基础检测..."
if ! check_nginx_container; then
log_warn "Nginx容器未运行,跳过其他检测"
return
fi
check_nginx_version
check_nginx_config
check_nginx_status
check_nginx_resources
log_info "Nginx基础检测完成"
}
main
#!/bin/bash
################################################################################
# Nacos基础检测模块
# 功能: 检测Nacos容器状态、服务实例数等
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
fi
# Nacos容器名称
NACOS_CONTAINER="${CONTAINERS[nacos]}"
# ==================== 辅助函数 ====================
nacos_exec() {
docker exec "$NACOS_CONTAINER" $@ 2>/dev/null
}
nacos_api() {
local endpoint=$1
nacos_exec curl -s "http://localhost:8848/nacos/$endpoint" 2>/dev/null
}
# ==================== 检测函数 ====================
# 检测Nacos容器状态
check_nacos_container() {
local matched_container=""
if command -v docker &> /dev/null; then
matched_container=$(docker ps --format "{{.Names}}" | grep -x "${NACOS_CONTAINER}" | head -1)
if [ -z "$matched_container" ] && [ -n "$NACOS_CONTAINER" ]; then
matched_container=$(docker ps --format "{{.Names}}" | grep -i "${NACOS_CONTAINER}" | head -1)
fi
fi
if [ -n "$matched_container" ]; then
eval "NACOS_CONTAINER='${matched_container}'"
output_result "NACOS_CONTAINER_STATUS" "运行中 (${NACOS_CONTAINER})"
output_result "NACOS_CONTAINER_LEVEL" "正常"
return 0
else
matched_container=$(docker ps -a --format "{{.Names}}" | grep -i "${NACOS_CONTAINER}" | head -1)
if [ -n "$matched_container" ]; then
output_result "NACOS_CONTAINER_STATUS" "已停止 (${matched_container})"
output_result "NACOS_CONTAINER_LEVEL" "警告"
else
output_result "NACOS_CONTAINER_STATUS" "未运行"
output_result "NACOS_CONTAINER_LEVEL" "严重"
fi
return 1
fi
}
# 检测Nacos健康状态
check_nacos_health() {
local nacos_health
nacos_health=$(nacos_api "v1/console/health/readiness" 2>/dev/null)
[ -n "$nacos_health" ] && output_result "NACOS_HEALTH" "$nacos_health"
}
# 检测Nacos容器资源
check_nacos_resources() {
local nacos_mem
nacos_mem=$(docker stats --no-stream --format "{{.MemUsage}}" "$NACOS_CONTAINER" 2>/dev/null)
[ -n "$nacos_mem" ] && output_result "NACOS_MEMORY" "$nacos_mem"
}
# 检测Nacos服务数量
check_nacos_services() {
local services
services=$(nacos_api "v1/ns/service/list?pageNo=1&pageSize=100&namespaceId=" 2>/dev/null)
if [ -n "$services" ]; then
local service_count
service_count=$(echo "$services" | grep -o '"count":[0-9]*' | cut -d: -f2 | head -1)
[ -n "$service_count" ] && output_result "NACOS_SERVICES_COUNT" "$service_count"
fi
}
# ==================== 主检测流程 ====================
main() {
log_info "开始Nacos基础检测..."
if ! check_nacos_container; then
log_warn "Nacos容器未运行,跳过其他检测"
return
fi
check_nacos_health
check_nacos_resources
check_nacos_services
log_info "Nacos基础检测完成"
}
main
#!/bin/bash
################################################################################
# 应用日志分析模块
# 功能: 检测Java、Python应用日志中的错误和异常
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
fi
# ==================== 检测函数 ====================
# 检测应用日志错误
check_app_log_errors() {
local log_dirs=("/data/services/api/*/log" "/data/services/api/python*/log")
local total_errors=0
for log_dir in $log_dirs; do
if [ -d "$log_dir" ]; then
local error_count
error_count=$(find "$log_dir" -name "*.log" -mtime -1 -exec grep -lE "ERROR|Exception" {} \; 2>/dev/null | wc -l)
total_errors=$((total_errors + error_count))
fi
done
output_result "APP_LOG_ERRORS_24H" "$total_errors"
if [ "$total_errors" -gt 100 ]; then
output_result "APP_LOG_LEVEL" "严重"
elif [ "$total_errors" -gt 10 ]; then
output_result "APP_LOG_LEVEL" "警告"
else
output_result "APP_LOG_LEVEL" "正常"
fi
}
# 检测Docker容器日志错误
check_container_log_errors() {
if ! command -v docker &> /dev/null; then
return
fi
local total_container_errors=0
local running_containers
running_containers=$(docker ps --format "{{.Names}}" 2>/dev/null | head -20)
for container in $running_containers; do
local error_count
error_count=$(docker logs --tail 200 "$container" 2>&1 | grep -ciE "ERROR|Exception|FATAL" || echo "0")
error_count=$(echo "$error_count" | tail -1)
if [ -n "$error_count" ] && [ "$error_count" -gt 0 ]; then
output_result "CONTAINER_LOG_ERRORS_${container}" "$error_count"
total_container_errors=$((total_container_errors + error_count))
fi
done
output_result "CONTAINER_LOG_ERRORS_TOTAL" "$total_container_errors"
if [ "$total_container_errors" -gt 200 ]; then
output_result "CONTAINER_LOG_LEVEL" "严重"
elif [ "$total_container_errors" -gt 50 ]; then
output_result "CONTAINER_LOG_LEVEL" "警告"
else
output_result "CONTAINER_LOG_LEVEL" "正常"
fi
}
# 检测系统日志错误
check_system_log_errors() {
local sys_errors=0
# 检查 /var/log/messages 或 /var/log/syslog
if [ -f "/var/log/messages" ]; then
sys_errors=$(grep -cE "error|ERROR|critical|CRITICAL" /var/log/messages 2>/dev/null || echo "0")
elif [ -f "/var/log/syslog" ]; then
sys_errors=$(grep -cE "error|ERROR|critical|CRITICAL" /var/log/syslog 2>/dev/null || echo "0")
fi
if [ "$sys_errors" -gt 0 ]; then
output_result "SYSLOG_ERRORS" "$sys_errors"
fi
}
# ==================== 主检测流程 ====================
main() {
log_info "开始应用日志分析..."
check_app_log_errors
check_container_log_errors
check_system_log_errors
log_info "应用日志分析完成"
}
main
#!/bin/bash
################################################################################
# Nacos深度检测模块
# 功能: 深度检测Nacos服务实例、配置数量、健康状态、Raft集群等
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
exit 1
fi
# Nacos容器名称
NACOS_CONTAINER="${CONTAINERS[nacos]}"
# ==================== 辅助函数 ====================
nacos_exec() {
docker exec "$NACOS_CONTAINER" $@ 2>/dev/null
}
nacos_api() {
local endpoint=$1
nacos_exec curl -s "http://localhost:8848/nacos/$endpoint" 2>/dev/null
}
# ==================== 深度检测函数 ====================
# 检测Nacos版本
check_nacos_version() {
local nacos_version
nacos_version=$(nacos_exec cat /home/nacos/version.txt 2>/dev/null | head -1)
if [ -n "$nacos_version" ]; then
output_result "NACOS_VERSION" "$nacos_version"
else
# 尝试从启动日志获取版本
nacos_version=$(nacos_exec cat /home/nacos/logs/start.out 2>/dev/null | grep "Nacos" | head -1)
[ -n "$nacos_version" ] && output_result "NACOS_VERSION" "$nacos_version"
fi
}
# 检测Nacos服务实例统计
check_nacos_services() {
# 获取命名空间列表
local namespaces
namespaces=$(nacos_api "v1/console/namespaces" 2>/dev/null)
if [ -n "$namespaces" ]; then
local namespace_count
namespace_count=$(echo "$namespaces" | grep -o "namespaceId" | wc -l)
output_result "NACOS_NAMESPACES" "$namespace_count"
fi
# 获取服务列表(默认命名空间)
local services
services=$(nacos_api "v1/ns/service/list?pageNo=1&pageSize=100&namespaceId=" 2>/dev/null)
if [ -n "$services" ]; then
local service_count
service_count=$(echo "$services" | grep -o '"count":[0-9]*' | cut -d: -f2 | head -1)
[ -n "$service_count" ] && output_result "NACOS_SERVICES_COUNT" "$service_count"
fi
}
# 检测Nacos实例统计
check_nacos_instances() {
local instances
instances=$(nacos_api "v1/ns/instance/list?pageNo=1&pageSize=100&namespaceId=" 2>/dev/null)
if [ -n "$instances" ]; then
local instance_count
instance_count=$(echo "$instances" | grep -o '"count":[0-9]*' | cut -d: -f2 | head -1)
[ -n "$instance_count" ] && output_result "NACOS_INSTANCES_COUNT" "$instance_count"
local healthy_count
healthy_count=$(echo "$instances" | grep -o '"healthyInstanceCount":[0-9]*' | cut -d: -f2 | head -1)
[ -n "$healthy_count" ] && output_result "NACOS_HEALTHY_INSTANCES" "$healthy_count"
# 计算健康率
if [ -n "$instance_count" ] && [ -n "$healthy_count" ] && [ "$instance_count" -gt 0 ]; then
local health_rate=$((healthy_count * 100 / instance_count))
output_result "NACOS_HEALTH_RATE" "${health_rate}%"
fi
fi
}
# 检测Nacos配置统计
check_nacos_configs() {
local configs
configs=$(nacos_api "v1/cs/configs?dataId=&group=&pageNo=1&pageSize=10&tenant=" 2>/dev/null)
if [ -n "$configs" ]; then
local config_count
config_count=$(echo "$configs" | grep -o '"total":[0-9]*' | cut -d: -f2 | head -1)
[ -n "$config_count" ] && output_result "NACOS_CONFIGS_COUNT" "$config_count"
fi
}
# 检测Nacos Raft集群状态
check_nacos_raft() {
local raft_info
raft_info=$(nacos_api "v1/ns/raft/state" 2>/dev/null)
if [ -n "$raft_info" ]; then
if echo "$raft_info" | grep -q "leader"; then
output_result "NACOS_RAFT_MODE" "是"
local role
role=$(echo "$raft_info" | grep -o '"role":"[^"]*"' | cut -d'"' -f4 | head -1)
[ -n "$role" ] && output_result "NACOS_RAFT_ROLE" "$role"
local node_count
node_count=$(echo "$raft_info" | grep -c "peer" || echo "0")
[ "$node_count" -gt 0 ] && output_result "NACOS_RAFT_NODES" "$node_count"
else
output_result "NACOS_RAFT_MODE" "否(单机模式)"
fi
fi
}
# 检测Nacos健康状态详情
check_nacos_health_detail() {
local health_status
health_status=$(nacos_api "v1/console/health/readiness" 2>/dev/null)
if [ -z "$health_status" ]; then
health_status=$(nacos_api "actuator/health" 2>/dev/null)
fi
if [ -z "$health_status" ]; then
health_status=$(nacos_exec curl -s -o /dev/null -w "%{http_code}" "http://localhost:8848/nacos/" 2>/dev/null)
if [ "$health_status" = "200" ] || [ "$health_status" = "302" ]; then
health_status="UP"
fi
fi
if [ -n "$health_status" ]; then
if echo "$health_status" | grep -qi "UP\|200\|302\|healthy"; then
output_result "NACOS_HEALTH_STATUS" "UP"
output_result "NACOS_HEALTH_LEVEL" "正常"
else
output_result "NACOS_HEALTH_STATUS" "DOWN"
output_result "NACOS_HEALTH_LEVEL" "严重"
fi
else
output_result "NACOS_HEALTH_STATUS" "DOWN"
output_result "NACOS_HEALTH_LEVEL" "严重"
fi
}
# 检测Nacos内存使用详情
check_nacos_memory_detail() {
local jvm_pid
jvm_pid=$(nacos_exec jps -l 2>/dev/null | grep nacos | awk '{print $1}')
if [ -n "$jvm_pid" ]; then
local heap_info
heap_info=$(nacos_exec jstat -gc "$jvm_pid" 2>/dev/null | tail -1)
if [ -n "$heap_info" ]; then
local heap_used heap_capacity
heap_used=$(echo "$heap_info" | awk '{print $4}' | tr -d ' ')
heap_capacity=$(echo "$heap_info" | awk '{print $6}' | tr -d ' ')
if [ -n "$heap_used" ] && [ -n "$heap_capacity" ] && [ "$heap_capacity" -gt 0 ]; then
local heap_usage=$((heap_used * 100 / heap_capacity))
output_result "NACOS_HEAP_USAGE" "${heap_usage}%"
fi
fi
fi
}
# 检测Nacos日志
check_nacos_logs() {
local log_size
log_size=$(nacos_exec du -sh /home/nacos/logs 2>/dev/null | awk '{print $1}')
if [ -n "$log_size" ]; then
output_result "NACOS_LOG_SIZE" "$log_size"
fi
local error_count
error_count=$(nacos_exec tail -100 /home/nacos/logs/nacos.log 2>/dev/null | grep -c "ERROR" || echo "0")
output_result "NACOS_RECENT_ERRORS" "$error_count"
}
# 检测Nacos容器资源
check_nacos_resources() {
local cpu_percent
cpu_percent=$(docker stats --no-stream --format '{{.CPUPerc}}' "$NACOS_CONTAINER" 2>/dev/null | tr -d '%')
if [ -n "$cpu_percent" ]; then
output_result "NACOS_CPU_USAGE" "$cpu_percent"
fi
local mem_usage
mem_usage=$(docker stats --no-stream --format '{{.MemUsage}}' "$NACOS_CONTAINER" 2>/dev/null)
if [ -n "$mem_usage" ]; then
output_result "NACOS_MEMORY_USAGE" "$mem_usage"
fi
local mem_percent
mem_percent=$(docker stats --no-stream --format '{{.MemPerc}}' "$NACOS_CONTAINER" 2>/dev/null | tr -d '%')
if [ -n "$mem_percent" ]; then
output_result "NACOS_MEMORY_PERCENT" "$mem_percent"
fi
}
# ==================== 主检测流程 ====================
main() {
log_info "开始Nacos深度检测..."
# 检查容器状态(使用模糊匹配)
local matched_container=""
matched_container=$(docker ps --format "{{.Names}}" | grep -x "${NACOS_CONTAINER}" | head -1)
if [ -z "$matched_container" ] && [ -n "$NACOS_CONTAINER" ]; then
matched_container=$(docker ps --format "{{.Names}}" | grep -i "${NACOS_CONTAINER}" | head -1)
fi
if [ -z "$matched_container" ]; then
log_warn "Nacos容器未运行"
output_result "NACOS_CONTAINER_STATUS" "未运行"
return 1
fi
eval "NACOS_CONTAINER='${matched_container}'"
output_result "NACOS_CONTAINER_STATUS" "运行中 (${NACOS_CONTAINER})"
# 执行各项深度检测
check_nacos_version 2>/dev/null || true
check_nacos_services 2>/dev/null || true
check_nacos_instances 2>/dev/null || true
check_nacos_configs 2>/dev/null || true
check_nacos_raft 2>/dev/null || true
check_nacos_health_detail 2>/dev/null || true
check_nacos_memory_detail 2>/dev/null || true
check_nacos_logs 2>/dev/null || true
check_nacos_resources 2>/dev/null || true
log_info "Nacos深度检测完成"
}
main
#!/bin/bash
################################################################################
# 综合诊断检测模块
# 功能: 汇总所有检测异常,进行核心问题诊断和历史对比分析
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
fi
# ==================== 检测函数 ====================
# 诊断系统负载
diagnose_system_load() {
local load1
load1=$(cat /proc/loadavg 2>/dev/null | awk '{print $1}')
if [ -n "$load1" ]; then
local cpu_count
cpu_count=$(nproc 2>/dev/null || echo "1")
local load_per_cpu
load_per_cpu=$(awk "BEGIN {printf \"%.2f\", $load1 / $cpu_count}")
output_result "DIAG_LOAD_1MIN" "$load1"
output_result "DIAG_LOAD_PER_CPU" "$load_per_cpu"
local level="正常"
if [ $(awk "BEGIN {print ($load_per_cpu > 4)}") -eq 1 ]; then
level="严重"
elif [ $(awk "BEGIN {print ($load_per_cpu > 2)}") -eq 1 ]; then
level="警告"
fi
output_result "DIAG_LOAD_LEVEL" "$level"
fi
}
# 诊断内存压力
diagnose_memory_pressure() {
local mem_info
mem_info=$(free -m 2>/dev/null | grep "Mem:")
if [ -n "$mem_info" ]; then
local total used free
total=$(echo "$mem_info" | awk '{print $2}')
used=$(echo "$mem_info" | awk '{print $3}')
free=$(echo "$mem_info" | awk '{print $4}')
local mem_usage
mem_usage=$(awk "BEGIN {printf \"%.1f\", ($used / $total) * 100}")
output_result "DIAG_MEMORY_USAGE" "${mem_usage}%"
output_result "DIAG_MEMORY_TOTAL" "${total}MB"
output_result "DIAG_MEMORY_USED" "${used}MB"
output_result "DIAG_MEMORY_FREE" "${free}MB"
local level="正常"
if [ $(awk "BEGIN {print ($mem_usage > 95)}") -eq 1 ]; then
level="严重"
elif [ $(awk "BEGIN {print ($mem_usage > 85)}") -eq 1 ]; then
level="警告"
fi
output_result "DIAG_MEMORY_LEVEL" "$level"
fi
}
# 诊断磁盘使用
diagnose_disk_usage() {
local disk_info
disk_info=$(df -h / 2>/dev/null | tail -1)
if [ -n "$disk_info" ]; then
local usage
usage=$(echo "$disk_info" | awk '{print $5}' | tr -d '%')
output_result "DIAG_DISK_USAGE" "${usage}%"
local level="正常"
if [ "$usage" -gt 95 ]; then
level="严重"
elif [ "$usage" -gt 85 ]; then
level="警告"
fi
output_result "DIAG_DISK_LEVEL" "$level"
fi
}
# 诊断Docker容器状态
diagnose_docker_status() {
if ! command -v docker &>/dev/null; then
return
fi
local total running stopped
total=$(docker ps -a --format "{{.Names}}" 2>/dev/null | wc -l)
running=$(docker ps --format "{{.Names}}" 2>/dev/null | wc -l)
stopped=$((total - running))
output_result "DIAG_DOCKER_TOTAL" "$total"
output_result "DIAG_DOCKER_RUNNING" "$running"
output_result "DIAG_DOCKER_STOPPED" "$stopped"
if [ "$stopped" -gt 5 ]; then
output_result "DIAG_DOCKER_LEVEL" "警告"
else
output_result "DIAG_DOCKER_LEVEL" "正常"
fi
}
# 诊断系统稳定性
diagnose_system_stability() {
local issues=0
# 检查OOM
if command -v dmesg &>/dev/null; then
local oom_count
oom_count=$(dmesg 2>/dev/null | grep -ci "out of memory" || echo "0")
if [ "$oom_count" -gt 0 ]; then
issues=$((issues + oom_count))
output_result "DIAG_OOM_ISSUES" "$oom_count"
fi
fi
# 检查磁盘错误
if command -v dmesg &>/dev/null; then
local disk_errors
disk_errors=$(dmesg 2>/dev/null | grep -ciE "I/O error|disk error" || echo "0")
if [ "$disk_errors" -gt 0 ]; then
issues=$((issues + disk_errors))
output_result "DIAG_DISK_ISSUES" "$disk_errors"
fi
fi
output_result "DIAG_TOTAL_ISSUES" "$issues"
if [ "$issues" -gt 10 ]; then
output_result "DIAG_STABILITY_LEVEL" "严重"
elif [ "$issues" -gt 0 ]; then
output_result "DIAG_STABILITY_LEVEL" "警告"
else
output_result "DIAG_STABILITY_LEVEL" "正常"
fi
}
# 诊断网络连通性
diagnose_network() {
local gateway
gateway=$(ip route 2>/dev/null | grep default | awk '{print $3}' | head -1)
if [ -n "$gateway" ]; then
output_result "DIAG_GATEWAY" "$gateway"
if ping -c 1 -W 2 "$gateway" &>/dev/null; then
output_result "DIAG_GATEWAY_STATUS" "可达"
else
output_result "DIAG_GATEWAY_STATUS" "不可达"
output_result "DIAG_NETWORK_LEVEL" "警告"
fi
fi
# 检查DNS解析
if host localhost &>/dev/null || nslookup localhost &>/dev/null; then
output_result "DIAG_DNS_STATUS" "正常"
else
output_result "DIAG_DNS_STATUS" "异常"
fi
}
# 综合健康评分
calculate_health_score() {
local score=100
# 内存扣分
local mem_info
mem_info=$(free -m 2>/dev/null | grep "Mem:")
if [ -n "$mem_info" ]; then
local total used
total=$(echo "$mem_info" | awk '{print $2}')
used=$(echo "$mem_info" | awk '{print $3}')
local mem_usage=$((used * 100 / total))
if [ "$mem_usage" -gt 95 ]; then
score=$((score - 20))
elif [ "$mem_usage" -gt 85 ]; then
score=$((score - 10))
fi
fi
# 磁盘扣分
local disk_usage
disk_usage=$(df / 2>/dev/null | tail -1 | awk '{print $5}' | tr -d '%')
if [ -n "$disk_usage" ]; then
if [ "$disk_usage" -gt 95 ]; then
score=$((score - 20))
elif [ "$disk_usage" -gt 85 ]; then
score=$((score - 10))
fi
fi
# 负载扣分
local load1
load1=$(cat /proc/loadavg 2>/dev/null | awk '{print $1}')
local cpu_count
cpu_count=$(nproc 2>/dev/null || echo "1")
if [ -n "$load1" ]; then
local load_ratio
load_ratio=$(awk "BEGIN {print $load1 / $cpu_count}")
if [ $(awk "BEGIN {print ($load_ratio > 4)}") -eq 1 ]; then
score=$((score - 15))
elif [ $(awk "BEGIN {print ($load_ratio > 2)}") -eq 1 ]; then
score=$((score - 5))
fi
fi
output_result "DIAG_HEALTH_SCORE" "$score"
if [ "$score" -ge 80 ]; then
output_result "DIAG_HEALTH_LEVEL" "正常"
elif [ "$score" -ge 60 ]; then
output_result "DIAG_HEALTH_LEVEL" "警告"
else
output_result "DIAG_HEALTH_LEVEL" "严重"
fi
}
# ==================== 主检测流程 ====================
main() {
log_info "开始综合诊断检测..."
set +e
diagnose_system_load 2>/dev/null || true
diagnose_memory_pressure 2>/dev/null || true
diagnose_disk_usage 2>/dev/null || true
diagnose_docker_status 2>/dev/null || true
diagnose_system_stability 2>/dev/null || true
diagnose_network 2>/dev/null || true
calculate_health_score 2>/dev/null || true
log_info "综合诊断检测完成"
}
main
\ No newline at end of file
#!/bin/bash
################################################################################
# 安全合规检测模块
# 功能: 检测系统安全状态、认证失败、异常账户、防火墙规则等
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
fi
# ==================== 检测函数 ====================
# 检测认证失败历史
check_auth_failures() {
local auth_fail_count=0
if [ -f "/var/log/secure" ]; then
auth_fail_count=$(grep -c "Failed password" /var/log/secure 2>/dev/null || echo "0")
elif [ -f "/var/log/auth.log" ]; then
auth_fail_count=$(grep -c "Failed password" /var/log/auth.log 2>/dev/null || echo "0")
fi
output_result "AUTH_FAILURES_24H" "$auth_fail_count"
if [ "$auth_fail_count" -gt 1000 ]; then
output_result "AUTH_FAILURES_LEVEL" "严重"
elif [ "$auth_fail_count" -gt 100 ]; then
output_result "AUTH_FAILURES_LEVEL" "警告"
else
output_result "AUTH_FAILURES_LEVEL" "正常"
fi
}
# 检测当前登录用户
check_current_users() {
local current_users=""
local user_count="0"
if command -v who &>/dev/null; then
current_users=$(who 2>/dev/null)
if [ -n "$current_users" ]; then
user_count=$(echo "$current_users" | wc -l)
fi
fi
output_result "CURRENT_USERS_COUNT" "${user_count:-0}"
if [ -n "$current_users" ] && [ "$user_count" -gt 0 ]; then
local users_list
users_list=$(echo "$current_users" | cut -d' ' -f1 | tr '\n' ',' | sed 's/,$//' 2>/dev/null)
[ -n "$users_list" ] && output_result "CURRENT_USERS" "$users_list"
fi
}
# 检测防火墙规则
check_firewall_rules() {
if command -v firewall-cmd &>/dev/null; then
if systemctl is-active --quiet firewalld 2>/dev/null; then
output_result "FIREWALL_STATUS" "firewalld运行中"
else
output_result "FIREWALL_STATUS" "firewalld未运行"
fi
fi
if command -v iptables &>/dev/null; then
local iptables_rules
iptables_rules=$(iptables -L -n 2>/dev/null)
if [ -n "$iptables_rules" ]; then
output_result "IPTABLES_STATUS" "iptables已配置"
output_result "IPTABLES_RULES_COUNT" "$(echo "$iptables_rules" | grep -c "^Chain" || echo "0")"
fi
fi
local open_ports
open_ports=$(ss -tlnp 2>/dev/null | grep LISTEN | awk '{print $4}' | grep -oE '[0-9]+$' | sort -u | wc -l)
output_result "OPEN_PORTS_COUNT" "$open_ports"
}
# 检测异常账户(UID=0的非root账户)
check_abnormal_accounts() {
local abnormal_accounts=""
if [ -r "/etc/passwd" ]; then
while IFS=: read -r username x uid rest; do
if [ "$uid" = "0" ] && [ "$username" != "root" ]; then
if [ -z "$abnormal_accounts" ]; then
abnormal_accounts="$username"
else
abnormal_accounts="$abnormal_accounts,$username"
fi
fi
done < /etc/passwd 2>/dev/null || true
fi
if [ -n "$abnormal_accounts" ]; then
output_result "ABNORMAL_ACCOUNTS" "$abnormal_accounts"
output_result "ABNORMAL_ACCOUNTS_LEVEL" "严重"
else
output_result "ABNORMAL_ACCOUNTS" "无"
output_result "ABNORMAL_ACCOUNTS_LEVEL" "正常"
fi
}
# 检测SSH配置安全检查
check_ssh_security() {
local ssh_config="/etc/ssh/sshd_config"
if [ -f "$ssh_config" ]; then
local permit_root
permit_root=$(grep -E "^PermitRootLogin" "$ssh_config" 2>/dev/null | grep -v "^#" | awk '{print $2}')
output_result "SSH_PERMIT_ROOT" "${permit_root:-未设置}"
local password_auth
password_auth=$(grep -E "^PasswordAuthentication" "$ssh_config" 2>/dev/null | grep -v "^#" | awk '{print $2}')
output_result "SSH_PASSWORD_AUTH" "${password_auth:-未设置}"
local ssh_port
ssh_port=$(grep -E "^Port" "$ssh_config" 2>/dev/null | grep -v "^#" | awk '{print $2}')
output_result "SSH_PORT" "${ssh_port:-22}"
if [ "$permit_root" = "yes" ]; then
output_result "SSH_ROOT_LOGIN_LEVEL" "严重"
else
output_result "SSH_ROOT_LOGIN_LEVEL" "正常"
fi
fi
}
# 检测开放端口详情
check_open_ports_detail() {
local tcp_ports
tcp_ports=$(ss -tlnp 2>/dev/null | grep LISTEN | awk '{print $4}' | grep -oE '[0-9]+$' | sort -nu | tr '\n' ',' | sed 's/,$//')
output_result "OPEN_TCP_PORTS" "$tcp_ports"
# 高风险端口
local high_risk_ports="23,135,139,445,1433,3389,5900,5901"
local found_risk_ports=""
for port in ${high_risk_ports//,/ }; do
if ss -tlnp 2>/dev/null | grep -q ":$port "; then
[ -z "$found_risk_ports" ] && found_risk_ports="$port" || found_risk_ports="$found_risk_ports,$port"
fi
done
if [ -n "$found_risk_ports" ]; then
output_result "HIGH_RISK_PORTS" "$found_risk_ports"
output_result "HIGH_RISK_PORTS_LEVEL" "警告"
else
output_result "HIGH_RISK_PORTS" "无"
output_result "HIGH_RISK_PORTS_LEVEL" "正常"
fi
}
# 检测暴力破解IP
check_brute_force_ips() {
local brute_force_ips=""
if [ -f "/var/log/secure" ]; then
brute_force_ips=$(grep "Failed password" /var/log/secure 2>/dev/null | grep -oE 'from [0-9.]+' | cut -d' ' -f2 | sort | uniq -c | sort -rn | head -5)
elif [ -f "/var/log/auth.log" ]; then
brute_force_ips=$(grep "Failed password" /var/log/auth.log 2>/dev/null | grep -oE 'from [0-9.]+' | cut -d' ' -f2 | sort | uniq -c | sort -rn | head -5)
fi
if [ -n "$brute_force_ips" ]; then
local max_attempts
max_attempts=$(echo "$brute_force_ips" | head -1 | awk '{print $1}')
output_result "MAX_LOGIN_FAILURES" "$max_attempts"
output_result "BRUTE_FORCE_IPS" "$(echo "$brute_force_ips" | sed 's/ /:/g' | tr '\n' ',' | sed 's/,$//')"
if [ "$max_attempts" -gt 100 ]; then
output_result "BRUTE_FORCE_LEVEL" "严重"
elif [ "$max_attempts" -gt 20 ]; then
output_result "BRUTE_FORCE_LEVEL" "警告"
else
output_result "BRUTE_FORCE_LEVEL" "正常"
fi
else
output_result "MAX_LOGIN_FAILURES" "0"
output_result "BRUTE_FORCE_LEVEL" "正常"
fi
}
# ==================== 主检测流程 ====================
main() {
log_info "开始安全合规检测..."
set +e
check_auth_failures 2>/dev/null || true
check_current_users 2>/dev/null || true
check_firewall_rules 2>/dev/null || true
check_abnormal_accounts 2>/dev/null || true
check_ssh_security 2>/dev/null || true
check_open_ports_detail 2>/dev/null || true
check_brute_force_ips 2>/dev/null || true
log_info "安全合规检测完成"
}
main
\ No newline at end of file
#!/bin/bash
################################################################################
# 系统日志检测模块
# 功能: 检测内核错误、磁盘错误、服务崩溃、系统资源耗尽等日志问题
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
fi
# ==================== 检测函数 ====================
# 检测内核错误
check_kernel_errors() {
local kernel_errors=0
if command -v dmesg &>/dev/null; then
kernel_errors=$(dmesg 2>/dev/null | grep -iE "error|fail|timeout" | grep -v "ACPI" | wc -l || echo "0")
fi
output_result "KERNEL_ERRORS_24H" "${kernel_errors:-0}"
if [ "$kernel_errors" -gt 100 ]; then
output_result "KERNEL_ERRORS_LEVEL" "严重"
elif [ "$kernel_errors" -gt 10 ]; then
output_result "KERNEL_ERRORS_LEVEL" "警告"
else
output_result "KERNEL_ERRORS_LEVEL" "正常"
fi
}
# 检测磁盘错误
check_disk_errors() {
local disk_errors=0
if command -v dmesg &>/dev/null; then
disk_errors=$(dmesg 2>/dev/null | grep -ciE "I/O error|disk error|ata error|sd.*error|nvme.*error|filesystem error" || echo "0")
fi
output_result "DISK_ERRORS_24H" "${disk_errors:-0}"
if [ "$disk_errors" -gt 10 ]; then
output_result "DISK_ERRORS_LEVEL" "严重"
elif [ "$disk_errors" -gt 0 ]; then
output_result "DISK_ERRORS_LEVEL" "警告"
else
output_result "DISK_ERRORS_LEVEL" "正常"
fi
}
# 检测内核panic/oops
check_kernel_panic() {
local panic_count=0
local oops_count=0
if command -v dmesg &>/dev/null; then
panic_count=$(dmesg 2>/dev/null | grep -ci "kernel panic" || echo "0")
oops_count=$(dmesg 2>/dev/null | grep -ci "kernel oops\|BUG:" || echo "0")
fi
output_result "KERNEL_PANIC_COUNT" "$panic_count"
output_result "KERNEL_OOPS_COUNT" "$oops_count"
if [ "$panic_count" -gt 0 ]; then
output_result "KERNEL_STABILITY_LEVEL" "严重"
elif [ "$oops_count" -gt 5 ]; then
output_result "KERNEL_STABILITY_LEVEL" "警告"
else
output_result "KERNEL_STABILITY_LEVEL" "正常"
fi
}
# 检测服务崩溃重启记录
check_service_crashes() {
local crash_count=0
local crashed_services=""
if command -v docker &>/dev/null; then
local restarted_containers
restarted_containers=$(docker ps -a --format "{{.Names}}: {{.RestartCount}}" 2>/dev/null | grep -v ": 0$" | grep -v ": $")
if [ -n "$restarted_containers" ]; then
crash_count=$(echo "$restarted_containers" | wc -l)
crashed_services=$(echo "$restarted_containers" | tr '\n' ',' | sed 's/,$//')
fi
fi
output_result "SERVICE_CRASH_COUNT" "$crash_count"
if [ -n "$crashed_services" ]; then
output_result "CRASHED_SERVICES" "$crashed_services"
fi
if [ "$crash_count" -gt 5 ]; then
output_result "SERVICE_STABILITY_LEVEL" "严重"
elif [ "$crash_count" -gt 0 ]; then
output_result "SERVICE_STABILITY_LEVEL" "警告"
else
output_result "SERVICE_STABILITY_LEVEL" "正常"
fi
}
# 检测systemd服务失败列表
check_systemd_failures() {
if ! command -v systemctl &>/dev/null; then
return
fi
local failed_services
failed_services=$(systemctl list-units --state=failed --no-legend 2>/dev/null | awk '{print $1}' | tr '\n' ',' | sed 's/,$//')
if [ -n "$failed_services" ]; then
local failed_count
failed_count=$(echo "$failed_services" | tr ',' '\n' | wc -l)
output_result "SYSTEMD_FAILED_COUNT" "$failed_count"
output_result "SYSTEMD_FAILED_SERVICES" "$failed_services"
output_result "SYSTEMD_FAILED_LEVEL" "严重"
else
output_result "SYSTEMD_FAILED_COUNT" "0"
output_result "SYSTEMD_FAILED_LEVEL" "正常"
fi
}
# 检测OOM Killer记录
check_oom_killer() {
local oom_count=0
if command -v dmesg &>/dev/null; then
oom_count=$(dmesg 2>/dev/null | grep -ci "out of memory" || echo "0")
fi
output_result "OOM_KILLER_COUNT" "$oom_count"
if [ "$oom_count" -gt 0 ]; then
output_result "OOM_LEVEL" "严重"
else
output_result "OOM_LEVEL" "正常"
fi
}
# 检测日志文件大小
check_log_file_sizes() {
local large_logs=""
for log_file in /var/log/messages /var/log/syslog /var/log/kern.log; do
if [ -f "$log_file" ]; then
local log_size
log_size=$(du -m "$log_file" 2>/dev/null | awk '{print $1}')
if [ "$log_size" -gt 500 ]; then
local log_name
log_name=$(basename "$log_file")
large_logs="${large_logs}${log_name}:${log_size}MB,"
fi
fi
done
large_logs=$(echo "$large_logs" | sed 's/,$//')
if [ -n "$large_logs" ]; then
output_result "LARGE_LOG_FILES" "$large_logs"
output_result "LARGE_LOG_FILES_LEVEL" "警告"
else
output_result "LARGE_LOG_FILES" "无"
output_result "LARGE_LOG_FILES_LEVEL" "正常"
fi
}
# 检测/var/log/messages
check_messages_log() {
local messages_file="/var/log/messages"
if [ ! -f "$messages_file" ]; then
if [ -f "/var/log/syslog" ]; then
messages_file="/var/log/syslog"
else
return
fi
fi
local error_count warn_count
error_count=$(grep -c "ERROR" "$messages_file" 2>/dev/null || echo "0")
warn_count=$(grep -c "WARN" "$messages_file" 2>/dev/null || echo "0")
output_result "MESSAGES_ERRORS_COUNT" "$error_count"
output_result "MESSAGES_WARNS_COUNT" "$warn_count"
local log_size
log_size=$(du -h "$messages_file" 2>/dev/null | awk '{print $1}')
output_result "MESSAGES_LOG_SIZE" "$log_size"
}
# ==================== 主检测流程 ====================
main() {
log_info "开始系统日志检测..."
set +e
check_kernel_errors 2>/dev/null || true
check_disk_errors 2>/dev/null || true
check_kernel_panic 2>/dev/null || true
check_service_crashes 2>/dev/null || true
check_systemd_failures 2>/dev/null || true
check_oom_killer 2>/dev/null || true
check_log_file_sizes 2>/dev/null || true
check_messages_log 2>/dev/null || true
log_info "系统日志检测完成"
}
main
\ No newline at end of file
#!/bin/bash
################################################################################
# 时间同步检测模块
# 功能: 检测NTP同步状态、时钟偏差、SSL证书有效期等
# 作者: Claude Code
# 日期: 2026-07-20
################################################################################
# 获取脚本所在目录并加载依赖
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="${LIB_DIR:-/tmp/check_modules}"
# 加载配置文件和通用函数库
if [ -f "$LIB_DIR/lib/config.sh" ]; then
source "$LIB_DIR/lib/config.sh"
else
echo "ERROR: 配置文件不存在: $LIB_DIR/lib/config.sh"
exit 1
fi
if [ -f "$LIB_DIR/lib/common.sh" ]; then
source "$LIB_DIR/lib/common.sh"
else
echo "ERROR: 通用函数库不存在: $LIB_DIR/lib/common.sh"
exit 1
fi
# ==================== 检测函数 ====================
# 检测NTP同步状态
check_ntp_status() {
if command -v timedatectl &>/dev/null; then
local timedate_output
timedate_output=$(timedatectl status 2>/dev/null)
if echo "$timedate_output" | grep -q "NTP service: active"; then
output_result "NTP_SERVICE_STATUS" "运行中"
elif echo "$timedate_output" | grep -q "NTP enabled: yes"; then
output_result "NTP_SERVICE_STATUS" "已启用"
else
output_result "NTP_SERVICE_STATUS" "未启用"
output_result "NTP_SERVICE_LEVEL" "警告"
fi
if echo "$timedate_output" | grep -q "System clock synchronized: yes"; then
output_result "SYSTEM_CLOCK_SYNC" "已同步"
else
output_result "SYSTEM_CLOCK_SYNC" "未同步"
output_result "SYSTEM_CLOCK_SYNC_LEVEL" "警告"
fi
fi
# 检查NTP守护进程
if systemctl is-active --quiet chronyd 2>/dev/null; then
output_result "NTP_DAEMON" "chronyd"
elif systemctl is-active --quiet ntpd 2>/dev/null; then
output_result "NTP_DAEMON" "ntpd"
elif systemctl is-active --quiet systemd-timesyncd 2>/dev/null; then
output_result "NTP_DAEMON" "systemd-timesyncd"
fi
}
# 检测时钟同步源
check_ntp_sources() {
local sources=""
local current_source=""
if command -v chronyc &>/dev/null; then
local chronyc_sources
chronyc_sources=$(chronyc sources 2>/dev/null)
if [ -n "$chronyc_sources" ]; then
sources=$(echo "$chronyc_sources" | grep "^[\*\+\#]" | awk '{print $2}' | tr '\n' ',' | sed 's/,$//')
current_source=$(echo "$chronyc_sources" | grep "^\*" | awk '{print $2}' | head -1)
output_result "NTP_SOURCES" "$sources"
if [ -n "$current_source" ]; then
output_result "NTP_CURRENT_SOURCE" "$current_source"
fi
fi
fi
if [ -z "$sources" ] && command -v ntpq &>/dev/null; then
local ntpq_output
ntpq_output=$(ntpq -p 2>/dev/null)
if [ -n "$ntpq_output" ]; then
sources=$(echo "$ntpq_output" | grep "^[\*\+\+\#]" | awk '{print $1}' | tr '\n' ',' | sed 's/,$//')
current_source=$(echo "$ntpq_output" | grep "^\*" | awk '{print $1}' | head -1)
output_result "NTP_SOURCES" "$sources"
if [ -n "$current_source" ]; then
output_result "NTP_CURRENT_SOURCE" "$current_source"
fi
fi
fi
}
# 检测时钟偏差
check_clock_offset() {
local offset_ms="未知"
local offset_level="正常"
if command -v chronyc &>/dev/null; then
local chronyc_tracking
chronyc_tracking=$(chronyc tracking 2>/dev/null)
if [ -n "$chronyc_tracking" ]; then
offset_ms=$(echo "$chronyc_tracking" | grep "RMS offset" | awk '{print $4}')
if [ -n "$offset_ms" ] && [ "$offset_ms" != "未知" ]; then
output_result "NTP_OFFSET_MS" "$offset_ms"
local offset_abs
offset_abs=$(awk "BEGIN {print ($offset_ms < 0) ? -$offset_ms : $offset_ms}")
if [ "$offset_abs" -gt 5000000 ]; then
offset_level="严重"
elif [ "$offset_abs" -gt 1000000 ]; then
offset_level="警告"
fi
fi
fi
fi
output_result "NTP_OFFSET_LEVEL" "$offset_level"
}
# 检测系统时间
check_system_time() {
local system_date
system_date=$(date 2>/dev/null)
output_result "SYSTEM_DATETIME" "$system_date"
local system_timestamp
system_timestamp=$(date +%s 2>/dev/null)
output_result "SYSTEM_TIMESTAMP" "$system_timestamp"
local timezone
timezone=$(timedatectl status 2>/dev/null | grep "Time zone" | awk '{print $3}')
[ -n "$timezone" ] && output_result "SYSTEM_TIMEZONE" "$timezone"
}
# 检测HTTPS证书有效期
check_https_cert_expiry() {
local cert_files=""
for cert_path in /etc/nginx/ssl/*.crt /etc/nginx/certs/*.crt /etc/ssl/certs/*.crt; do
if [ -f "$cert_path" ]; then
cert_files="${cert_files}${cert_path},"
fi
done
cert_files=$(echo "$cert_files" | sed 's/,$//')
if [ -n "$cert_files" ]; then
local min_days=9999
for cert in ${cert_files//,/ }; do
if [ -f "$cert" ]; then
local expiry_date
expiry_date=$(openssl x509 -in "$cert" -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -n "$expiry_date" ]; then
local expiry_timestamp
expiry_timestamp=$(date -d "$expiry_date" +%s 2>/dev/null)
if [ -n "$expiry_timestamp" ]; then
local current_timestamp
current_timestamp=$(date +%s)
local days_left=$(( (expiry_timestamp - current_timestamp) / 86400 ))
if [ "$days_left" -lt "$min_days" ]; then
min_days=$days_left
fi
fi
fi
fi
done
if [ "$min_days" -lt 9999 ]; then
output_result "HTTPS_CERT_MIN_DAYS" "$min_days"
if [ "$min_days" -le 7 ]; then
output_result "HTTPS_CERT_LEVEL" "严重"
elif [ "$min_days" -le 30 ]; then
output_result "HTTPS_CERT_LEVEL" "警告"
else
output_result "HTTPS_CERT_LEVEL" "正常"
fi
fi
else
output_result "HTTPS_CERT_STATUS" "未找到证书文件"
fi
}
# 检测系统运行时间
check_uptime() {
local uptime_seconds
uptime_seconds=$(cat /proc/uptime 2>/dev/null | awk '{print $1}' | cut -d. -f1)
if [ -n "$uptime_seconds" ]; then
local uptime_days
uptime_days=$((uptime_seconds / 86400))
output_result "SYSTEM_UPTIME_DAYS" "$uptime_days"
fi
}
# ==================== 主检测流程 ====================
main() {
log_info "开始时间同步检测..."
set +e
check_ntp_status 2>/dev/null || true
check_ntp_sources 2>/dev/null || true
check_clock_offset 2>/dev/null || true
check_system_time 2>/dev/null || true
check_https_cert_expiry 2>/dev/null || true
check_uptime 2>/dev/null || true
log_info "时间同步检测完成"
}
main
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论