Aviator 表达式指南

使用 Aviator 表达式灵活配置告警降噪、聚合、分派和数据预处理规则

概述

Aviator 是一个高性能的 Java 表达式引擎,1Duty 使用它来对告警 JSON 数据进行动态匹配、计算和修改。通过 Aviator 表达式,您可以编写灵活的规则来控制告警的降噪、聚合、分派和数据预处理流程。

Aviator 表达式在 1Duty 中的核心特性:

在 1Duty 中的使用场景

Aviator 表达式在以下功能中使用,每个场景对表达式的返回值要求不同:

使用场景位置返回值要求说明
排除规则 集成详情 > 降噪配置 > 排除规则 返回 true/false 返回 true 的告警将被丢弃
静默策略 集成详情 > 降噪配置 > 静默策略 返回 true/false 返回 true 的告警将被静默(不发通知)
自动关闭 集成详情 > 降噪配置 > 自动关闭 返回 true/false 返回 true 的告警对应的事件将被自动关闭
聚合规则 集成详情 > 降噪配置 > 告警聚合 返回 字符串 返回字符串作为聚合 Key,相同 Key 合并到同一事件
分派条件 集成详情 > 分派策略 > 条件过滤 返回 true/false 返回 true 则匹配该分派策略
数据预处理 集成编辑 > Webhook > 数据预处理 返回 json 对象 修改 JSON 字段值,返回修改后的 json
主动探测条件 主动探测 > 触发条件 返回 true/false 返回 true 则判定探测异常并触发告警

基本语法

引用字段

系统接收到告警后,会将 JSON 数据的所有字段展开到表达式上下文中。你可以直接使用字段名来引用告警中的任意字段,嵌套字段用点号访问。

假设收到以下告警 JSON:

{
  "title": "CPU 使用率过高",
  "severity": "CRITICAL",
  "source": "prometheus",
  "host": "web-server-01",
  "description": "CPU usage is 95%, threshold 80%",
  "labels": {
    "env": "production",
    "region": "cn-east-1",
    "team": "infra"
  },
  "value": 95.2,
  "status": "firing"
}
表达式含义结果
title引用顶层字段"CPU 使用率过高"
severity引用告警级别"CRITICAL"
value引用数值字段95.2
labels.env引用嵌套字段(点号访问)"production"
labels.region引用嵌套字段"cn-east-1"
notExist不存在的字段返回 nilnil

比较运算符

运算符说明示例结果
==等于severity == 'CRITICAL'true
!=不等于severity != 'INFO'true
>大于value > 90true
>=大于等于value >= 95.2true
<小于value < 50false
<=小于等于value <= 80false

逻辑运算符

运算符说明示例结果
&&与(AND)severity == 'CRITICAL' && value > 90true
||或(OR)severity == 'INFO' || value > 90true
!非(NOT)!(severity == 'INFO')true

字符串函数

函数说明示例
string.contains(s, sub)字符串是否包含子串string.contains(title, 'CPU') → true
string.startsWith(s, prefix)前缀匹配string.startsWith(host, 'web-') → true
string.endsWith(s, suffix)后缀匹配string.endsWith(host, '-01') → true
string.length(s)字符串长度string.length(title) → 8
string.substring(s, start, end)截取子串string.substring(host, 0, 3) → "web"

正则表达式函数

1Duty 提供了三个自定义正则函数,底层使用 RE2/J 引擎确保安全(不会因正则回溯导致性能问题):

函数说明示例
regex_match(text, pattern)是否匹配正则regex_match(title, '.*CPU.*') → true
regex_extract(text, pattern)提取第一个捕获组(无捕获组则返回完整匹配)regex_extract(description, 'is (\d+)%') → "95"
regex_replace(text, pattern, replacement)替换所有匹配regex_replace(title, '过高', '异常') → "CPU 使用率异常"

其他内置函数

函数说明示例
html2text(html)去除 HTML 标签html2text('<b>Error</b>') → "Error"

nil 安全判断

当引用的字段可能不存在时,建议先做 nil 判断,避免执行错误:

## 安全判断字段是否存在
labels != nil && labels.env == 'production'

## 结合默认值(三元表达式)
severity != nil ? severity : 'UNKNOWN'

JSON 原地修改(核心特性)

这是 1Duty 中 Aviator 表达式最强大的特性之一。在数据预处理场景中,Aviator 脚本可以通过 json.xxx = yyy 语法直接修改告警的 JSON 数据,修改会传递到外部,后续的告警处理流程将使用修改后的数据。

只有在数据预处理(Aviator 脚本规则)中才需要使用 JSON 修改功能。排除规则、静默策略等场景只需要返回 true/false。

工作原理

这意味着你可以在 Webhook 接收到告警后、系统处理之前,对告警数据进行任意修改和增强。

数据预处理示例

示例 1:给标题添加前缀

json.title = '[P0] ' + title;
return json;

示例 2:从描述中提取错误码并添加为新字段

let code = regex_extract(description, 'code: (\d+)');
if code != nil {
  json.error_code = code;
}
return json;

示例 3:根据标题关键词自动设置严重级别

if string.contains(title, 'OOM') || string.contains(title, '宕机') {
  json.severity = 'CRITICAL';
} elsif string.contains(title, '超时') {
  json.severity = 'WARNING';
}
return json;

示例 4:清理 HTML 描述并提取关键信息

json.description = html2text(description);
let ip = regex_extract(description, '(\d+\.\d+\.\d+\.\d+)');
if ip != nil {
  json.source_ip = ip;
}
return json;

示例 5:修改嵌套字段

if labels != nil && labels.env == 'staging' {
  json.title = '[Staging] ' + title;
}
return json;

各场景完整示例

场景一:排除规则 / 静默策略 / 自动关闭(返回 true/false)

这些场景中,表达式返回 true 表示命中规则,返回 false 表示不命中。

## 排除 INFO 级别的告警
severity == 'INFO'

## 排除测试环境的告警
labels != nil && labels.env == 'test'

## 静默包含特定关键词的告警
string.contains(title, '健康检查') || string.contains(title, 'heartbeat')

## 自动关闭已恢复的告警
status == 'resolved' || status == 'ok'

## 组合条件:排除低级别 + 特定来源
severity == 'INFO' && source == 'prometheus' && value < 50

## 使用正则匹配
regex_match(title, '(?i).*test.*|.*debug.*')

场景二:聚合规则(返回字符串作为聚合 Key)

表达式返回字符串,系统对结果取 MD5 后作为聚合 Key。相同 Key 的告警会被合并到同一事件。

## 按标题聚合(等效于智能聚合)
title

## 按标题 + 主机名聚合
title + '_' + host

## 按来源 + 级别聚合
source + '_' + severity

## 使用正则提取关键信息聚合
regex_extract(title, '(\S+)\s+') + '_' + severity

场景三:分派策略条件(返回 true/false)

在分派策略中,Aviator 条件用于判断告警是否匹配该策略。

## 按严重级别分派
severity == 'CRITICAL'

## 按来源 + 标签分派
source == 'prometheus' && labels != nil && labels.team == 'infra'

## 按标题关键词分派到不同团队
string.contains(title, '数据库') || string.contains(title, 'MySQL')

场景四:主动探测条件(返回 true/false)

在主动探测中,可用变量包括 status_coderesponse_timebody_sizebody_text 等。

## 状态码不是 200 或响应时间超过 3 秒
status_code != 200 || response_time > 3000

## 响应体包含错误关键词
string.contains(body_text, 'error') || string.contains(body_text, 'failed')

## 状态码正常但响应时间过长
status_code == 200 && response_time > 5000

安全限制

为了保障系统安全和稳定,1Duty 对 Aviator 表达式施加了以下限制:

限制项限制值说明
脚本最大长度10,000 字符超出长度的脚本将被拒绝
执行超时5 秒超时的脚本将被终止
循环上限100 次for/while 循环最多执行 100 次
Java 类访问完全禁止无法访问任何 Java 类
属性缺失处理返回 nil访问不存在的字段返回 nil 而非报错

常见错误

错误信息原因修复方法
Could not find variable: xxx 字段名拼写错误或字段不存在 确认 JSON 中有该字段,或加 nil 判断
NullPointerException 对 nil 值进行操作 field != nil && ... 前置判断
ClassCastException 类型不匹配(如数值与字符串比较) 确保比较类型一致
Timeout 表达式执行超过 5 秒 简化表达式,减少循环

在配置规则时,建议使用每个配置页面内置的「测试」功能来验证表达式的正确性。输入示例 JSON 数据,点击测试按钮即可查看表达式的执行结果。