- 指标监控
- 可观测性
- 告警
- 运维
【免费下载链接】zabbix
Real-time monitoring of IT components and services, such as networks, servers, VMs, applications and the cloud.
导读
本文以 Zabbix 官方仓库中的 ServiceNow 集成模板为核心,完整讲解如何借助 Zabbix 的 Webhook 媒体类型能力,将 Zabbix 中的告警事件自动同步为 ServiceNow 平台上的 incident(事件工单)。阅读并实践本文后,你将掌握:ServiceNow 端服务用户与角色的创建、media_servicenow.yaml模板的导入与参数填充、Zabbix 用户与媒体配置、事件严重级别到 ServiceNow urgency 的映射,以及恢复(recovery)与更新(update)操作对既有工单的联动逻辑,最终形成一套可直接复用的监控告警闭环。
概述:Webhook 如何打通 Zabbix 与 ServiceNow
本指南对应的官方集成模板位于仓库 templates/media/servicenow,由两个核心文件组成:
- README.md:官方配置指南(即本文主体内容的来源);
- media_servicenow.yaml:可直接导入 Zabbix 前端的 Webhook 媒体类型定义。
集成的本质是:Zabbix 的 Webhook 媒体类型内部执行一段 JavaScript 脚本,把动作(action)中定义的通知内容拼装成 JSON 请求,通过 ServiceNow 的POST /api/now/table/incidentREST API 创建 incident;当问题恢复或问题被更新时,脚本改为对.../incident/{sys_id}发送PUT请求,从而更新既有工单。这种"一个 webhook 同时覆盖创建与更新"的设计,正是该模板的核心价值。
在 Zabbix 源码层面,Webhook 媒体类型有明确的类型定义:include/zbxdbhigh.h中的MEDIA_TYPE_WEBHOOK = 4(include/zbxdbhigh.h#L265);通知的发送由 alerter 进程执行,在 alerter.c 的alerter_process_webhook()中,通过 Zabbix 内嵌的 JS 引擎(zbx_es_*系列函数)加载并执行 webhook 脚本,最终将脚本返回的 JSON(包含__zbx_servicenow_sys_id等标签)回传给事件,作为后续恢复/更新操作的依据。
适用范围与限制
官方文档明确了两点前提:
- Zabbix 版本要求:8.0 及以上(模板
zabbix_export.version同样标记为8.0); - 恢复与更新操作、以及 ServiceNow 自定义字段(custom fields)仅对触发器(trigger)产生的事件有效。对应地,模板脚本中只有在
event_source为触发器事件时才执行工单恢复/更新的PUT逻辑。
前置条件
在开始配置前,需要准备:
- 一台可访问的Zabbix 8.0+ 服务器(Webhook 媒体类型依赖内嵌 JS 引擎与 alerter 进程,需确认编译时已启用相应组件);
- 一个ServiceNow 实例(instance),并拥有管理权限;
- 用于创建工单的ServiceNow 服务账号及其密码;
- Zabbix 服务器与 ServiceNow 实例之间的网络连通性(HTTPS 出站)。
Webhook 参数详解
导入媒体类型后,可在"媒体类型 -> ServiceNow -> 参数"中查看和修改参数。模板脚本会读取全部参数:以servicenow_开头的参数被提取为连接与工单核心配置,以u_开头的参数被识别为 ServiceNow 自定义字段(custom field),其余预定义参数用于事件解析。
可配置参数
| 参数名 | 默认值 | 说明 |
|---|---|---|
| servicenow_password | \<PLACE PASSWORD HERE\> | ServiceNow 服务用户的密码。 |
| servicenow_url | \<PLACE URL HERE\> | ServiceNow 实例的完整 URL(如https://\<INSTANCE>.service-now.com/),脚本会自动拼接api/now/table/incident作为工单 REST 接口。 |
| servicenow_user | \<PLACE USERNAME HERE\> | ServiceNow 服务账号的用户名。 |
| tls_verify | {$HTTP.TLS.VERIFY:"ServiceNow"} | HTTP 请求的 TLS 证书校验策略:none关闭校验,peer校验证书链与有效期,full进行完整校验(同时校验主机名);任何其他值都会被当作full。可通过定义上下文为ServiceNow的全局宏(即{$HTTP.TLS.VERIFY:"ServiceNow"})针对该媒体类型单独覆盖。 |
| urgency_for_average | 2 | 事件严重级别为 Average 时映射的 ServiceNow urgency 值。 |
| urgency_for_disaster | 1 | 事件严重级别为 Disaster 时映射的 ServiceNow urgency 值。 |
| urgency_for_high | 2 | 事件严重级别为 High 时映射的 ServiceNow urgency 值。 |
| urgency_for_information | 3 | 事件严重级别为 Information 时映射的 ServiceNow urgency 值。 |
| urgency_for_not_classified | 3 | 事件严重级别为 Not classified 时映射的 ServiceNow urgency 值。 |
| urgency_for_warning | 3 | 事件严重级别为 Warning 时映射的 ServiceNow urgency 值。 |
从 media_servicenow.yaml 中的脚本逻辑可以看到,urgency_for_*与严重级别的对应关系是通过severities数组(not_classified/information/warning/average/high/disaster)与EVENT.NSEVERITY数值(0–5)联动的:脚本读取params['urgency_for_' + severity_name]写入工单的urgency字段。也就是说,你可以按需调整每个严重级别对应的 urgency,例如把 Disaster 调成1(最高紧急度)而 Information 保持3。
HTTP 代理支持:每个 webhook 都支持 HTTP 代理。如需使用,在媒体类型参数中新增一个名为
http_proxy的参数,值填写代理 URL 即可。脚本中对应逻辑为ServiceNow.setProxy(params.HTTPProxy)。
内部参数
以下参数为脚本预定义宏,不建议修改,它们承载事件上下文:
| 参数名 | 值 | 说明 |
|---|---|---|
| alert_message | {ALERT.MESSAGE} | 动作配置中"Default message"(默认消息)的值。 |
| alert_subject | {ALERT.SUBJECT} | 动作配置中"Default subject"(默认主题)的值。 |
| event_nseverity | {EVENT.NSEVERITY} | 事件严重级别的数值:0 – Not classified,1 – Information,2 – Warning,3 – Average,4 – High,5 – Disaster。 |
| event_recovery_value | {EVENT.RECOVERY.VALUE} | 恢复事件的数值。 |
| event_source | {EVENT.SOURCE} | 事件来源数值:0 – Trigger,1 – Discovery,2 – Autoregistration,3 – Internal,4 – Service。 |
| event_update_status | {EVENT.UPDATE.STATUS} | 问题更新状态数值:0 – Webhook 因问题/恢复事件被调用,1 – 更新操作。 |
| event_value | {EVENT.VALUE} | 触发动作的事件数值(1 表示问题发生,0 表示恢复)。 |
| servicenow_sys_id | {EVENT.TAGS.__zbx_servicenow_sys_id} | 已创建工单的 ServiceNow sys_id(由脚本写入事件标签,供恢复/更新时定位工单)。 |
这些参数与脚本中的输入校验一一对应。例如脚本会校验event_source必须在 0–3 范围内,event_value在来源为 Trigger/Internal 时必须是 0 或 1,event_update_status在 Trigger 来源下必须是 0 或 1;当event_source不是 0(非触发器)且event_recovery_value为 0 时,会直接抛出"恢复操作仅支持触发器事件"的错误——这正是官方文档"recovery/update 仅支持 trigger 事件"的底层实现。
ServiceNow 端设置
在开始 Zabbix 配置前,需要先准备好 ServiceNow 侧的工作:
- 创建服务用户:登录 ServiceNow 管理后台,创建一个专门用于创建 incident 的系统用户(不要使用个人账号);
- 授予角色:给该用户分配两个角色:
rest_api_explorer:允许通过 REST API 进行资源浏览与调用;sn_incident_write:允许创建/写入 incident 记录。
该用户将作为 Zabbix webhook 调用 ServiceNow API 时的 Basic Auth 凭证来源(脚本中以
Authorization: Basic base64(user:password)头携带),因此务必妥善保管其密码。
Zabbix 端配置步骤
第 1 步:设置全局宏(推荐)
建议先定义全局宏{$ZABBIX.URL},其值为 Zabbix 前端的 URL。该宏可在后续用于向 ServiceNow 自定义字段填充"事件详情 / 图表"的跳转链接。在 Zabbix 前端的Administration -> General -> Macros(全局宏)页面中配置:
第 2 步:导入媒体类型
在Administration -> Media types(管理 -> 媒体类型)中,点击"Import"导入 media_servicenow.yaml。导入成功后即可看到名为ServiceNow的媒体类型,类型为 Webhook(模板中以type: WEBHOOK声明,默认状态为DISABLED)。
第 3 步:填充占位符参数
打开ServiceNow媒体类型,将<PLACEHOLDERS>替换为实际值,以下三个参数必填:
- servicenow_user:前面创建的 ServiceNow 用户登录名;
- servicenow_password:该用户的密码;
- servicenow_url:ServiceNow 实例完整 URL(
https://\<INSTANCE>.service-now.com/)。
自定义字段导出:若需要把信息写入 ServiceNow 的自定义字段,可新增一个参数,参数名使用自定义字段的 ID(形如u_field_name),参数值使用 Zabbix 宏。脚本会遍历所有以u_开头的参数,将其逐项写入 incident 数据中(见ServiceNow.setFields())。
注意事项(来自官方文档):
- ServiceNow 实例时区必须与 Zabbix 服务器时区一致;
- 对Date/time 类型字段,参数值需用空格分隔日期与时间,例如
"{EVENT.DATE} {EVENT.TIME}"; - 对纯日期字段,参数值仅允许包含返回日期的宏(如
{EVENT.DATE}、{EVENT.RECOVERY.DATE}),脚本会自动把 Zabbix 的yyyy.MM.dd格式转换为 ServiceNow API 兼容的yyyy-MM-dd格式(对应setFields中的正则^\d{4}\.\d{2}\.\d{2}$与replace(/\./g, '-')); - 如果不想让信息在 description 字段与自定义字段中重复,可在
Message templates(消息模板)页签中修改Problem、Problem recovery和Problem update三类消息模板。
第 4 步:创建 Zabbix 用户并配置媒体
- 在 Zabbix 中创建一个用户(
Administration -> Users); - 为该用户添加Media(媒体),类型选择ServiceNow;
- 注意:虽然 ServiceNow webhook 不使用
Send to(发送到)字段,但该字段不能留空,否则无法通过前端校验——随意输入任意字符即可; - 确保该用户对所有需要把告警转换为 ServiceNow 工单的主机都有访问权限,否则这些主机的告警不会触发通知。
第 5 步:创建动作(Action)
在Alerts -> Actions -> Trigger actions中创建动作,绑定上述用户/媒体,并设置操作(operation)使用 ServiceNow 媒体类型发送通知。动作中的默认主题与消息会分别映射到{ALERT.SUBJECT}和{ALERT.MESSAGE},进而写入工单的short_description(简短描述)、description(描述)与comments(备注)字段。
消息模板:工单内容的标准化
导入的媒体类型自带一整套消息模板(定义于 media_servicenow.yaml 的message_templates),覆盖多类事件来源与操作模式:
- TRIGGERS / PROBLEM:主题
Problem: {EVENT.NAME},正文包含问题开始时间、问题名、主机名、严重级别、操作数据、原始问题 ID 与触发器 URL; - TRIGGERS / RECOVERY:主题
Resolved in {EVENT.DURATION}: {EVENT.NAME},包含恢复耗时、恢复时间等; - TRIGGERS / UPDATE:主题
Updated problem in {EVENT.AGE}: {EVENT.NAME},包含更新人、更新动作、当前状态与确认状态; - DISCOVERY / PROBLEM:网络发现事件模板,包含设备 IP/DNS/状态/运行时长与服务信息;
- AUTOREGISTRATION / PROBLEM:自动注册事件模板;
- INTERNAL / PROBLEM、RECOVERY:内部事件模板;
- SERVICE / PROBLEM、RECOVERY、UPDATE:服务(Service)事件模板,包含服务名、严重级别、根因描述等。
这些模板决定了工单正文的信息结构,你可以按团队规范自由增删宏。
工单生命周期:创建、恢复与更新的底层逻辑
从 media_servicenow.yaml 的脚本可见完整的工单生命周期处理:
- 问题发生时(POST 创建工单):默认
method = 'post',脚本把short_description、description、comments、urgency及自定义字段组装为 JSON,POST 到servicenow_url + api/now/table/incident; - 写入回传标签:创建成功后,脚本把返回结果写入事件标签:
__zbx_servicenow_sys_id(工单 sys_id)、__zbx_servicenow_link(工单直达链接)、__zbx_servicenow_number(工单编号),并以JSON.stringify(result)返回; - 问题恢复或更新时(PUT 更新工单):当
event_source == 0(触发器事件)且event_value == 0(恢复)或event_update_status == 1(更新)时,脚本将process_tags置为false、方法改为put、删除description与urgency,并拼接servicenow_sys_id定位到既有工单后发送 PUT 请求; - 事件菜单联动:模板还启用了
process_tags与show_event_menu,event_menu_url指向{EVENT.TAGS.__zbx_servicenow_link},event_menu_name显示为ServiceNow: {EVENT.TAGS.__zbx_servicenow_number}——即在 Zabbix 问题详情中可以直接看到并跳转到对应的 ServiceNow 工单。
请求与错误处理
脚本通过HttpRequest对象发起请求,携带Content-Type: application/json与 Basic Auth 头;若配置了http_proxy则通过代理发送。响应状态码不在 200–299 范围内,或响应缺少result.sys_id时,脚本会抛出带状态码与错误信息的异常并记录到 debug 日志(Zabbix.log(4, ...)记录请求/响应详情,Zabbix.log(3, ...)记录错误摘要)。排障时可在媒体类型测试界面或Administration -> Audit log中查看日志。
TLS 校验细节
CTlsConfig将tls_verify归一化后映射为两个底层选项:SSLVerifyPeer(peer/full时启用)与SSLVerifyHost(仅full时启用);并且当校验开启时,checkURL()会强制要求 URL 为https://,否则直接报错提示改用 HTTPS 或把{$HTTP.TLS.VERIFY}设为none——这能有效防止凭证在明文 HTTP 下泄露。
告警执行链路与源码印证
了解 webhook 在 Zabbix 内部的执行路径,有助于定位"为什么没收到工单"这类问题:
- 动作触发:
src/zabbix_server/escalator/escalator.c在升级(escalation)流程中处理 webhook 通知:从数据库取出 webhook 参数、对脚本与参数执行宏替换(substitute_message_macros),再通过zbx_webhook_params_pack_json把参数打包为 JSON 传入脚本执行(escalator.c#L1508-L1540); - 脚本执行:alerter 进程的
alerter_process_webhook()(alerter.c#L475-L510)反序列化 webhook 数据、初始化内嵌 JS 引擎(zbx_es_init_env)、设置超时与调试模式后,调用zbx_es_execute运行脚本,并把脚本输出/错误回传; - 媒体类型注册:webhook 作为媒体类型的一种,在
include/zbxdbhigh.h中以MEDIA_TYPE_WEBHOOK = 4参与数据库存取(include/zbxdbhigh.h#L265)。
因此,一条告警从"问题产生"到"ServiceNow 出现工单",完整路径为:事件 → 动作/升级(escalator)→ alerter 进程 → 内嵌 JS 引擎执行 webhook 脚本 → HTTP 调用 ServiceNow REST API → 写入事件标签回传 sys_id。
常见问题与排障建议
- 媒体类型导入后无法发送:确认已把三个必填占位符(user/password/url)替换为真实值;脚本对缺失的
url/user/password会抛出Required ServiceNow param is not set: "..."。 - TLS 校验报错:若 URL 为
http://而tls_verify未设为none,脚本会拒绝请求——优先改用 HTTPS 实例地址。 - 恢复/更新不生效:确认事件来源为触发器(trigger)事件;非触发器事件的恢复操作会被脚本直接拒绝。
- 工单内容缺失自定义字段:检查参数名是否以
u_开头、字段 ID 是否正确、纯日期字段是否只包含日期类宏。 - 时区与日期格式问题:ServiceNow 实例与 Zabbix 服务器时区必须一致;日期时间字段要用
{EVENT.DATE} {EVENT.TIME}这种空格分隔格式。 - 查看详细日志:将媒体类型测试时的 debug 日志打开(脚本以
Zabbix.log(4, ...)输出请求与响应),并结合 alerter 进程日志确认脚本执行结果。
小结
通过本指南,你可以在 Zabbix 8.0+ 上完成 ServiceNow 的端到端集成:导入官方 media_servicenow.yaml 媒体类型、配置三要素与 severity→urgency 映射、创建带媒体授权的用户与动作,即可实现"告警自动建单、恢复自动更新、问题详情一键跳转工单"的完整闭环。结合本文给出的源码链路(escalator → alerter → 内嵌 JS 引擎 → ServiceNow REST API),当集成出现异常时,你也可以从 Zabbix 内部执行路径出发快速定位问题。
若在使用过程中遇到媒体类型本身的缺陷,可到 Zabbix 官方支持站点(support.zabbix.com)提交 issue,或在 Zabbix 官方论坛中讨论该媒体类型的设计与改进建议。
- 指标监控
- 可观测性
- 告警
- 运维
【免费下载链接】zabbix
Real-time monitoring of IT components and services, such as networks, servers, VMs, applications and the cloud.
相关推荐
Zabbix 8.0 与 Event-Driven Ansible 集成实战:Webhook 媒体类型接入指南
Zabbix 8.0 与 Event Driven Ansible 集成实战:Webhook 媒体类型接入指南 本文基于 Zabbix 官方模板仓库中的 tem
指标监控可观测性告警运维Zabbix 与 GitHub 集成指南:使用 Webhook 媒体类型自动创建 Issue
Zabbix 与 GitHub 集成指南:使用 Webhook 媒体类型自动创建 Issue 导读 本文讲解如何在 Zabbix 8.0 及以上版本中,通过自带
指标监控可观测性告警运维OneUptime 与 Zabbix 集成实战:通过 Webhook 媒体类型与 Workflow 自动创建与解除事件
OneUptime 与 Zabbix 集成实战:通过 Webhook 媒体类型与 Workflow 自动创建与解除事件 本篇技术指南以 OneUptime 官方
可观测性后端运维前端云原生微服务AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考