COBCO IT 45f617a523 fix(l2): ensureSchema() in getConfig/saveConfig so l2_topology_config always exists before read/write (config persists to DB reliably) vor 3 Tagen
..
WecomCenter 45f617a523 fix(l2): ensureSchema() in getConfig/saveConfig so l2_topology_config always exists before read/write (config persists to DB reliably) vor 3 Tagen
README.md 8d1ac543dd feat(WecomCenter): per-class & per-trigger severity editing on Maintenance tab; ship plugin via compose (auto module-enable); add usage/deploy doc vor 3 Tagen
install.sh e058c52f50 L2 topology: DB-backed 7-day history + time selector, grouped frames layout, speed/latency/alarm colours, dark mode, working terminal toggles, configurable templates/rules in ROMAN config center vor 3 Tagen

README.md

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。
    • 环境初始化 / 自检:见下文“全新 Zabbix 两步装好”——一键补媒体类型、机器人用户、动作与 {$WECOM_KEY} 宏。
  • 日常维护(Maintenance)
    • 按类别批量改告警等级:选一个“触发器类别”(如 设备离线 / 硬件故障 / 性能 …)+ 目标严重度,点 应用,即把该类别下模板触发器、触发器原型、已发现(LLD)触发器一次性改到该等级(复用策略引擎同一套写入逻辑,完全可逆)。适合“把某一类警报统一拉高/压低”。
    • 按单个触发器精确调整:按名称搜索触发器(最多显示 200 条),对每行可 ①勾选/取消 = 启用/停用告警(写 trigger.status,0 启用 / 1 停用);②行尾下拉直接选该触发器的严重度(0–5)。改完点 保存,页面自动刷新、即时可见(server 配置缓存约 60 秒内同步到告警逻辑)。
    • 单套环境常有数万个触发器,需先输入关键字搜索(最多显示 200 条)。所有调整仅改 triggers.priority / status,不删除任何对象。

所有改动都通过 Zabbix 官方 API / 受控 SQL 写入数据库,因此:换机器、重建容器、升级镜像后设置都在;只要“加载插件”即可复用。

全新 Zabbix:两步装好

第一步 —— 装插件本体(把文件搬进去):

# 在解压出来的 web-modules 目录里执行:
./install.sh                     # 自动找到运行中的 zabbix-* web 容器并复制进去
# 或指定普通(非 docker)前端模块目录:
./install.sh /usr/share/zabbix/modules

然后到 Administration → Modules → Scan directory → 启用 WecomCenter(或执行 README 末尾的 SQL)。

第二步 —— 点“初始化”:打开 WeCom Center 页面,首次进入会自动显示 First-time setup: 粘贴群机器人 Key → 点 Initialise / self-check。它会自动补齐整条链路(缺啥建啥,已存在则复用、可反复点当自检):

对象 说明
{$WECOM_KEY} 全局宏 存群机器人 webhook key
媒体类型 WeCom Group Robot type=4 webhook,内置发送脚本(markdown,失败回退 text)
机器人用户 wecomrobot 挂上面这个媒体类型,severity = High+Disaster
触发器动作 Send alarm by Wecom Robot 告警/恢复各发一条 markdown 到群里(含 {$ZBX_URL} 详情链接)

装完之后日常调参都在页面上点,不用再碰命令行。

目录结构

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
└── install.sh                    # 一步搬运脚本(docker 自动探测 / 指定目录)

安装(可移植方式)

有现成 docker-compose(推荐):仓库根目录的 docker-compose.yaml 已把插件目录做成 ${WEB_MODULES_DIR:-./web-modules}:/usr/share/zabbix/modules},并新增一次性服务 wecom-module-init 会在 MySQL 就绪后自动把 wecom_center 模块登记为已启用(幂等)。 所以 git clone 后直接 docker compose up -d,起来就有插件,无需手动启用。

  1. 持久化模块目录:web 服务下挂载宿主目录(compose 已内置,默认用仓库同级 ./web-modules):

    zabbix-web-nginx-mysql:
     volumes:
       - ${WEB_MODULES_DIR:-./web-modules}:/usr/share/zabbix/modules
    

已有环境若模块目录在别处,设环境变量 WEB_MODULES_DIR=/opt/zabbix/zabbix-server/web-modules 覆盖即可。

  1. 把本 WecomCenter/ 目录整体放到该挂载目录下(仓库里 web-modules/WecomCenter/ 即是),然后 docker compose up -d 重建 web 容器使挂载生效(数据不动,仅 web 短暂重启)。

  2. 启用模块(写入 module 表,status=1 为启用):

    • 用仓库 compose 时:wecom-module-init 服务已自动完成;
    • 手动方式(非 compose / 想手动):

      SET @nid := (SELECT COALESCE(MAX(moduleid),0)+1 FROM module);
      INSERT INTO module(moduleid,id,relative_path,status,config)
      SELECT @nid,'wecom_center','modules/WecomCenter',1,'[]'
      WHERE NOT EXISTS (SELECT 1 FROM module WHERE id='wecom_center');
      

(也可在 Administration → General → Modules 里点“启用”。)

  1. 刷新网页,左侧 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/<lang>.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 红字(<font color="warning">),并新增恢复操作发绿字(<font color="info">),两者均带前端直达链接 {$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 瓦片;纯内网环境下底图会空白(标记点逻辑仍正确)。