服务器监控
scripts/monitor.sh 每分钟检查服务状态与系统资源,异常时自动合并告警并推送到钉钉。
脚本可独立部署在任意服务器上,通过 PUSH_ENDPOINT 指向中央推送服务,
用 HOSTNAME 区分来源,不要求与推送服务同机。
检查项
脚本依次执行四类检查,任何一项异常都会进入告警汇总:
| 检查项 | 依据 | 告警条件 |
|---|---|---|
| systemd 服务 | systemctl is-active |
服务状态不是 active |
| 端口监听 | ss / lsof |
端口无进程监听 |
| 内存 | free -m |
使用率 ≥ 阈值 |
| 磁盘 | df -h |
挂载点使用率 ≥ 阈值 |
配置监控项
编辑 scripts/monitor.conf:
# 检查 systemd 服务是否运行(空格分隔,为空则不检查)
CHECK_SERVICES="nginx.service docker.service"
# 检查端口是否监听(空格分隔,为空则不检查)
CHECK_PORTS="80 443 8080"
# 内存使用率阈值(百分比,超过则告警)
MEMORY_THRESHOLD=80
# 磁盘使用率阈值(挂载点:百分比,空格分隔)
DISK_THRESHOLDS="/:80 /data:90"
# 告警消息中显示的主机名(为空则自动获取 hostname)
HOSTNAME=""
# 推送地址
PUSH_ENDPOINT="http://localhost:3000/api/v1/push"
# API 鉴权 Token(在项目 .env 中配置 DINGTALK_API_TOKEN,此处可覆盖)
DINGTALK_API_TOKEN=""
# 日志文件路径(为空则不写日志)
LOG_FILE="/opt/dingtalk-notice/logs/monitor.log"
配置字段说明
| 字段 | 说明 |
|---|---|
CHECK_SERVICES |
要检查的 systemd 服务,空格分隔;为空则不检查 |
CHECK_PORTS |
要检查的监听端口,空格分隔;为空则不检查 |
MEMORY_THRESHOLD |
内存使用率告警阈值,单位 % |
DISK_THRESHOLDS |
磁盘告警阈值,格式 挂载点:百分比,空格分隔多个 |
HOSTNAME |
告警消息中显示的主机名,为空则自动获取本机 hostname |
PUSH_ENDPOINT |
推送服务地址,指向 /api/v1/push |
DINGTALK_API_TOKEN |
可选,API 鉴权 token,可覆盖 .env 中的配置 |
LOG_FILE |
监控日志文件路径,为空则不写日志 |
修改配置后无需重启任何服务,下次 cron 执行自动生效。
添加 cron 任务
crontab -e
# 每分钟执行
* * * * * /bin/bash /opt/dingtalk-notice/scripts/monitor.sh
💡 脚本依赖
监控脚本只需 bash、curl 与常见系统命令(ss / lsof / free / df),
不依赖 Node.js,可单独装到任意被监控的服务器上。
告警消息示例
无异常时脚本静默退出,不发消息。有异常时合并为一条 markdown 消息推送:
## 🚨 prod-server-01
**时间**: 2026-08-15 14:30:00
**服务异常**
- nginx.service: 已停止
- 端口 443: 无进程监听
**资源异常**
- 内存: 85% (阈值 80%)
- 磁盘 /data: 92% (阈值 90%)
其中红色加粗标题来自 hostname 字段;「服务异常」与「资源异常」按检查结果动态出现,无异常的类别不会显示。
执行日志
配置 LOG_FILE 后,每次执行会写入日志,超过 5000 行自动截断:
[2026-08-15 15:10:27] ===== 开始检查 =====
[2026-08-15 15:10:27] 服务检查: 2/2 正常
[2026-08-15 15:10:27] 资源检查: 2/2 正常
[2026-08-15 15:10:27] 一切正常,退出