Webhook Custom Body Templates¶
With template syntax, you can customize the Body content of Webhook notifications:
-
Dynamic rendering: use
{{ field_name }}to insert alert fields directly (for example,{{ host }}or{{ df_status }}); -
Data processing: format data with
{{ variable | function() }}(for example, converting a timestamp to a date, or a value to a percentage); -
Conditional branching: use
{% if ... %}to achieve differentiated Body output under different statuses; -
JSON output: use
to_json_dumpsto output JSON objects, arrays, numbers, booleans, and more; -
Real-time queries: embed
DQL("query statement")to retrieve related data (such as host IP and system information).
Basic Template Variables¶
The basic syntax of template variables is {{ field_name }}, which can be used to render dynamic information about events. The following table lists common template variables in Webhook custom Bodies and their purposes:
| Template Variable | Type | Description |
|---|---|---|
date, timestamp |
Integer | Time when the event was generated, Unix timestamp in seconds |
df_status |
String(Enum) | Event status. Possible values: Critical (critical), Error (error), Warning (warning), OK (ok), No Data (nodata) |
df_event_id |
String | Unique event ID |
df_event_link |
String | Link to the event details page |
df_title |
String | Event title |
df_message |
String | Event content |
df_dimension_tags |
String | Event dimension tags, used to identify the detected object, for example {"host":"web-001"} |
df_dimension_tags_obj |
Dict | Event dimension object, for reading dimension fields as an object |
df_monitor_id |
String | Alert policy ID |
df_monitor_name |
String | Alert policy name |
df_monitor_checker_id |
String | Monitor ID |
df_monitor_checker_name |
String | Monitor name |
df_monitor_checker_value |
String | Detection value, that is, the value detected by the monitor |
Result |
Integer, Float, String, Dict, List | Raw value detected. Like df_monitor_checker_value, it is generated at detection time, but retains its original type |
Result_with_unit |
String | Detection value with unit |
df_related_data |
Dict | Related data |
df_fault_id |
String | ID of the current fault, equal to the df_event_id of the first fault event |
df_fault_status |
String(Enum) | Status of the current fault. Possible values: OK (ok), Fault (fault) |
df_fault_start_time |
Integer | Time when the current fault occurred, Unix timestamp in seconds |
df_fault_duration |
Integer | Duration of the current fault, in seconds |
df_site_name |
String | Name of the current Guance node |
df_workspace_name |
String | Name of the workspace it belongs to |
df_workspace_uuid |
String | ID of the workspace it belongs to |
df_label |
List | List of monitor labels |
df_alert_policy_names |
List | List of matched alert policy names |
df_sent_target_types |
List | List of alert notification target types to which this event has been sent |
df_event |
Dict | Complete event data |
Fields in df_dimension_tags |
String | Fields in df_dimension_tags are extracted to the top level, such as host and region |
Note:
-
df_monitor_checker_valueis forcibly converted to the String type for compatibility; -
If you need to retain the original type of the detection value, it is recommended to use
Result; -
Available variables may vary by monitor type, event source, and notification scenario.
Template Variable Example¶
Suppose the monitor's by clause is configured with region and host, and the Webhook custom Body template is as follows:
{
"title": "Monitor {{ df_monitor_checker_name }} detected a fault in {{ df_dimension_tags }}",
"region": "{{ region }}",
"host": "{{ host }}",
"status": "{{ df_status }}",
"value": "{{ Result }}",
"monitor": "{{ df_monitor_checker_name }}",
"policy": "{{ df_monitor_name }}"
}
After an error event is generated, the rendered Body output is as follows:
{
"title": "Monitor Monitor 001 detected a fault in {\"region\":\"hangzhou\",\"host\":\"web-001\"}",
"region": "hangzhou",
"host": "web-001",
"status": "error",
"value": "90.12345",
"monitor": "Monitor 001",
"policy": "Team 001"
}
JSON Body Output¶
The final Webhook custom Body usually needs to output valid JSON. It is recommended to define a JSON object first and then process it with the to_json_dumps function, to avoid JSON syntax errors such as string escaping, nested objects and arrays, and missing commas.
Example:
{% 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 }}
The output is as follows:
{
"event_id": "event-xxxxx",
"title": "CPU usage too high",
"status": "error",
"status_text": "Error",
"event_link": "https://console.guance.com/keyevents/monitor/events/event-xxxxx",
"monitor": {
"id": "altpl_xxxxx",
"name": "Team 001",
"checker_id": "rul_xxxxx",
"checker_name": "Monitor 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"
}
}
Rendering JSON Field by Field¶
You can also render JSON field by field. In this case, pay attention to field types:
{
"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 }}
}
Notes:
-
String fields can be placed in double quotes, for example
"{{ df_status }}"; -
For objects, arrays, numbers, and booleans, it is recommended to use
to_json_dumps; -
It is not recommended to write objects or arrays as
"{{ df_related_data }}"; otherwise, the receiver will get a string instead of a JSON object.
Variables for Special Scenarios¶
RUM Metric Detection¶
In RUM metric detection, in addition to the common template variables above, the following template variables are also supported:
| Template Variable | Type | Description |
|---|---|---|
app_id |
String | App ID |
app_name |
String | App name |
app_type |
String | App type |
Handling Fields with Special Characters¶
If the dimensions field in the detection configuration contains special characters (such as - or @), for example host-name or @level, it cannot be used directly as a normal variable name, which causes template rendering to fail.
Incorrect syntax:
The solution is to reference them in the following format:
{{ df_event["host-name"] }}
{{ df_event["@level"] }}
{{ df_dimension_tags_obj["host-name"] }}
{{ df_dimension_tags_obj["@level"] }}
Template Functions¶
In addition to directly displaying field values from events, you can also use template functions to further process field values for better output.
The basic syntax is as follows:
{{ <template_variable> | <template_function> }}
{{ <template_variable> | <template_function>(arguments) }}
Here is a concrete example:
If you need to perform arithmetic on a template variable before applying a template function, do not forget to add parentheses, for example:
The available template functions are as follows:
| Template Function | Arguments | Description |
|---|---|---|
to_datetime |
tz="Asia/Shanghai" |
Converts a Unix timestamp in seconds or an ISO8601 date string to a datetime string |
to_date_range_human |
lang="zh" |
Converts a duration in seconds to a human-readable form, such as 1 day 2 hours 3 minutes 1 second |
to_status_human |
lang="zh" |
Converts df_status to a human-readable status |
to_fixed |
ndigits=0 |
Outputs a number with a fixed number of decimal places |
to_round |
ndigits=0 |
Rounds a number to the specified number of decimal places |
to_percent |
ndigits=0 |
Converts a decimal to a percentage |
to_pretty_tags |
separators=(':', ', ') |
Converts dict or JSON string tags into readable tag text |
limit_lines |
lines=3, chars=None |
Limits the number of output lines and can also limit the number of characters per line |
limit_chars / limit_text |
chars=50 |
Limits the number of output characters; limit_text is an alias for limit_chars |
type_name |
None | Outputs the name of the data type |
to_int |
None | Converts to an integer |
to_float |
None | Converts to a float |
to_str |
None | Converts to a string |
to_json_dumps |
indent=None |
Converts dict, list, and other data into a JSON-serialized string |
is_error |
None | Determines whether an object is an error; often used to check whether an embedded DQL executed normally |
length |
None | Returns the length of a string, list, dict, or other object |
replace |
old, new, count=-1 |
Replaces string content; count=-1 means replace all |
abs |
None | Returns the absolute value of a number |
Template Function Example¶
{% 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 }}
Template Branches¶
You can use conditional branches to achieve differentiated Body output for different statuses.
The basic syntax is as follows:
Template Branch Example¶
{% 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 }}
Embedded DQL Query Function¶
When template variables alone cannot meet the rendering requirements, you can use the embedded DQL query function to supplement data. The embedded DQL executes the DQL within the current workspace and the time range of the current detection, and usually uses the first record of the query result as a template variable.
The call format is as follows:
Embedded DQL Query Example¶
{% 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 }}
Embedded DQL Query Function Details¶
-
The embedded DQL query should be placed at the beginning of the template;
-
The parameter placeholder
?in the DQL statement is automatically escaped when replaced with specific values; -
When passing template variables to DQL, write the variable name directly in the arguments, such as
host; do not write{{ host }}; -
The variable name of the query result must not conflict with existing template variables or template functions;
-
If functions are used to process fields in DQL, it is recommended to use
ASto specify a field alias for easy access in the template; -
If a field name in the DQL query result contains special characters, read it in the form
{{ host_info["host-name"] }}; -
You can use
is_errorto determine whether the DQL executed normally.
Complete Body Example¶
The following example is suitable for sending alert events to an external event center:
{% 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 }}
Notes¶
-
The final rendered result of a Webhook custom Body must be valid JSON;
-
If a field value may contain double quotes, line breaks, or special characters, it is recommended to use
to_json_dumpsfor output; -
Do not forcibly wrap objects, arrays, numbers, or booleans in strings;
-
When debugging a template, it is recommended to first verify the rendering result with a few fields, and then gradually add complex fields and conditional branches;
-
The Webhook custom Body template is responsible only for rendering the request Body; configurations such as the request URL and request headers are still maintained in the Webhook notification target.