事件处理与告警
DeviceChain 将原始设备遥测转化为可采取行动的信号。专用 event-processing 服务观察流水线中的事件。其检测阶段实时评估流式规则,随后动作阶段执行每次触发声明的自动响应:触发告警(具有生命周期、严重程度和通知人员路径的有状态条件),或向设备发送命令。
服务按事件时间评估并持久保存状态,因此重启会重新推导相同触发结果,不遗漏、不重复。
规则保存在哪里
你在**设备配置文件**上定义检测规则。它是一个或多个设备类型共享、支持版本管理的能力契约。配置文件支持版本管理(草稿 → 发布 → 回滚),因此设备群检测逻辑与指标、命令定义采用同样的修改方式:编写草稿、原子发布,必要时回滚。所有解析到该配置文件的设备都会自动使用其规则。
规则描述配置文件遥测数据上的条件,声明严重程度,并列出触发时运行的动作。
将规则限定到分组
默认规则适用于解析到该配置文件的所有设备。也可以将规则限定到动态分组,使其只对当前成员触发。例如,只对干旱地区的设备执行更严格的高温规则。作用域按规则可选设置。缺失和区域关联规则不能限定分组,发布这种规则会被拒绝。
事件解析时记录分组成员关系。因此,引擎看到的是当时准确适用的规则,包括重放历史进行预览或重新推导触发结果时。设备加入或离开分组后,在下一次事件上加入或移除(device-management 多副本运行时约五秒内生效),无需编辑规则或重新扫描。
条件类型
检测覆盖阈值、持续时间、重复出现、变化率、静默/缺失、连接状态、窗口聚合和区域/分组关联条件。
| 条件 | 触发时机 | 参数 |
|---|---|---|
| 阈值 | 读数满足比较,例如 temperature > 80 | 比较表达式 + 阈值 |
| 持续时间 | 条件连续成立至少指定时长,例如 pressure low for 5 minutes | 持续时长 |
| 重复 | 条件在窗口内出现指定次数,例如 3 faults in 10 minutes | 出现次数 + 窗口 |
| 变化率 | 指标在相邻读数间变化过快,例如 temperature rising > 5°/s | 比较表达式 + 可选标志,将变化规范化为每秒速率 |
| 缺失 / 静默 | 设备静默,窗口内没有任何事件(失联检查);所有事件都算心跳,因此规则没有条件 | 静默窗口 |
| 连接状态 | 设备明确上报断开时触发、重连时解除;适用于 Sparkplug-B、LwM2M 等主动声明在线状态的传输。通过控制台表单、自动化画布或 API 编写。 | 无,在线状态边沿就是完整信号 |
| 窗口聚合 | 窗口内聚合值满足比较,例如 average > 50 over 10 minutes | 函数(count/sum/avg/min/max)、窗口(滚动、滑动、会话或 N 个事件的计数窗口)、比较表达式 + 值 |
| 区域关联 | 区域内足够多的不同设备同时满足条件,例如 ≥ 3 devices in a zone report a fault within 5 minutes | 区域/锚点类型、不同设备数量 + 窗口 |
每个条件的比较可以是结构化 metric · operator · value 叶节点,也可以是针对事件的高级 CEL 表达式。两者都在配置文件发布时进行静态类型检查和成本限制,因此格式错误或计算失控的规则在运行前就会被拒绝。
规则声明的每个时间跨度默认最多 24 小时。要求更长时,会在配置文件发布时被拒绝,错误指出字段和限制。参见规则时间限制。
规则时间限制
默认 24 小时上限适用于规则声明的所有时间跨度:窗口、持续时长、静默超时和会话间隔。
设置上限是因为窗口规则在整个窗口中,为每台设备的每条读数保留一条记录,而引擎由所有租户共享。设备群每隔几秒上报、多天窗口会长期占用大量内存。整个实例共同承担成本,而不只是编写规则的租户。
静默超时和会话间隔也有上限,虽然它们不保存读数。这些规则每次设备上报都会重新设定计时器,被替代的计时器要等截止时间到达才释放。因此,频繁上报下的长超时也会类似地累积。
如果需要更长时段,运维人员可以在评估内存容量后提高实例限制(maxRuleDurationSeconds)。请求之前,请考虑实际问题是保留数据还是检测。“与上个月比较”通常更适合查询已存储历史,而不是在内存中保留一个月读数。
在表单或画布打开已存规则
表单构建器和自动化画布都能编写连接状态规则。在线状态边沿是完整信号,因此两者都不为该类型提供条件或参数:画布上是 **连接状态(Connectivity)**节点,与其他条件一样,接收来源流并连接动作。
两种界面都不会静默重写无法完整显示的规则。如果表单打开无法完整表示的已存规则(未建模字段或未知类型),会警告部分定义未显示,保存将只用可见部分替换原始内容。这与定义不是有效 JSON 时显示的“无法读取”提示不同。连接状态规则打开时不会出现这两种提示。
画布更严格。打开已存规则时,它询问编译器,按当前布局保存是否会保留原定义的全部内容。答案不是肯定时,画布说明原因并禁用该规则的保存:
- 规则类型没有对应节点,或字段/动作类型未建模时,请通过 API 编辑。表单也可打开,但会警告保存会丢弃无法显示的内容。
- 如果按画布布局生成的规则无法编译,画布无法确认保存能完整保留它,请改用表单编辑。
- 画布无法访问编译器检查时,选择再次检查(Check again)。检查完成前保持禁用保存。
两种情况专门适用于画布构建的规则:
- 如果上次在画布保存后,规则定义通过 API 改变,已存布局不再匹配规则。画布根据当前定义重新布局并告知,避免保存撤销该变更。无法完整布局当前规则时,禁用保存。
- 如果已存画布本身不再能够编译,它会按原样打开并显示说明。修复画布后,保存会用画布内容替换已存规则。不能编译的画布无法与规则比较,因此若上次画布保存后规则也经 API 修改,此处保存会撤销该修改。说明会指出这一点。
静态与动态阈值
阈值可以是规则上的固定值,也可以是动态值:规则评估时读取的设备属性名称。动态阈值让同一规则适配不同设备。配置文件只定义一次规则,各设备通过 SERVER 或 SHARED 作用域属性携带自身限制(服务器设置值优先)。修改属性即可改变实际阈值,无需编辑规则。
CEL 表达式中的动态阈值
CEL 表达式中,事件测量是映射 m,设备属性是映射 attr,两者都是键到数字的映射。只有设备在 SERVER 或 SHARED 作用域下具有数值时,键才存在于 attr。从未设置、设为非数值、设在 CLIENT 作用域,以及设置后等待变更到达检测引擎的短暂时间内,键都不存在。
读取值前请先测试是否存在。表单动态阈值编译为 "tempLimit" in attr && "temp" in m && m["temp"] > attr["tempLimit"],没有属性的设备不会触发。表单没有回退值。要回退固定限制,请自行编写回退比较:
"temp" in m && ("tempLimit" in attr ? m["temp"] > attr["tempLimit"] : m["temp"] > 80.0)
该表达式不可能在没有 temp 的事件上成立,因此规则只查看携带 temp 的事件。没有该测量的事件会跳过,不会解除阈值告警,也不会取消持续时间计时。
如果阈值或持续时间条件对缺少所读属性的所有设备、无论事件携带什么内容都成立,会在配置文件发布时拒绝。例如,!("tempLimit" in attr) || m["temp"] > attr["tempLimit"] 会在属性缺失期间,无论设备上报什么都对它触发告警。仍依赖读数的条件,例如 !("tempLimit" in attr) && m["temp"] > 80.0,可以接受。请注意,它也适用于属性类型或作用域错误的设备,不只是从未设置属性的设备。
可以接受的写法会带有警告。当规则的条件用 && 把“某个属性未设置”的判断与其他判断连在一起时,例如 !("tempLimit" in attr) && m["temp"] > 80.0,表单、画布和“描述”入口都会显示一条警告,指出该属性,并说明规则适用于所有没有该属性的设备。警告只是提示:规则照常保存,并严格按所写内容求值。之所以提示,是因为“未设置”比“未配置”范围更广,规则也会覆盖属性类型或作用域错误的设备。当该判断是“或”的一个分支而不是必要条件时,警告更为严重,例如 "temp" in m && (!("tempLimit" in attr) || m["temp"] > attr["tempLimit"]):无论设备上报什么,该条件对所有没有此属性的设备都成立,因此不会对它们应用任何阈值。请使用上面的条件写法,为它们提供备用限值。
重复、变化率、窗口聚合和区域关联规则中的条件用于筛选计数事件,因此 !("maint" in attr)(“未处于维护状态的设备”)等筛选可以接受,但同样会显示该警告。该属性只保存数字,所以对于 maint 标志被设置为布尔值、字符串或使用客户端作用域的设备,这个筛选同样成立。
自动动作
规则触发时运行其动作。内置动作有:
- 触发告警:为设备打开或升级有状态告警,见下文。它是表单和画布中新动作的默认类型,除严重程度外无需目标。没有动作的规则不会产生告警,只输出可订阅的检测结果。
- 发送命令:通过持久化命令流水线将命令发回设备。派发幂等,因此重放或重试不会重复发送。
- 调用 webhook(
httpCall):向外部 HTTP 端点 POST 经 CEL 组织的载荷,提供加固投递(拒绝重定向、移除保留标头)和可选密钥存储认证。 - 发布到连接器(
publish):将经 CEL 组织的载荷交给**出站连接器**,转发到消息代理或云队列(MQTT、Kafka、AWS SNS/SQS)。
两种出站动作 httpCall 和 publish 见**出站连接器**。独立服务负责投递,缓慢外部系统不会拖慢检测。
规则可以携带多个动作,数量有较小固定上限。区域关联规则不携带动作:其触发属于区域,而不是设备,但每个动作都面向设备。每个动作可根据触发结果设置守卫条件。例如,同一规则每次触发都产生告警,但只在读数位于特定区间时发送命令。
触发是边沿触发:条件开始成立时上升沿,停止成立时下降沿。因此,上升沿产生的告警在下降沿自动解除。你编写触发,解除是隐含行为。
编写与预览规则
控制台提供三种编写方式。全部使用同一模式,并在发布前由同一服务器端编译器验证:
- 表单构建器:每种条件对应带类型表单,是编写单条规则的最快路径。编辑时在发布前就内联显示编译器类型与成本反馈。动作选择器只提供触发告警和发送命令。守卫条件与出站动作在画布编写,表单只读显示,并在保存时保留。
- 可视化自动化画布:节点图(来源 → 条件 → 可选分支 → 动作)支持更丰富流程。画布编译为与表单相同的规则,是编写界面,而不是第二套引擎。它提供分支节点(按守卫条件将触发结果路由到不同动作)和计算节点(为可复用派生值命名,并在条件或守卫中引用)。所有条件类型都有对应节点。
- 自然语言**“描述(Describe)”入口**:启用 AI 服务后,用文字描述规则,获得候选草稿供审查和发布。创建新规则时提供,生成的模式与另外两个入口一致。参见 AI 辅助编写。
画布的突出功能是针对历史预览。你可以让草稿规则在配置文件的事件历史重放上运行,查看选定窗口内本应产生的触发/解除边沿,无需发布。选择一次触发,会在画布叠加逐节点轨迹,显示事件路径:匹配哪个条件、经过哪个分支、触发哪个动作。反复编辑和预览,直到符合预期,再发布。
告警生命周期
触发的告警是有状态对象,不是一次性消息。其状态结合两个轴,构成四状态模型:
- 状态:条件成立时为
ACTIVE,解除后为CLEARED。 - 已确认:是否有运维人员接管告警,并记录谁在何时接管。
告警经过 ACTIVE/unacknowledged → ACTIVE/acknowledged → CLEARED。条件反复变化时,会重新激活同一告警,而不是产生重复告警。
告警标识触发它的设备。查询在租户范围执行,支持状态、严重程度、确认情况和来源设备筛选,而不是从父实体读取。
严重程度与升级
每个告警带有严重程度:CRITICAL、MAJOR、MINOR、WARNING 或 INDETERMINATE。同一个条件可以声明多个严重程度层级的规则,例如 temp > 80 → MAJOR、temp > 100 → CRITICAL。这些规则使用相同告警键触发时,引擎会将单个活跃告警原地升级到当前满足的最高层级,并随条件缓和降级,而不是每个层级创建独立告警。未指定告警键的触发告警动作,以规则自身为键(配置文件与规则令牌),因此使用默认值的不同规则会创建不同告警。
通知人员
告警可以通过通知系统通知人员。每租户策略按严重程度,将告警路由到电子邮件(SMTP)和 webhook 渠道:策略每条规则将一种严重程度或任意严重程度映射到渠道与收件人列表。
升级按策略设置,不按严重程度。 策略设置统一间隔和次数上限。持续未确认、未解除的告警,会按该计划通过相同渠道重复通知,直到上限。无论匹配多少策略,告警都只有一个升级时钟和层级,因此其中最短间隔控制所有策略节奏。不能为某严重程度单独设置频率。
策略也支持节流:同一告警通知之间的最小间隔,防止反复发出信号的告警淹没渠道。
两个策略路由到同一渠道且收件人列表完全相同时,重复投递合并,只发送一次。相同收件人但顺序或字母大小写不同,则视为不同,会发送两次。
渠道凭据(SMTP 密码、webhook bearer 令牌)保存在平台加密密钥存储中,静态时采用信封加密,通过 API 只写,绝不返回明文。
机器到人的通知路径,与将事件转发到其他系统的机器到机器**出站连接器**分开。
查看告警与规则健康状态
无需额外配置,告警会实时出现在两个位置:
- 控制台**告警(Alarms)**视图:实时租户范围列表,支持筛选和直接确认。
- 仪表板组件:实时告警表格和告警计数组件(参见仪表板),包括服务器根据运维人员自身权限授权的确认/解除动作。
两者都使用实时订阅,因此状态变化会即时显示。
配置文件编辑器还显示规则健康状态,包括各规则状态、上次触发时间和触发次数,以及检测发生时的实时记录。在真正产生告警之前,就能确认新发布规则是否按预期运行。
运行服务
评估规则的服务在内存中保存实时状态,由单个活跃实例检测;其他副本都是备用。因此,生产环境依赖它之前应了解几个运维特性:重启代价、静默规则多快能触发、告警为何可能不解除,以及如何找到评估失败的规则。参见**运行检测引擎**。