背景:
在1.0的基础上,保留原来的日常监控加告警的功能外,增加部分功能,修改展示样式,增加用户体验。之前没时间整理,先在项目上用了几天,稳定了才做。
思路:
从一个系统管理者的角度去改造。1.0是从运维者的角度。
开干:
java_health_checker2.0.sh

#!/bin/bash
# ==============================================================================
# Java服务状态监控脚本 (美观表格输出版)
# 功能:
# 1. 检查期望的服务列表是否运行。
# 2. 以美观的表格形式显示运行服务的详细状态。
# 3. 对停止的服务进行告警。
# 4. 支持邮件和企业微信两种告警方式。
# ==============================================================================
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m' # No Color
# ==============================================================================
# 初始化区域
# ==============================================================================
# 初始化停止服务的计数器
down_services_count=0
down_services_list=""
# ==============================================================================
# 配置区域:请在这里修改配置
# ==============================================================================
# --- 期望监控的服务列表 ---
# 格式: "服务名:端口号"
EXPECTED_SERVICES=(
"model:18286"
"esb:18285"
...........
)
# --- 邮件告警设置 (方案一) ---
EMAIL_ENABLED=true # true:启用, false:禁用
EMAIL_TO="*************@qq.com" # 接收告警的邮箱
EMAIL_SUBJECT="[*******] Java服务健康检查报告" # 邮件主题
# --- 企业微信告警设置 (方案二) ---
WECHAT_ENABLED=false # true:启用, false:禁用
# 请替换为您自己的企业微信机器人Webhook地址
WECHAT_WEBHOOK_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY_HERE"
# ==============================================================================
# 打印标题
echo -e "${BLUE}============================================${NC}"
echo -e "${BLUE} ***** $(hostname) Java服务健康巡检报告${NC}"
echo -e "${BLUE} $(date '+%Y-%m-%d %H:%M:%S')${NC}"
echo -e "${BLUE} 当前IP:$(hostname -I | awk '{print $1}')${NC}"
echo -e "${BLUE}============================================${NC}"
# 创建一个关联数组,用于存储正在运行的服务信息
declare -A running_services
# --- 1. 扫描并收集所有正在运行的Java服务信息 ---
echo -e "${GREEN}🔍 正在扫描当前运行的Java服务...${NC}"
echo ""
# 使用pgrep获取所有Java进程的PID
java_pids=$(pgrep -f java)
if [ -n "$java_pids" ]; then
for pid in $java_pids; do
# 获取完整命令行
full_cmd=$(ps -p $pid -o cmd=)
if [[ "$full_cmd" != *"java"* ]]; then
continue
fi
# 提取服务名和端口
service_name=$(echo "$full_cmd" | grep -oP 'SW_AGENT_NAME=\K[^ ]+' | head -1)
if [ -z "$service_name" ]; then
service_name=$(echo "$full_cmd" | grep -oP '\-jar\s+\K[^\.]+' | head -1)
fi
port=$(echo "$full_cmd" | grep -oP '(?:--|-D)server\.port=\K\d+' | head -1)
# 如果服务名和端口都有效,存入数组
if [ -n "$service_name" ] && [ -n "$port" ]; then
running_services["${service_name}:${port}"]="$pid"
fi
done
fi
# --- 2. 准备并打印美观的表格 ---
echo -e "${BLUE}📋 服务状态检查报告如下:${NC}"
echo ""
# 定义表格格式化函数
# 参数: $1=内容, $2=宽度, $3=对齐方式 (left/right)
format_cell() {
local content="$1"
local width="$2"
local align="${3:-left}"
local len=${#content}
# 移除ANSI颜色代码以计算真实长度
local plain_content=$(echo "$content" | sed 's/\x1b\[[0-9;]*m//g')
local plain_len=${#plain_content}
if [ "$align" == "right" ]; then
printf "%*s%s" $((width - plain_len)) "" "$content"
else
printf "%-*s%s" $((width - plain_len)) "" "$content"
fi
}
# 定义列宽
col1_width=20
col2_width=9
col3_width=8
col4_width=6
col5_width=8
col6_width=9
col7_width=8
col8_width=11
# 打印表头
printf "${CYAN}${BOLD}"
format_cell "SERVICE_NAME" $col1_width
format_cell "STATUS" $col2_width
format_cell "PID" $col3_width "right"
format_cell "PORT" $col4_width "right"
format_cell "CPU(%)" $col5_width "right"
format_cell "MEM(MB)" $col6_width "right"
format_cell "THREADS" $col7_width "right"
format_cell "UPTIME" $col8_width
printf "${NC}\n"
# 打印分隔线
printf '%.0s-' $(seq 1 $((col1_width + col2_width + col3_width + col4_width + col5_width + col6_width + col7_width + col8_width)))
printf "\n"
# 遍历期望的服务列表,填充并打印表格行
for expected_service in "${EXPECTED_SERVICES[@]}"; do
service_name=${expected_service%:*}
service_port=${expected_service#*:}
if [[ -n "${running_services[$expected_service]}" ]]; then
# 服务正在运行
pid=${running_services[$expected_service]}
# 获取运行时信息
etime=$(ps -p $pid -o etime= | tr -d ' ')
cpu_usage=$(ps -p $pid -o %cpu= | tr -d ' ')
mem_rss=$(ps -p $pid -o rss= | tr -d ' ')
threads=$(ps -p $pid -o nlwp= | tr -d ' ')
mem_rss_mb=$(echo "$mem_rss" | awk '{printf "%.0f", $1/1024}')
# 打印运行中的服务信息
format_cell "$service_name" $col1_width
printf "${GREEN}"
format_cell "RUNNING" $col2_width
printf "${NC}"
printf "${CYAN}"
format_cell "$pid" $col3_width "right"
printf "${NC}"
format_cell "$service_port" $col4_width "right"
format_cell "$cpu_usage" $col5_width "right"
format_cell "$mem_rss_mb" $col6_width "right"
format_cell "$threads" $col7_width "right"
format_cell "$etime" $col8_width
printf "\n"
else
# 服务停止或异常
((down_services_count++))
down_services_list="${down_services_list} ${service_name}"
# 打印停止的服务信息
format_cell "$service_name" $col1_width
printf "${RED}${BOLD}"
format_cell "DOWN" $col2_width
printf "${NC}"
format_cell "-" $col3_width "right"
format_cell "-" $col4_width "right"
format_cell "-" $col5_width "right"
format_cell "-" $col6_width "right"
format_cell "-" $col7_width "right"
format_cell "-" $col8_width
printf "\n"
fi
done
echo ""
# --- 3. 最终报告与告警发送 ---
echo -e "${BLUE}============================================${NC}"
if [ "$down_services_count" -eq 0 ]; then
echo -e "${GREEN}🎉 所有期望的服务都在正常运行!${NC}"
else
echo -e "${RED}⚠️ 发现 ${down_services_count} 个服务存在问题,请立即检查!${NC}"
# --- 发送邮件告警 ---
if [ "$EMAIL_ENABLED" = true ]; then
echo -e "${YELLOW}📧 正在发送告警邮件到 $EMAIL_TO ...${NC}"
email_body=$(cat <<EOF
服务器 $(hostname) 上的Java服务健康检查发现异常!
时间: $(date '+%Y-%m-%d %H:%M:%S')
异常服务数量: $down_services_count
异常服务列表:
$down_services_list
请登录服务器检查详细情况。
EOF
)
echo "$email_body" | mailx -s "$EMAIL_SUBJECT - [ALERT]" "$EMAIL_TO"
if [ $? -eq 0 ]; then
echo -e "${GREEN}✅ 告警邮件发送成功!${NC}"
else
echo -e "${RED}❌ 告警邮件发送失败!请检查邮件配置。${NC}"
fi
fi
# --- 发送企业微信告警 ---
if [ "$WECHAT_ENABLED" = true ]; then
echo -e "${YELLOW}📱 正在发送企业微信告警...${NC}"
# 构建JSON消息体
message=$(cat <<EOF
{
"msgtype": "markdown",
"markdown": {
"content": "<font color='warning'>【$(hostname)服务告警】</font>\n\n> 服务器: <code>prd1</code>\n> 时间: <code>$(date '+%Y-%m-%d %H:%M:%S')</code>\n> 异常服务数: <code>$down_services_count</code>\n> 异常列表: <code>${down_services_list//\\n/ }</code>\n\n请立即登录服务器检查!"
}
}
EOF
)
# 发送HTTP请求
curl -s -X POST "$WECHAT_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "$message" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "${GREEN}✅ 企业微信告警发送成功!${NC}"
else
echo -e "${RED}❌ 企业微信告警发送失败!请检查Webhook URL和网络。${NC}"
fi
fi
fi
echo -e "${BLUE}============================================${NC}"
# 如果有服务停止,脚本的退出码为1,便于告警系统识别
if [ "$down_services_count" -gt 0 ]; then
exit 1
fi
效果展示:


因为我配置了邮箱异常告警功能,所以有异常会发邮件提醒:

其他说明:
在此基础上,我们能做的还有很多,日常监控、异常告警、定期巡检。就看大家的发挥了。

1602

被折叠的 条评论
为什么被折叠?



