Webhook 自定义 Body 模板¶
通过模板语法,可自定义 Webhook 通知 Body 内容:
-
动态渲染:使用
{{ 字段名 }}直接插入告警字段(如{{ host }}、{{ df_status }}); -
数据处理:通过
{{ 变量 | 函数() }}格式化数据(如时间戳转日期、数值转百分比); -
条件分支:用
{% if ... %}实现不同状态下的 Body 差异化输出; -
JSON 输出:通过
to_json_dumps输出 JSON 对象、数组、数字、布尔值等内容; -
实时查询:嵌入
DQL("查询语句")获取关联数据(如主机 IP、系统信息)。
基础模板变量¶
模板变量的基本语法为 {{ 字段名 }},可用于渲染事件相关动态信息。以下是 Webhook 自定义 Body 中常见的模板变量及其用途:
| 模板变量 | 类型 | 说明 |
|---|---|---|
date、timestamp |
Integer | 事件产生时间,Unix 时间戳,单位为秒 |
df_status |
String(Enum) | 事件状态,可能的值为:紧急 critical、重要 error、警告 warning、正常 ok、数据断档 nodata |
df_event_id |
String | 事件唯一 ID |
df_event_link |
String | 事件详情页链接地址 |
df_title |
String | 事件标题 |
df_message |
String | 事件内容 |
df_dimension_tags |
String | 事件维度,用于标识检测对象,如 {"host":"web-001"} |
df_dimension_tags_obj |
Dict | 事件维度对象,便于按对象方式读取维度字段 |
df_monitor_id |
String | 告警策略 ID |
df_monitor_name |
String | 告警策略名称 |
df_monitor_checker_id |
String | 监控器 ID |
df_monitor_checker_name |
String | 监控器名称 |
df_monitor_checker_value |
String | 检测值,即被监控器检测的值 |
Result |
Integer, Float, String, Dict, List | 检测到的原始值,与 df_monitor_checker_value 同为检测时产生的值,但保留原始类型 |
Result_with_unit |
String | 带单位的检测值 |
df_related_data |
Dict | 关联数据 |
df_fault_id |
String | 本轮故障 ID,取值为首次故障事件的 df_event_id |
df_fault_status |
String(Enum) | 本轮故障状态,可能的值为:正常 ok、故障 fault |
df_fault_start_time |
Integer | 本轮故障发生时间,Unix 时间戳,单位为秒 |
df_fault_duration |
Integer | 本轮故障持续时间,单位为秒 |
df_site_name |
String | 当前观测云节点名 |
df_workspace_name |
String | 所属工作空间名 |
df_workspace_uuid |
String | 所属工作空间 ID |
df_label |
List | 监控器标签列表 |
df_alert_policy_names |
List | 命中的告警策略名称列表 |
df_sent_target_types |
List | 本事件已发送的告警通知对象类型列表 |
df_event |
Dict | 完整事件数据 |
df_dimension_tags 中的各字段 |
String | df_dimension_tags 中的各字段会被提取到顶层,如 host、region |
注意:
-
df_monitor_checker_value会强制转换为 String 类型以保证兼容性; -
如果需要保留检测值原始类型,建议使用
Result; -
不同监控器类型、事件来源和通知场景下,可用变量可能不同。
模板变量示例¶
假设监控器 by 配置了 region 和 host,Webhook 自定义 Body 模板如下:
{
"title": "监控器 {{ df_monitor_checker_name }} 发现 {{ df_dimension_tags }} 存在故障",
"region": "{{ region }}",
"host": "{{ host }}",
"status": "{{ df_status }}",
"value": "{{ Result }}",
"monitor": "{{ df_monitor_checker_name }}",
"policy": "{{ df_monitor_name }}"
}
那么,产生 error 事件后,经过渲染的 Body 输出如下:
{
"title": "监控器 监控器001 发现 {\"region\":\"hangzhou\",\"host\":\"web-001\"} 存在故障",
"region": "hangzhou",
"host": "web-001",
"status": "error",
"value": "90.12345",
"monitor": "监控器001",
"policy": "团队001"
}
JSON Body 输出¶
Webhook 自定义 Body 最终通常需要输出合法 JSON。推荐先定义 JSON 对象,再使用 to_json_dumps 函数处理,以避免字符串转义、对象数组嵌套、逗号遗漏等 JSON 语法错误。
示例:
{% set json_data = {
"event_id": df_event_id,
"title": df_title,
"status": df_status,
"status_text": df_status | to_status_human,
"event_link": df_event_link,
"monitor": {
"id": df_monitor_id,
"name": df_monitor_name,
"checker_id": df_monitor_checker_id,
"checker_name": df_monitor_checker_name
},
"dimension": {
"raw": df_dimension_tags,
"object": df_dimension_tags_obj,
"pretty": df_dimension_tags | to_pretty_tags
},
"value": {
"raw": Result,
"with_unit": Result_with_unit,
"type": Result | type_name
}
} %}
{{ json_data | to_json_dumps }}
输出结果如下:
{
"event_id": "event-xxxxx",
"title": "CPU 使用率过高",
"status": "error",
"status_text": "重要",
"event_link": "https://console.guance.com/keyevents/monitor/events/event-xxxxx",
"monitor": {
"id": "altpl_xxxxx",
"name": "团队001",
"checker_id": "rul_xxxxx",
"checker_name": "监控器001"
},
"dimension": {
"raw": "{\"region\":\"hangzhou\",\"host\":\"web-001\"}",
"object": {
"region": "hangzhou",
"host": "web-001"
},
"pretty": "region:hangzhou, host:web-001"
},
"value": {
"raw": 90.12345,
"with_unit": "90.12345%",
"type": "float"
}
}
逐字段渲染 JSON¶
也可以逐个字段渲染 JSON。此时需要注意字段类型:
{
"event_id": "{{ df_event_id }}",
"status": "{{ df_status }}",
"status_text": "{{ df_status | to_status_human }}",
"checker_name": "{{ df_monitor_checker_name }}",
"dimension": {{ df_dimension_tags_obj | to_json_dumps }},
"value": {{ Result | to_json_dumps }},
"related_data": {{ df_related_data | to_json_dumps }}
}
说明:
-
字符串字段可以放在双引号中,例如
"{{ df_status }}"; -
对象、数组、数字、布尔值建议使用
to_json_dumps; -
不建议将对象或数组写成
"{{ df_related_data }}",否则接收方会得到字符串,而不是 JSON 对象。
特殊场景变量¶
用户访问指标检测¶
在用户访问指标检测中,除了上述通用的模板变量外,额外支持下列模板变量:
| 模板变量 | 类型 | 说明 |
|---|---|---|
app_id |
String | 应用 ID |
app_name |
String | 应用名称 |
app_type |
String | 应用类型 |
特殊字符字段处理¶
若检测配置中 维度 字段包含特殊字符(如 -、@),例如 host-name、@level,则无法直接作为正常变量名使用,会导致模板渲染失败。
错误写法:
解决方案是使用以下格式进行引用:
{{ df_event["host-name"] }}
{{ df_event["@level"] }}
{{ df_dimension_tags_obj["host-name"] }}
{{ df_dimension_tags_obj["@level"] }}
模板函数¶
除了可以直接展示事件中的字段值外,还可以使用模板函数对字段值进行进一步处理,优化输出。
基本语法如下:
具体实例如下:
如果需要在使用模板函数之前对模板变量进行运算,请不要忘记添加括号,如:
可用的模板函数列表如下:
| 模板函数 | 参数 | 说明 |
|---|---|---|
to_datetime |
tz="Asia/Shanghai" |
将 Unix 秒级时间戳或 ISO8601 日期字符串转换为日期时间字符串 |
to_date_range_human |
lang="zh" |
将秒级时长转换为易读形式,如 1 天 2 小时 3 分钟 1 秒 |
to_status_human |
lang="zh" |
将 df_status 转换为易读状态 |
to_fixed |
ndigits=0 |
将数字输出为固定小数位数 |
to_round |
ndigits=0 |
将数字按指定小数位数取近似值 |
to_percent |
ndigits=0 |
将小数转换为百分比形式 |
to_pretty_tags |
separators=(':', ', ') |
将 dict 或 JSON 字符串格式的标签转换为易读标签文本 |
limit_lines |
lines=3, chars=None |
限制输出行数,可同时限制每行字符数 |
limit_chars / limit_text |
chars=50 |
限制输出字符数,limit_text 是 limit_chars 的别名 |
type_name |
无 | 输出数据类型名称 |
to_int |
无 | 转换为整数 |
to_float |
无 | 转换为浮点数 |
to_str |
无 | 转换为字符串 |
to_json_dumps |
indent=None |
将 dict、list 等数据转换为 JSON 序列化字符串 |
is_error |
无 | 判断对象是否为错误,常用于判断内嵌 DQL 是否执行正常 |
length |
无 | 获取字符串、列表、字典等对象的长度 |
replace |
old, new, count=-1 |
替换字符串内容,count=-1 表示全部替换 |
abs |
无 | 获取数值的绝对值 |
模板函数示例¶
{% set body = {
"object": df_dimension_tags | to_pretty_tags,
"time": date | to_datetime,
"status": df_status | to_status_human,
"value": Result | to_fixed(2),
"percent": Result | to_percent(1),
"duration": df_fault_duration | to_date_range_human,
"message": df_message | limit_lines(3, 80)
} %}
{{ body | to_json_dumps }}
模板分支¶
可以通过条件分支实现不同状态下的差异化 Body 输出。
基本语法如下:
模板分支示例¶
{% set level = "info" %}
{% if df_status == "critical" %}
{% set level = "critical" %}
{% elif df_status == "error" %}
{% set level = "error" %}
{% elif df_status == "warning" %}
{% set level = "warning" %}
{% elif df_status == "nodata" %}
{% set level = "nodata" %}
{% endif %}
{% set body = {
"level": level,
"status": df_status,
"status_text": df_status | to_status_human,
"title": df_title,
"event_link": df_event_link
} %}
{{ body | to_json_dumps }}
内嵌 DQL 查询函数¶
在仅使用模板变量无法满足渲染需求时,可以使用内嵌 DQL 查询函数补充查询数据。内嵌 DQL 会在本工作空间、本次检测时间范围内执行 DQL,通常将查询结果的第一条数据作为模板变量使用。
调用格式如下:
内嵌 DQL 查询示例¶
{% set host_info = DQL("O::HOST:(host_ip, os) { region = ?, host = ? }", region, host) %}
{% set body = {
"host": host,
"region": region,
"host_ip": host_info.host_ip,
"os": host_info.os,
"status": df_status,
"event_link": df_event_link
} %}
{{ body | to_json_dumps }}
内嵌 DQL 查询函数细节¶
-
内嵌 DQL 查询应放在模板开头;
-
DQL 语句中的参数占位符
?会在替换为具体值时自动转义; -
向 DQL 传递模板变量时,参数部分直接写变量名,如
host;不要写成{{ host }}; -
查询结果变量名不要与现有模板变量、模板函数重名;
-
如果 DQL 中使用函数处理字段,建议使用
AS指定字段别名,便于模板读取; -
如果 DQL 查询结果字段名包含特殊字符,应使用
{{ host_info["host-name"] }}形式读取; -
可配合
is_error判断 DQL 是否执行正常。
完整 Body 示例¶
以下示例适用于将告警事件发送到外部事件中心:
{% set is_recovery = df_status == "ok" %}
{% set priority = "P0" if df_status == "critical" else ("P1" if df_status in ["error", "nodata"] else ("P2" if df_status == "warning" else "INFO")) %}
{% set body = {
"source": "guance",
"event_id": df_event_id,
"event_link": df_event_link,
"title": df_title,
"status": df_status,
"status_text": df_status | to_status_human,
"priority": priority,
"is_recovery": is_recovery,
"monitor": {
"policy_id": df_monitor_id,
"policy_name": df_monitor_name,
"checker_id": df_monitor_checker_id,
"checker_name": df_monitor_checker_name
},
"object": {
"tags": df_dimension_tags_obj,
"text": df_dimension_tags | to_pretty_tags
},
"value": {
"raw": Result,
"with_unit": Result_with_unit,
"fixed_2": Result | to_fixed(2)
},
"fault": {
"fault_id": df_fault_id,
"fault_status": df_fault_status,
"start_time": df_fault_start_time | to_datetime,
"duration_seconds": df_fault_duration,
"duration_text": df_fault_duration | to_date_range_human
},
"notify": {
"alert_policy_names": df_alert_policy_names,
"sent_target_types": df_sent_target_types
}
} %}
{{ body | to_json_dumps }}
注意事项¶
-
Webhook 自定义 Body 最终渲染结果必须是合法 JSON;
-
若字段值可能包含双引号、换行、特殊字符,建议使用
to_json_dumps输出; -
对象、数组、数字、布尔值不要强行包裹成字符串;
-
调试模板时,建议先使用少量字段验证渲染结果,再逐步增加复杂字段和条件分支;
-
Webhook 自定义 Body 模板只负责渲染请求 Body;请求地址、请求头等配置仍在 Webhook 通知对象中维护。