# WeCom Center — 可移植 Zabbix 前端模块 一个自包含、多语言的 Zabbix 7.4 前端模块(custom module / plugin)。加载后会在 **Administration → WeCom Center** 增加一个定制页面,分三个 Tab: - **告警(Alert)** - **机器人 key**:单字段读写全局宏 `{$WECOM_KEY}`,无“账号/接收目标”概念(群机器人就是往群里发一条消息);可“发送测试”直接打企微接口看 `errcode`。 - **告警策略引擎**:内置 5 套策略预设(稳健运维 / 只保命 / 全量观察 / 夜间降噪 / 核心从严)。**先“预览”(dry-run,不写入)→ 再“应用”**。应用会:① 设置媒介严重度阈值;② 把模板触发器、触发器原型、已发现(LLD)触发器按类别批量改严重度。必告警类别一律钉到 **灾难(Disaster=5)**,因此无论阈值多高都必然发出。 - **手动阈值**:勾选会通知的严重度 + 总开关(写媒介 `severity` / `active`)。 - **优化(Optimization)** - **服务端调优生成器**:选“小/中/大”规模,生成 `StartSNMPPollers` 等 `.env`/compose 参数与重建命令——**只生成、不落地**,由运维复制到主机自行重建 server 容器(零风险、零特权)。 - **模板导入**:内置的是**真实的华为模板** `Huawei VRP by SNMP walk`(导出文件在 `templates/`),点“导入”即导入 Zabbix;导入已存在模板会就地更新,导入新模板会新建。 - **模板切换(迁移设备)**:选“旧模板 → 新模板”,**预览**列出受影响设备 → **确认切换**把每台设备的模板链接替换为新模板(这就是“导入后是否切换”那一步)。 - **地图标记**:以 **单点(Zabbix server 主机)** 作为代表点,设置 `location_lat` / `location_lon`。 - **日常维护(Maintenance)** - **触发器告警开关**:按名称搜索触发器,勾选 = 启用告警、取消勾选 = 停用该触发器(写 `trigger.status`,0 启用 / 1 停用)。单套环境常有数万个触发器,需先输入关键字搜索(最多显示 200 条)。 所有改动都通过 **Zabbix 官方 API / 受控 SQL** 写入数据库,因此:换机器、重建容器、升级镜像后设置都在;只要“加载插件”即可复用。 ## 目录结构 ``` WecomCenter/ ├── manifest.json # 模块清单(v2.0),注册 2 个 action ├── Module.php # 模块入口:注册视图目录、初始化 i18n、注入左侧菜单 ├── actions/ │ ├── WecomCenterView.php # GET 控制器,渲染页面 │ └── WecomCenterSave.php # POST 控制器,分发一键方案/保存/测试/导入/地图 ├── views/ │ └── wecom.center.view.php # 页面模板(Zabbix 原生 UI 组件) ├── lib/ │ ├── I18n.php # 极简多语言层(按当前语言加载,缺省回退英文) │ └── Helper.php # 业务逻辑:媒介/账号/key、方案预设、导入、坐标、测试 ├── locale/ # 35 个语言文件(见“多语言”) ├── templates/Huawei VRP by SNMP walk.yaml # 内置真实华为模板(导入/切换用) └── assets/wecom.center.css ``` ## 安装(可移植方式) 1. **持久化模块目录**:在 `docker-compose.yaml` 的 web 服务下挂载宿主目录: ```yaml zabbix-web-nginx-mysql: volumes: - /opt/zabbix/zabbix-server/web-modules:/usr/share/zabbix/modules ``` 2. 把本 `WecomCenter/` 目录整体放到宿主 `/opt/zabbix/zabbix-server/web-modules/WecomCenter/`,然后 `docker compose up -d` 重建一次 web 容器使挂载生效(数据不动,仅 web 短暂重启)。 3. **启用模块**(写入 `module` 表,status=1 为启用): ```sql INSERT INTO module(moduleid,id,relative_path,status,config) SELECT 1001,'wecom_center','modules/WecomCenter',1,'[]' WHERE NOT EXISTS (SELECT 1 FROM module WHERE id='wecom_center'); ``` (也可在 Administration → General → Modules 里点“启用”。) 4. 刷新网页,左侧 **Administration → WeCom Center** 即可进入。 > 换环境:重复 1–3 即可。模块代码放在 git 里,`web-modules/` 随仓库走;MySQL 卷里保存着 `module` 启用记录,二者都在 → 插件始终在线。 ## 多语言 - 共 **35 个语言文件**,覆盖 Zabbix 全部 36 个 locale(`en_GB`/`en_US` 共用英文)。 - **已人工翻译**:`zh_CN`、`zh_TW`、`ja_JP`、`ko_KR`、`ru_RU`、`de_DE`、`fr_FR`、`es_ES`、`pt_BR`、`it_IT`、`pl_PL`、`tr_TR`。 - 其余语言文件存在但暂未翻译,运行时自动回退英文(页面照常工作,不会报错)。 - 增加/完善语言:复制 `locale/en.php` 为 `locale/.php` 并翻译 value 即可,键名保持不变。模块会读取当前用户语言(`CWebUser::$data['lang']`)自动切换。 ## 设计要点(适配 Zabbix 7.4) - `manifest.json` 用 `manifest_version: 2.0`;action 的控制器类位于 `actions/`(自动加载器会把子命名空间段转小写)。 - 视图目录必须在 `Module::init()` 里 `CView::registerDirectory($this->getRelativePath().'/views')`。 - 菜单注入:`APP::Component()->get('menu.main')->findOrAdd(_('Administration'))->getSubmenu()->add(...)`。 - 关键 API 注意:`mediatype.get` **不支持 `sortfield=name`**(会整体返回 false);`configuration.import` 的规则键是复数 `templates`(不是 `template`);`trigger.update` **不接受 `triggers` 数组**,只能逐条用 `triggerid` 更新。 - 告警“开关”落在用户媒介的 `active` 字段:**0=启用、1=停用**;严重度为位掩码(未分类=1…灾难=32)。触发器“是否告警”落在 `trigger.status`:**0=启用、1=停用**。 ## 告警媒介说明(key 已迁到全局宏) 页面基于“Webhook 类型(type=4)的媒介 + 一个机器人账号(默认用户名 `wecomrobot`)的媒介记录”工作。 - **机器人 key 存于全局宏 `{$WECOM_KEY}`**(Administration → Macros),页面“机器人 key”字段直接**读取/写入该宏**——key 不再散落在一长串 `webhook_url` 里。换机器人只改这一格。 - 媒介 102 的固定参数:`key = {$WECOM_KEY}`、`message = {ALERT.MESSAGE}`。 - Webhook 脚本按 `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key= + params.key` 拼 URL,用 **markdown** 发送(失败自动回退 text)。 - 一键方案 / 勾选保存 → 修改该账号对应媒介的 `severity` / `active`。 - 发送测试 → 用 base + `{$WECOM_KEY}` 拼 URL 直接 POST,检查返回 `errcode:0`。 ## 配套告警链路(告警方案 v2,已按预期配置) - **动作 7「Send alarm by Wecom Robot」**:问题消息改为 markdown 红字(``),并**新增恢复操作**发绿字(``),两者均带前端直达链接 `{$ZBX_URL}/tr_events.php?triggerid={TRIGGER.ID}&eventid={EVENT.ID}`。 - **全局宏**:`{$WECOM_KEY}`(机器人 key)、`{$ZBX_URL}`(前端地址,默认 `http://192.168.87.20:8080`)。 - **收件人**:统一为机器人账号 `wecomrobot`(uid 6)的媒介 102,不再指向真人账号。 - **备份与回滚**:改动前已导出 `/opt/zabbix/backup/wecom-config-backup-*.json`(含媒介 102、动作 7、全局宏),可用对应 API 还原。 若环境中没有 Webhook 媒介类型,页面会提示“未找到 webhook 媒介类型”。 ## 告警策略引擎(核心) **设计原则**:每条策略里,“必告警”类别一律设为最高严重度 **灾难 Disaster(5)**——因为“无论如何,最严重的总得告警”,这样无论阈值怎么卡都必然通过。策略同时给其余类别定阈值。**没有默认策略**:页面上列出预设,用户“选择 → 预览 → 应用”,应用可重复执行。 | 预设 | 阈值(最低会通知的级别) | 适用 | |---|---|---| | 稳健运维 steady | 严重(High) 及以上 | 日常生产 | | 只保命 core | 仅灾难(Disaster) | 最大降噪 | | 全量观察 observe | 警告(Warning) 及以上 | 新接入/排障 | | 夜间降噪 night | 仅灾难 | 夜班静默 | | 核心从严 balanced | 一般严重(Average) 及以上 | 比稳健略宽 | **类别与“必告警”**(按优先级顺序判定,一个触发器只归一类,高优先覆盖低优先): `device_down(设备离线) > hw_fault(硬件故障) > restarted(重启) > core_link(核心/上联) > interface_down(接口down) > perf(性能) > other(不动)`。 `device_down / hw_fault / restarted / core_link` 属于必告警,钉到 Disaster。 **一次“应用”实际改哪些对象**(三管齐下,缺一不可): 1. **模板触发器**(普通触发器):`API trigger.update`,立即生效并自动下发到已链接主机。 2. **触发器原型**:`API triggerprototype.update`,保证以后重新发现的新触发器也一致。 3. **已发现触发器(flags=4,LLD 生成,无 templateid)**:`trigger.update` 会报 `Cannot update "priority" for a discovered trigger`,故用**受控 SQL** `UPDATE triggers SET priority` 按类别批量改;分“低优先级类别先写、高优先级后写”,确保重叠时高优先胜出。前端读库即时可见,server 配置缓存约 60 秒内自动刷新。 **实测结论(2026-11-04,单套 186 台华为交换机 / 全库 45,824 触发器)**: - 走页面后端真实点“应用 steady”:模板触发器 4 个、原型 5 个、已发现触发器 11,047 个全部改成功;抽检 `73801 Unavailable by ICMP ping` 4→5、`73807 Fan critical` 原型 3→5 ✅。 - 应用后已做**全量还原**:全部 45,824 行 `priority` 与快照比对 **0 误差**,媒介严重度/策略宏一并复位。证明“一键刷新”在所有探测节点上可运行且**完全可逆**。 - “预览(dry-run)”按类别列出触发数/将改动数,不写入。已在页面验证渲染正常、无 PHP 报错。 ## 模板切换(旧→新迁移) 区别于“导入”,切换是把**已在用的设备**从一个模板迁到另一个模板: 1. 在“优化 → 模板切换”里选 `从模板(旧)` 与 `到模板(新)`(下拉只列 `Huawei` 相关模板)。 2. 点**预览**:调用 `host.get(templateids=旧)` 列出受影响设备(最多显示 300 个名字)与实际台数,不写入。 3. 点**确认切换**:对每台设备 `host.update`,把 `templates` 集合中的旧模板替换为新模板(保留其它模板链接、去重)。LLD 会按新模板重新采集。 4. 页面顶部弹出结果提示(切换了多少台)。 > 实测:`10962(walk) → 10229(旧)` 预览正确显示 **186 device(s)**(带设备名 chips)。当前环境旧模板 10229 挂 0 台,所以反向 `10229 → 10962` 为空操作——这是数据现状,不是功能问题。 ## 已知限制(如实说明) - **核心 vs 接入的 `Link down` 无法在原型层面区分**(只有一个原型):两者统一设为“一般严重(Average=3)”,71 条核心链路不会被单独拔高;如需对核心链路更敏感,后续可加事件规则/标签区分。 - **模板“导入后切换”迁移**:功能已具备(导入 + 预览 + 确认切换)。当前环境旧模板 `Huawei VRP by SNMP(10229)` 挂载主机数为 0,全部 186 台已在 `Huawei VRP by SNMP walk(10962)`,所以“旧→新迁移”在此环境下是空操作;换到真有旧模板带机的环境才会真正迁移。 - **Geomap 底图**:Zabbix Geomap 组件需**浏览器能访问外网**加载 OSM 瓦片;纯内网环境下底图会空白(标记点逻辑仍正确)。