# server_monitoring **Repository Path**: xhzcs/server_monitoring ## Basic Information - **Project Name**: server_monitoring - **Description**: 本系统是一个完整的服务器监控和告警解决方案,由后端数据采集、云端数据处理、微信小程序展示和智能告警推送四部分组成。通过实时监控服务器性能指标和服务运行状态,在发现异常时自动触发告警通知,帮助运维人员及时发现和处理问题。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-12-12 - **Last Updated**: 2025-12-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README <<<<<<< HEAD # 服务器监控微信小程序 基于微信云开发的服务器性能监控系统,实现服务器实时监控、告警通知、性能分析等功能。 ## 线上版本 ![输入图片说明](wechat/miniprogram/images/gh_cc653a0aca0c_258%20(1).jpg) ## 📋 项目简介 本项目是一个完整的服务器监控解决方案,包含数据采集端和可视化展示端: - **前端**:微信小程序,提供服务器状态查看、告警配置等功能 - **后端**:微信云开发(云函数 + 云数据库) - **服务器数据采集**:Java程序 ## ✨ 主要功能 ### 📊 监控功能 - **服务器状态监控** - 实时显示服务器在线/离线状态 - 10分钟无数据上报自动标记为异常 - 支持多台服务器同时监控 - **服务运行监控** - 监控指定服务运行状态(MySQL、Java、Nginx等) - 服务状态可视化展示 - 服务异常自动检测 - **性能监控** - CPU使用率实时监控 - 内存使用率监控 - 磁盘使用情况监控 - 运行时间统计 ### 🔔 告警功能 #### 服务/服务器异常告警 - 服务器离线告警(10分钟无数据) - 服务停止告警 - 支持微信模板消息推送 - 支持邮箱告警 #### 性能告警(仅邮箱) - **磁盘告警**:使用率超过80% - **内存告警**:连续10次检测超过90% - **CPU告警**:连续10次检测超过90% #### 告警配置 - 独立开关控制(微信通知、邮箱通知、磁盘告警、内存告警、CPU告警) - 定时检测(每10分钟) - 聚合告警,避免消息轰炸 ### 📱 界面功能 #### 首页 - 服务器卡片列表展示 - 状态指示器(旋转齿轮) - 快速查看服务器在线状态 - 点击卡片进入详情页 #### 详情页 - **服务器基本信息**:主机名、操作系统、CPU、内存等 - **性能信息**:CPU和内存使用率环形图 - **磁盘使用情况**:所有挂载点使用率 - **服务运行情况**:各服务状态展示 #### 配置页(我的) - 消息订阅管理 - OpenID查看与复制 - 告警开关配置 - 统一告警测试 ## 🏗️ 技术架构 ### 前端技术栈 ```javascript ├── 框架:微信小程序 ├── UI组件:ColorUI ├── 图表库:qiun-wx-ucharts └── 开发语言:JavaScript + WXML + WXSS ``` ### 后端技术栈 ```javascript ├── 运行环境:微信云开发 ├── 云函数:Node.js ├── 数据库:云数据库(MongoDB) └── 邮件发送:nodemailer ``` ## 📁 项目结构 ``` server_mertics/ ├── cloudfunctions/ # 云函数目录 │ ├── login/ # 登录云函数(获取OpenID) │ ├── server_metric/ # 服务器指标数据接收 │ └── unified_alert/ # 统一告警云函数 │ ├── index.js # 整合所有告警逻辑 │ ├── package.json # 依赖配置(nodemailer) │ └── config.json # 定时触发器配置 │ ├── miniprogram/ # 小程序前端 │ ├── pages/ # 页面 │ │ ├── index/ # 首页(服务器列表) │ │ ├── detailed/ # 详情页 │ │ └── my/ # 配置页 │ │ │ └── components/ # 组件 │ ├── ColorUI/ # UI组件库 │ └── qiun-wx-ucharts/ # 图表组件 │ ├── project.config.json # 项目配置 └── README.md # 项目说明 ``` ## 🗄️ 数据库设计 ### 集合说明 #### server_metric(服务器指标数据) ```javascript { _id: String, ip: String, // 公网IP local_ip: String, // 内网IP create_time: Date, // 数据采集时间 data: { cpu: [...], // CPU信息 memory: [...], // 内存信息 disk: [...], // 磁盘信息 status: [...], // 服务状态 configuration: [...], // 配置信息 uptime: [...], // 运行时间 ports: [...] // 端口信息 ======= # 服务器监控告警系统介绍 ## 📋 系统概述 本系统是一个完整的服务器监控和告警解决方案,由**后端数据采集**、**云端数据处理**、**微信小程序展示**和**智能告警推送**四部分组成。通过实时监控服务器性能指标和服务运行状态,在发现异常时自动触发告警通知,帮助运维人员及时发现和处理问题。 ### 系统架构图 ``` ┌──────────────────────────────────────────────────────────────────────┐ │ 业务服务器集群 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 服务器1 │ │ 服务器2 │ │ 服务器N │ │ │ │ Agent │ │ Agent │ │ Agent │ │ │ │ (Java 8) │ │ (Java 8) │ │ (Java 8) │ │ │ │ :9090 │ │ :9090 │ │ :9090 │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ └─────────┼────────────────┼────────────────┼──────────────────────────┘ │ 主动模式 │ 主动模式 │ 被动模式 │ 直接上报 │ 直接上报 │ 中转拉取 │ │ │ ├────────────────┼────────────────┤ │ │ │ ▼ ▼ ▼ ┌────────────────────────────────────────────┐ │ 中转服务器(可选) │ │ collector.py (Python 3) │ │ 定时拉取 → 数据聚合 → 批量上报 │ └────────────────┬───────────────────────────┘ │ ▼ ┌───────────────┐ │ 微信云开发 │ │ 云函数 + 云DB │ └───────┬───────┘ │ ┌───────────┼───────────┐ │ │ │ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │小程序展示 │ │告警检测 │ │告警推送 │ │ 数据可视化│ │定时触发 │ │微信/邮件 │ └─────────┘ └─────────┘ └─────────┘ ``` --- ## 🔧 后端数据采集 ### 1. 采集 Agent 架构 #### 核心技术栈 - **开发语言**:Java 8 - **核心依赖**: - Jackson 2.13.5+(JSON 序列化/反序列化) - OkHttp 3.x(HTTP 客户端) - SimpleDateFormat(日志时间格式化) - **部署方式**:独立 JAR 包,无需外部容器 #### 运行模式 Agent 支持**两种运行模式**,根据不同场景灵活选择: ##### 模式1:主动上报模式(Active Mode) **适用场景**: - 服务器数量 ≤ 10 台 - 每台服务器可直接访问公网 - 云函数调用次数充足(< 20万次/月) **工作流程**: ``` 1. Agent 定时采集指标(默认30秒) 2. 采集完成后立即上报到云函数 3. 云函数接收数据并存储到云数据库 4. 小程序实时查询数据库展示 ``` **配置示例**: ```json { "endpoint": "https://xxx.app.tcloudbase.com/metric", "apiKey": null, "interval": 30, "enableAutoReport": true, // 启用主动上报 "metrics": { ... } } ``` **优点**: - ✅ 配置简单,部署快速 - ✅ 数据实时性好 - ✅ 无需额外中转服务器 **缺点**: - ❌ 服务器多时云函数调用次数激增 - ❌ 每台服务器需配置云函数地址 - ❌ 需要公网访问权限 ##### 模式2:被动拉取模式(Passive Mode) **适用场景**: - 服务器数量 ≥ 10 台 - 云函数调用次数有限制 - 业务服务器可内网隔离 **工作流程**: ``` 1. Agent 定时采集指标(默认30秒) 2. 数据缓存在内存中,不主动上报 3. HTTP 服务监听端口(默认9090) 4. 中转服务器定时拉取(默认60秒) 5. 中转服务器聚合数据后批量上报 6. 云函数接收批量数据存储 ``` **配置示例(Agent端)**: ```json { "endpoint": null, "apiKey": null, "interval": 30, "enableAutoReport": false, // 禁用主动上报 "dataExpireSeconds": 600, // 数据过期时间10分钟 "metrics": { ... } } ``` **配置示例(中转服务器)**: ```python # collector.py 配置 SERVERS = [ {"ip": "192.168.1.101", "port": 9090}, {"ip": "192.168.1.102", "port": 9090}, # ... 可添加任意多台 ] CLOUD_FUNCTION_URL = "https://xxx.app.tcloudbase.com/metric" PULL_INTERVAL = 60 # 拉取间隔60秒 ``` **优点**: - ✅ 云函数调用次数降低 **99%** - ✅ 业务服务器可完全内网隔离 - ✅ 集中管理,易于扩展 - ✅ 单台故障不影响其他服务器 **缺点**: - ❌ 需要额外的中转服务器 - ❌ 数据实时性略低(受拉取间隔影响) #### 调用次数对比 **场景**:100 台服务器,采集间隔 60 秒 | 模式 | 每天调用次数 | 每月调用次数 | 是否超限 | |------|------------|------------|----------| | **主动模式** | 100 × 1440 = 144,000 次 | 4,320,000 次 | ❌ 远超20万限额 | | **被动模式** | 1 × 1440 = 1,440 次 | 43,200 次 | ✅ 仅占21.6% | | **节省比例** | - | **99%** | - | ### 2. 数据采集内容 #### 2.1 内置采集指标 Agent 提供丰富的内置采集功能,开箱即用: ##### ① CPU 指标 - **采集方法**:Java OperatingSystemMXBean - **采集内容**: - CPU 使用率(实时百分比) - CPU 核心数 - CPU 型号(配置信息) - **数据格式**: ```json { "cpu": [{ "usage": 45.23, "cores": 8 }] } ``` ##### ② 内存指标 - **采集方法**:执行 `free -m` 命令 - **采集内容**: - 物理内存:总量、已用、空闲、共享、缓冲/缓存、可用 - Swap 交换分区:总量、已用、空闲 - **数据格式**: ```json { "memory": [ { "category": "Mem", "total": "16384M", "used": "8192M", "free": "4096M", "shared": "128M", "buff_cache": "4096M", "available": "8064M" }, { "category": "Swap", "total": "2048M", "used": "0M", "free": "2048M" } ] } ``` ##### ③ 磁盘指标 - **采集方法**:执行 `df -h` 命令 - **采集内容**:所有挂载点的使用情况 - **数据格式**: ```json { "disk": [ { "filesystem": "/dev/sda1", "size": "50G", "used": "35G", "avail": "12G", "usedPercent": "75%", "mountPoint": "/" } ] } ``` ##### ④ 服务器运行时间 - **采集方法**:执行 `uptime` 命令 + 读取 `/proc/uptime` - **采集内容**: - 运行时间(天/时/分) - 系统负载(1分钟、5分钟、15分钟) - **数据格式**: ```json { "uptime": [{ "duration": "42 days, 3:24", "uptime_seconds": 3644640, "days": 42, "hours": 3, "minutes": 24, "load_1min": "0.52", "load_5min": "0.58", "load_15min": "0.59" }] } ``` ##### ⑤ 服务器配置信息 - **采集方法**:读取 `/etc/os-release`、`/proc/cpuinfo` 等系统文件 - **采集内容**: - 操作系统类型和版本 - 内核版本 - CPU 型号和核心数 - 总内存大小 - 主机名 - 虚拟化类型(KVM/VMware/Physical) - Java 版本和厂商 - **数据格式**: ```json { "configuration": [{ "os_type": "CentOS", "os_distribution": "CentOS Linux 7 (Core)", "kernel_version": "3.10.0-1160.el7.x86_64", "architecture": "x86_64", "cpu_model": "Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz", "cpu_cores": 8, "total_memory_gb": "16.00", "hostname": "web-server-01", "virtualization": "kvm", "java_version": "1.8.0_292" }] } ``` ##### ⑥ Kubernetes Pod 信息(可选) - **采集方法**:执行 `kubectl get pods` 命令 - **环境要求**:Kubernetes 集群环境 - **采集内容**: - Pod 名称、命名空间 - 就绪状态、运行状态 - 重启次数、运行时长 - Pod IP、所在节点 - **数据格式**: ```json { "pod": [ { "namespace": "default", "name": "blog-server-68cd5f765b-6fxjc", "ready": "1/1", "status": "Running", "restarts": "0", "age": "23d", "ip": "10.244.36.75", "node": "k8s-node1" } ] } ``` #### 2.2 自定义采集指标 Agent 支持通过配置文件灵活添加自定义指标,无需修改代码: ##### 支持的采集类型 **① 服务状态监控(status)** - **用途**:监控服务/进程运行状态 - **支持命令**: - `systemctl status ` - systemd 服务 - `systemctl is-active ` - 快速检查(推荐) - `ps -ef | grep ` - 进程检测(兼容性好) - `pgrep ` - 进程查找 - `pidof ` - PID 查找 - **返回值**:`running` 或 `stopped` - **配置示例**: ```json { "name": "mysql", "type": "shell", "category": "status", "command": "systemctl is-active mysql", "dataType": "status", "description": "MySQL数据库服务" } ``` **② 端口监听检测(port)** - **用途**:检测端口监听状态和进程信息 - **支持命令**:`lsof -i :` 或 `lsof -i : -sTCP:LISTEN` - **返回信息**:进程名、PID、用户、监听地址 - **配置示例**: ```json { "name": "80", "type": "shell", "category": "port", "command": "lsof -i :80 -sTCP:LISTEN", "dataType": "port", "description": "HTTP服务端口" } ``` **③ 自定义数值指标(int/long/double)** - **用途**:采集数值型指标 - **支持类型**: - `int` - 整数(如连接数、进程数) - `long` - 长整数(如磁盘inode数) - `double` - 浮点数(如CPU温度、使用率) - **配置示例**: ```json { "name": "tcp_connections", "type": "shell", "category": "other", "command": "netstat -ant | grep ESTABLISHED | wc -l", "dataType": "int", "description": "当前TCP连接数" } ``` **④ 自定义文本指标(string)** - **用途**:采集文本型指标 - **配置示例**: ```json { "name": "hostname", "type": "shell", "category": "other", "command": "hostname", "dataType": "string", "description": "服务器主机名" } ``` **⑤ 布尔值指标(boolean)** - **用途**:采集开关状态 - **配置示例**: ```json { "name": "selinux_enabled", "type": "shell", "category": "other", "command": "[ $(getenforce) = 'Enforcing' ] && echo true || echo false", "dataType": "boolean", "description": "SELinux是否启用" } ``` ##### 常用自定义采集示例 **监控常见服务**: ```json { "custom": [ // Web服务器 {"name": "nginx", "type": "shell", "category": "status", "command": "systemctl is-active nginx", "dataType": "status"}, // 数据库 {"name": "mysql", "type": "shell", "category": "status", "command": "systemctl is-active mysql", "dataType": "status"}, {"name": "redis", "type": "shell", "category": "status", "command": "systemctl status redis", "dataType": "status"}, // 容器服务 {"name": "docker", "type": "shell", "category": "status", "command": "systemctl is-active docker", "dataType": "status"}, // Java应用 {"name": "java_app", "type": "shell", "category": "status", "command": "ps -ef | grep 'java.*my-app.jar' | grep -v grep", "dataType": "status"} ] } ``` **监控端口**: ```json { "custom": [ {"name": "80", "type": "shell", "category": "port", "command": "lsof -i :80 -sTCP:LISTEN", "dataType": "port"}, {"name": "443", "type": "shell", "category": "port", "command": "lsof -i :443 -sTCP:LISTEN", "dataType": "port"}, {"name": "3306", "type": "shell", "category": "port", "command": "lsof -i :3306 -sTCP:LISTEN", "dataType": "port"} ] } ``` ### 3. 数据上报流程 #### 主动模式上报流程 ``` 1. Agent 采集指标 → 构建 JSON 数据 2. 添加 _server_ip 字段(服务器本地IP) 3. HTTP POST 到云函数 /metric 接口 4. 云函数提取 HTTP 请求IP(公网IP) 5. 存储到云数据库(ip + local_ip + data) ``` #### 被动模式上报流程 ``` 1. Agent 采集指标 → 缓存到内存 2. HTTP 服务监听 9090 端口 3. 中转服务器定时拉取: a. 遍历服务器列表 b. GET http://192.168.1.x:9090/metrics c. 收集所有 JSON 响应 4. 中转服务器聚合数据为数组 5. 批量 POST 到云函数 6. 云函数批量存储 ``` #### 数据存储格式 云数据库 `server_metric` 集合: ```json { "_id": "auto_generated_id", "ip": "123.45.67.89", // 公网IP(从HTTP请求提取) "local_ip": "192.168.1.101", // 内网IP(从数据中提取) "create_time": ISODate("2025-12-11T10:00:00Z"), "data": { "cpu": [...], "memory": [...], "disk": [...], "uptime": [...], "configuration": [...], "pod": [...], "status": [...], "ports": [...], // 自定义指标... >>>>>>> 97837e0025d17b8cbaef582558aeac09635a78fe } } ``` <<<<<<< HEAD #### alert_settings(告警配置) ```javascript { _id: "global", wechat_enabled: Boolean, // 微信通知开关 email_enabled: Boolean, // 邮箱通知开关 disk_alert_enabled: Boolean, // 磁盘告警开关 memory_alert_enabled: Boolean, // 内存告警开关 cpu_alert_enabled: Boolean, // CPU告警开关 update_time: Date } ``` #### server_send(微信订阅用户) ```javascript { _id: String, openid: String, // 微信用户OpenID create_time: Date } ``` #### server_email(邮箱订阅用户) ```javascript { _id: String, email: String, // 邮箱地址 create_time: Date } ``` ## 🚀 快速开始 ### 1. 环境准备 - 微信开发者工具 - 微信小程序账号(开通云开发) - 163邮箱账号(用于发送告警邮件) ### 2. 克隆项目 ```bash git clone cd server_mertics ``` ### 3. 配置云开发环境 1. 在微信开发者工具中打开项目 2. 点击「云开发」按钮,开通云开发 3. 创建云开发环境 4. 记录环境ID ### 4. 部署云函数 #### 方法一:微信开发者工具部署 1. 右键 `cloudfunctions/unified_alert` 文件夹 2. 选择「上传并部署:云端安装依赖」 3. 等待部署完成 4. 重复以上步骤部署 `login` 和 `server_metric` 云函数 #### 方法二:命令行部署 ```bash # 安装云开发CLI npm install -g @cloudbase/cli # 登录 tcb login # 部署云函数 tcb fn deploy unified_alert tcb fn deploy login tcb fn deploy server_metric ``` ### 5. 配置定时触发器 云函数 `unified_alert` 会自动创建定时触发器(每10分钟执行一次) ### 6. 配置邮箱告警 修改 `cloudfunctions/unified_alert/index.js` 中的邮箱配置: ```javascript auth: { user: 'your_email@163.com', // 你的163邮箱 pass: 'your_auth_code' // 163邮箱授权码 } ``` **获取163邮箱授权码**: 1. 登录163邮箱网页版 2. 设置 → POP3/SMTP/IMAP 3. 开启 SMTP 服务 4. 生成授权码 ### 7. 初始化数据库 在云开发控制台创建以下集合: - `server_metric` - `alert_settings` - `server_send` - `server_email` ### 8. 配置数据采集端 参考 `F:\IDEA项目\Server_metric_collection\Server_metric\` 目录下的说明文档,在服务器上部署数据采集脚本。 ## 📝 使用说明 ### 订阅告警通知 #### 微信通知 1. 打开小程序「我的」页面 2. 点击「消息订阅」,授权订阅消息 3. 点击「获取OpenID」,查看并复制你的OpenID 4. 在云数据库 `server_send` 集合中添加记录: ```javascript ======= --- ## 📱 微信小程序功能 ### 1. 首页 - 服务器列表 **功能特性**: - 📊 卡片式展示所有服务器 - 🔄 实时在线状态指示(旋转齿轮动画) - ⚠️ 异常服务器醒目标识(10分钟无数据) - 🖱️ 点击卡片进入详情页 **展示信息**: - 服务器主机名 - 内网IP地址 - 在线/离线状态 - 最后更新时间 ### 2. 详情页 - 服务器监控 **① 基本信息卡片** - 主机名 - 操作系统类型和版本 - CPU 型号和核心数 - 总内存大小 - 运行时间 - 虚拟化类型 **② 性能监控卡片** - CPU 使用率环形图(实时百分比) - 内存使用率环形图(实时百分比) - 颜色指示: - 绿色:正常(< 80%) - 橙色:警告(80% ~ 90%) - 红色:危险(> 90%) **③ 磁盘使用情况** - 所有挂载点列表展示 - 每个分区的使用率进度条 - 文件系统类型 - 总容量、已用、可用空间 **④ 服务运行状态** - 所有监控服务列表 - 运行中/已停止状态标识 - 服务描述信息 **⑤ Pod 运行状态(Kubernetes环境)** - Pod 名称和命名空间 - 就绪状态和运行状态 - 重启次数统计 ### 3. 我的页面 - 配置中心 **① 消息订阅管理** - 一键订阅告警消息 - 查看订阅状态 - 获取和复制 OpenID **② 告警开关配置** - **微信通知开关**:开启/关闭微信模板消息推送 - **邮箱通知开关**:开启/关闭邮件告警推送 **③ 性能告警配置** - **磁盘告警开关**:监控磁盘使用率 > 80% - **内存告警开关**:连续10次检测 > 90% - **CPU告警开关**:连续10次检测 > 90% **④ 功能操作** - **统一告警测试**:手动触发告警检测,验证配置 - **OpenID复制**:便于配置微信订阅 --- ## 🔔 告警系统详解 ### 1. 告警检测机制 #### 定时触发器 告警系统通过云函数定时触发器自动运行: ```javascript // unified_alert/config.json { "triggers": [ { "name": "unifiedAlertTrigger", "type": "timer", "config": "0 */10 * * * * *" // 每10分钟执行一次 } ] } ``` **执行流程**: ``` 每10分钟 → 云函数自动触发 → 检测所有告警类型 → 聚合告警 → 推送通知 ``` #### 告警检测逻辑 云函数 `unified_alert` 统一处理所有告警类型: ```javascript exports.main = async (event, context) => { // 1. 查询告警配置开关 const alertSettings = await getAlertSettings(); // 2. 查询最新服务器数据 const serverData = await getLatestServerData(); // 3. 检测各类告警 const alerts = { offline: [], // 服务器离线 service: [], // 服务异常 disk: [], // 磁盘告警 memory: [], // 内存告警 cpu: [] // CPU告警 }; // 4. 遍历服务器数据 for (const server of serverData) { // 检测服务器离线 if (isOffline(server)) { alerts.offline.push(server); } // 检测服务异常 const stoppedServices = checkServices(server); if (stoppedServices.length > 0) { alerts.service.push({...server, services: stoppedServices}); } // 检测磁盘告警 if (alertSettings.disk_alert_enabled) { const diskAlerts = checkDisk(server); if (diskAlerts.length > 0) { alerts.disk.push({...server, disks: diskAlerts}); } } // 检测内存告警(连续10次 > 90%) if (alertSettings.memory_alert_enabled) { const memoryAlert = await checkMemory(server); if (memoryAlert) { alerts.memory.push(server); } } // 检测CPU告警(连续10次 > 90%) if (alertSettings.cpu_alert_enabled) { const cpuAlert = await checkCPU(server); if (cpuAlert) { alerts.cpu.push(server); } } } // 5. 聚合告警并推送 await sendAlerts(alerts, alertSettings); }; ``` ### 2. 告警类型详解 #### 告警类型1:服务器离线告警 **触发条件**: - 10分钟内未收到服务器数据上报 - 计算方式:`当前时间 - 最后上报时间 > 10分钟` **检测代码**: ```javascript function isOffline(server) { const now = new Date().getTime(); const lastUpdate = new Date(server.create_time).getTime(); const diff = (now - lastUpdate) / 1000 / 60; // 分钟 return diff > 10; } ``` **告警信息**: - 服务器主机名 - 内网IP地址 - 最后在线时间 - 离线时长 **通知方式**: - ✅ 微信模板消息(需订阅) - ✅ 邮件通知 **告警示例**: ``` 【服务器离线】 服务器: web-server-01 IP地址: 192.168.1.101 离线时长: 15分钟 最后在线: 2025-12-11 10:00:00 ``` #### 告警类型2:服务异常告警 **触发条件**: - 监控的服务状态为 `stopped` 或 `offline` - 基于自定义配置的服务监控 **检测代码**: ```javascript function checkServices(server) { const stoppedServices = []; if (server.data.status && server.data.status.length > 0) { for (const service of server.data.status) { if (service.status !== 'running') { stoppedServices.push(service); } } } return stoppedServices; } ``` **告警信息**: - 服务器主机名 - 服务名称 - 服务状态 - 服务描述 **通知方式**: - ✅ 微信模板消息(需订阅) - ✅ 邮件通知 **告警示例**: ``` 【服务异常】 服务器: web-server-01 服务名称: mysql 服务状态: stopped 服务描述: MySQL数据库服务 ``` #### 告警类型3:磁盘告警 **触发条件**: - 任一磁盘分区使用率 > 80% - 独立开关控制 **检测代码**: ```javascript function checkDisk(server) { const diskAlerts = []; if (server.data.disk && server.data.disk.length > 0) { for (const disk of server.data.disk) { const usage = parseFloat(disk.usedPercent); if (usage > 80) { diskAlerts.push(disk); } } } return diskAlerts; } ``` **告警信息**: - 服务器主机名 - 挂载点 - 使用率 - 总容量、已用、可用空间 **通知方式**: - ❌ 微信模板消息(不支持) - ✅ 邮件通知 **告警示例**: ``` 【磁盘告警】 服务器: web-server-01 挂载点: /data 使用率: 85% 总容量: 100G 已用: 85G 可用: 15G ``` #### 告警类型4:内存告警 **触发条件**: - 连续10次检测内存使用率 > 90% - 检测间隔:10分钟(定时器间隔) - 总计时长:约100分钟 - 独立开关控制 **持久化计数**: ```javascript // 在云数据库中记录连续超标次数 // 集合: alert_counters { server_ip: "192.168.1.101", memory_high_count: 8, // 当前连续超标次数 last_check_time: Date } ``` **检测代码**: ```javascript async function checkMemory(server) { // 获取当前内存使用率 const memoryUsage = calculateMemoryUsage(server.data.memory); // 查询历史计数 const counter = await db.collection('alert_counters') .where({server_ip: server.local_ip}).get(); if (memoryUsage > 90) { // 超标,计数+1 const newCount = (counter.data[0]?.memory_high_count || 0) + 1; if (newCount >= 10) { // 连续10次超标,触发告警 await resetCounter(server.local_ip, 'memory'); return true; } else { // 更新计数 await updateCounter(server.local_ip, 'memory', newCount); } } else { // 未超标,重置计数 await resetCounter(server.local_ip, 'memory'); } return false; } ``` **告警信息**: - 服务器主机名 - 内存使用率 - 总内存、已用、可用 - 连续超标时长 **通知方式**: - ❌ 微信模板消息(不支持) - ✅ 邮件通知 **告警示例**: ``` 【内存告警】 服务器: web-server-01 内存使用率: 92% 总内存: 16G 已用: 14.7G 可用: 1.3G 连续超标: 100分钟 ``` #### 告警类型5:CPU告警 **触发条件**: - 连续10次检测CPU使用率 > 90% - 检测间隔:10分钟(定时器间隔) - 总计时长:约100分钟 - 独立开关控制 **检测机制**: 与内存告警类似,采用持久化计数机制 **告警信息**: - 服务器主机名 - CPU使用率 - CPU核心数 - 连续超标时长 **通知方式**: - ❌ 微信模板消息(不支持) - ✅ 邮件通知 **告警示例**: ``` 【CPU告警】 服务器: web-server-01 CPU使用率: 95% CPU核心数: 8 连续超标: 100分钟 ``` ### 3. 告警推送方式 #### 推送方式1:微信模板消息 **适用告警类型**: - ✅ 服务器离线告警 - ✅ 服务异常告警 - ❌ 磁盘告警(微信不支持) - ❌ 内存告警(微信不支持) - ❌ CPU告警(微信不支持) **订阅流程**: ``` 1. 打开小程序「我的」页面 2. 点击「消息订阅」按钮 3. 授权订阅消息权限 4. 点击「获取OpenID」并复制 5. 在云数据库 server_send 集合添加记录: >>>>>>> 97837e0025d17b8cbaef582558aeac09635a78fe { openid: "你的OpenID", create_time: new Date() } <<<<<<< HEAD ``` #### 邮箱通知 在云数据库 `server_email` 集合中添加记录: ```javascript ======= ``` **推送代码**: ```javascript // 发送微信模板消息 async function sendWechatMessage(openid, data) { await cloud.openapi.subscribeMessage.send({ touser: openid, page: 'pages/index/index', data: { thing1: { value: data.serverName }, // 服务器名称 thing2: { value: data.status }, // 告警状态 time3: { value: data.time } // 告警时间 }, templateId: 'xxx', // 模板ID miniprogramState: 'formal' }); } ``` **推送限制**: - 用户需主动订阅 - 每次订阅仅一次推送机会 - 需定期重新订阅 #### 推送方式2:邮件通知 **适用告警类型**: - ✅ 服务器离线告警 - ✅ 服务异常告警 - ✅ 磁盘告警 - ✅ 内存告警 - ✅ CPU告警 **订阅流程**: ``` 在云数据库 server_email 集合添加记录: >>>>>>> 97837e0025d17b8cbaef582558aeac09635a78fe { email: "your_email@qq.com", create_time: new Date() } ``` <<<<<<< HEAD ### 配置告警开关 1. 打开「我的」页面 2. 在「告警设置」区域配置: - 微信通知:开启/关闭 - 邮箱通知:开启/关闭 3. 在「性能告警设置」区域配置: - 磁盘告警:开启/关闭 - 内存告警:开启/关闭 - CPU告警:开启/关闭 ### 测试告警功能 点击「统一告警测试」按钮,查看执行结果。 ## ⚙️ 告警规则说明 ### 服务器异常 - 触发条件:10分钟内未收到数据上报 - 通知方式:微信模板消息 + 邮件 ### 服务异常 - 触发条件:服务状态为 stopped 或 offline - 通知方式:微信模板消息 + 邮件 ### 磁盘告警 - 触发条件:任一磁盘使用率 > 80% - 通知方式:仅邮件 ### 内存告警 - 触发条件:连续10次检测内存使用率 > 90% - 检测间隔:约100分钟(10次 × 10分钟) - 通知方式:仅邮件 ### CPU告警 - 触发条件:连续10次检测CPU使用率 > 90% - 检测间隔:约100分钟(10次 × 10分钟) - 通知方式:仅邮件 ## 🔧 常见问题 ### 1. 邮件发送失败(535 Error) **原因**:163邮箱授权码无效或SMTP服务未开启 **解决方案**: 1. 重新获取163邮箱授权码 2. 确保开启了SMTP服务 3. 或改用QQ邮箱(更稳定) ### 2. 首页显示异常但详情页显示正常 **原因**:数据时间判断逻辑不一致 **解决方案**:已在详情页添加10分钟阈值判断,确保一致性 ### 3. 定时任务不执行 **检查项**: 1. 云函数是否正确部署 2. 定时触发器是否创建 3. 告警开关是否开启 4. 查看云函数日志 ### 4. 收不到告警通知 **检查项**: 1. 订阅信息是否正确添加到数据库 2. 告警开关是否开启 3. 是否有异常触发(通过测试按钮验证) 4. 微信订阅消息是否授权 ## 📈 性能优化 ### 云函数合并优化 原本有3个独立的定时云函数: - `alert_notification`(微信通知) - `email_alert`(邮箱通知) - `performance_alert`(性能告警) 现已合并为 `unified_alert` 统一告警云函数: - ✅ 减少66%数据库查询次数 - ✅ 减少66%云函数执行次数 - ✅ 共享数据,提高效率 - ✅ 统一日志,便于排查 ## 📄 许可证 MIT License ## 👥 贡献 欢迎提交 Issue 和 Pull Request! ## 📞 联系方式 如有问题,请通过以下方式联系: - 邮箱:geekzzf@163.com - 微信小程序:服务器监控 ## 🙏 致谢 - [微信云开发](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html) - [ColorUI](https://github.com/weilanwl/ColorUI) - [qiun-wx-ucharts](https://www.ucharts.cn/) - [nodemailer](https://nodemailer.com/) --- **最后更新时间**:2025-12-10 ======= **邮件配置**: ```javascript // 使用 nodemailer 发送邮件 const transporter = nodemailer.createTransport({ host: 'smtp.163.com', port: 465, secure: true, auth: { user: 'your_email@163.com', // 163邮箱 pass: 'your_auth_code' // 授权码 } }); ``` **邮件内容**: ```html

🚨 服务器告警通知

服务器:web-server-01

IP地址:192.168.1.101

告警详情

磁盘使用率: 85% (超过阈值80%)

挂载点: /data

总容量: 100G

已用: 85G

可用: 15G

告警时间:2025-12-11 10:15:00

``` **推送优势**: - 无需用户订阅 - 无推送次数限制 - 支持所有告警类型 - 支持富文本格式 ### 4. 告警聚合机制 #### 为什么需要聚合? 避免消息轰炸: ``` ❌ 不聚合: 10台服务器 × 3个告警 = 30条推送 ✅ 聚合后: 1条推送,包含所有告警摘要 ``` #### 聚合策略 **① 按告警类型聚合** ```javascript // 聚合所有离线服务器 const offlineServers = alerts.offline.map(s => s.hostname).join('、'); // 聚合邮件内容 邮件标题: 【服务器告警】3台服务器离线,5个服务异常,2个磁盘告警 邮件正文: - 离线服务器:web-server-01、web-server-02、db-server-01 - 服务异常:... - 磁盘告警:... ``` **② 微信消息聚合** ```javascript // 微信模板消息(简略版) { thing1: "3台服务器告警", thing2: "离线×3,服务异常×5,磁盘×2", time3: "2025-12-11 10:15:00" } ``` **③ 邮件详细列表** ```html

离线服务器 (3台)

  • web-server-01 (192.168.1.101) - 离线15分钟
  • web-server-02 (192.168.1.102) - 离线20分钟
  • db-server-01 (192.168.1.110) - 离线12分钟

服务异常 (5个)

  • web-server-01: MySQL (stopped)
  • web-server-02: Nginx (stopped)
  • ...
``` ### 5. 告警配置管理 #### 云数据库配置表 集合:`alert_settings` ```javascript { _id: "global", wechat_enabled: true, // 微信通知总开关 email_enabled: true, // 邮箱通知总开关 disk_alert_enabled: true, // 磁盘告警开关 memory_alert_enabled: true, // 内存告警开关 cpu_alert_enabled: true, // CPU告警开关 update_time: Date } ``` #### 小程序配置界面 **开关控制**: ```javascript // 更新告警配置 async updateAlertSettings(key, value) { await db.collection('alert_settings').doc('global').update({ data: { [key]: value, update_time: new Date() } }); } // 示例:关闭磁盘告警 updateAlertSettings('disk_alert_enabled', false); ``` **配置生效**: - 实时生效:下次定时任务(10分钟内)即采用新配置 - 无需重启:云函数自动读取最新配置 ### 6. 告警测试功能 #### 手动触发测试 **小程序操作**: ``` 1. 打开「我的」页面 2. 点击「统一告警测试」按钮 3. 查看弹窗显示的执行结果 ``` **测试代码**: ```javascript // 小程序端调用 wx.cloud.callFunction({ name: 'unified_alert', data: { test: true } // 测试模式 }).then(res => { wx.showModal({ title: '测试结果', content: JSON.stringify(res.result, null, 2), showCancel: false }); }); ``` **测试输出**: ```json { "success": true, "alerts": { "offline": 2, "service": 3, "disk": 1, "memory": 0, "cpu": 0 }, "notifications": { "wechat_sent": 5, "email_sent": 6 }, "errors": [] } ``` --- ## 🎯 支持的自定义告警 ### 1. 基于自定义指标的告警 虽然系统默认支持5种告警类型,但通过**自定义采集指标**,可以实现更多告警场景: #### 场景1:数据库连接数告警 **采集配置**: ```json { "name": "mysql_connections", "type": "shell", "category": "other", "command": "mysql -uroot -pPassword -e 'show status like \"Threads_connected\"' | tail -1 | awk '{print $2}'", "dataType": "int", "description": "MySQL当前连接数" } ``` **告警逻辑**(需自行在云函数中添加): ```javascript if (server.data.mysql_connections > 100) { // 触发告警 } ``` #### 场景2:Docker容器数量告警 **采集配置**: ```json { "name": "docker_container_count", "type": "shell", "category": "other", "command": "docker ps -q | wc -l", "dataType": "int", "description": "运行中的Docker容器数量" } ``` **告警逻辑**: ```javascript if (server.data.docker_container_count === 0) { // 所有容器停止,触发告警 } ``` #### 场景3:网络连接数告警 **采集配置**: ```json { "name": "tcp_connections", "type": "shell", "category": "other", "command": "netstat -ant | grep ESTABLISHED | wc -l", "dataType": "int", "description": "当前TCP连接数" } ``` **告警逻辑**: ```javascript if (server.data.tcp_connections > 1000) { // 连接数过高,触发告警 } ``` #### 场景4:磁盘IO等待告警 **采集配置**: ```json { "name": "disk_io_wait", "type": "shell", "category": "other", "command": "iostat -x 1 2 | grep '^sda' | tail -1 | awk '{print $4}'", "dataType": "double", "description": "磁盘IO等待百分比" } ``` **告警逻辑**: ```javascript if (server.data.disk_io_wait > 50) { // IO等待过高,触发告警 } ``` #### 场景5:Kubernetes Pod异常告警 **采集配置**: ```json { "metrics": { "builtin": { "pod": { "enabled": true } } } } ``` **告警逻辑**: ```javascript // 检测 CrashLoopBackOff 状态 for (const pod of server.data.pod) { if (pod.status === 'CrashLoopBackOff' || pod.status === 'Error' || pod.status === 'Failed') { // 触发告警 } } ``` ### 2. 扩展告警的实现方式 #### 方法1:修改云函数逻辑 在 `unified_alert/index.js` 中添加自定义检测: ```javascript // 添加自定义告警检测 function checkCustomAlerts(server) { const customAlerts = []; // 检测1:MySQL连接数 if (server.data.mysql_connections > 100) { customAlerts.push({ type: 'mysql_connections', message: `MySQL连接数过高: ${server.data.mysql_connections}` }); } // 检测2:Docker容器 if (server.data.docker_container_count === 0) { customAlerts.push({ type: 'docker_stopped', message: '所有Docker容器已停止' }); } return customAlerts; } ``` #### 方法2:创建独立告警云函数 针对特定场景创建专用云函数: ```javascript // custom_alert/index.js exports.main = async (event, context) => { const db = cloud.database(); // 查询最新数据 const data = await db.collection('server_metric') .orderBy('create_time', 'desc') .limit(1) .get(); // 自定义检测逻辑 const alerts = []; for (const server of data.data) { // 你的告警逻辑... } // 发送告警 if (alerts.length > 0) { await sendAlerts(alerts); } }; ``` #### 方法3:基于阈值配置 将告警阈值配置化: ```javascript // 云数据库集合:custom_alert_rules { metric_name: "mysql_connections", threshold: 100, operator: ">", // >, <, =, >=, <= enabled: true } // 检测代码 async function checkConfigurableAlerts(server) { const rules = await db.collection('custom_alert_rules') .where({enabled: true}).get(); for (const rule of rules.data) { const value = server.data[rule.metric_name]; if (compareValue(value, rule.operator, rule.threshold)) { // 触发告警 } } } ``` --- ## 📊 完整数据流图 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 数据采集 → 存储流程 │ └─────────────────────────────────────────────────────────────────┘ 服务器1 服务器2 服务器N │ │ │ │ Agent采集 │ Agent采集 │ Agent采集 │ (30秒/次) │ (30秒/次) │ (30秒/次) │ │ │ ├─主动模式───────────┼───────────────────┤ │ POST /metric │ POST /metric │ POST /metric │ │ │ └─被动模式───────────┴───────────────────┘ │ HTTP :9090 │ GET /metrics ▼ ┌─────────────┐ │ 中转服务器 │ │ collector.py│ │ (60秒/次) │ └──────┬──────┘ │ POST (批量) ▼ ┌─────────────┐ │ 云函数 │ │ server_metric│ └──────┬──────┘ │ 批量写入 ▼ ┌─────────────┐ │ 云数据库 │ │server_metric│ └─────────────┘ ┌─────────────────────────────────────────────────────────────────┐ │ 告警检测 → 推送流程 │ └─────────────────────────────────────────────────────────────────┘ 云数据库 定时触发器 云函数 server_metric (每10分钟) unified_alert │ │ │ │ ├─────────触发────────→│ │ │ │ │←──────────查询最新数据──────────────────────┤ │ │ │ ├──────────返回数据───────────────────────→│ │ │ │ │ │ 检测告警 │ │ - 离线 │ │ - 服务异常 │ │ - 磁盘 │ │ - 内存 │ │ - CPU │ │ │ │ │ 聚合告警 │ │ │ ├─────查询订阅用户─────────────────────────→│ │ │ │ ├─────查询告警配置─────────────────────────→│ │ │ │ │ │ 推送 │ │ ┌──┴──┐ │ │ │ │ │ │ ▼ ▼ │ │ 微信推送 邮件推送 │ │ │ │ │ │ ▼ ▼ │ │ 用户1 用户2 │ │ 用户2 用户3 │ │ ... ``` --- ## 🚀 部署建议 ### 小规模场景(≤ 10台服务器) **推荐方案**:主动上报模式 ``` 优势: - 配置简单,快速部署 - 数据实时性好 - 无需额外服务器 部署步骤: 1. 每台服务器部署Agent 2. 配置 enableAutoReport: true 3. 配置云函数地址 4. 启动Agent ``` ### 中大规模场景(≥ 10台服务器) **推荐方案**:被动拉取模式 ``` 优势: - 云函数调用次数降低99% - 业务服务器可内网隔离 - 集中管理,易于扩展 部署步骤: 1. 每台服务器部署Agent(被动模式) 2. 部署1台中转服务器 3. 配置服务器列表 4. 启动collector.py ``` ### 混合部署场景 ``` 场景: - 核心服务器:主动上报(实时性要求高) - 其他服务器:被动拉取(成本优化) 配置: - 核心服务器:enableAutoReport: true - 其他服务器:enableAutoReport: false - 中转服务器:只拉取被动模式服务器 ``` --- ## 📞 源码获取 - **微信**:15121959400 - >>>>>>> 97837e0025d17b8cbaef582558aeac09635a78fe