写点什么

精准捕捉异常时刻——从写好事件标题与内容开始

作者:观测云
  • 2023-12-11
    上海
  • 本文字数:2490 字

    阅读完需:约 8 分钟

精准捕捉异常时刻——从写好事件标题与内容开始

写在前面

在讨论如何写好监控器配置时的事件通知内容之前,需要明确这样一个逻辑:


当监控器检测规则生效后,它会针对系统业务数据进行一系列聚合数据处理并以事件的形式留存。这些事件记录可以理解为当前监控器检测对象发出的异常信号的承载者,本文即将讨论的事件标题与内容就是这些事件记录的一部分。如果利益相关方认为当前异常是紧急处理事项,并且需要预估风险、及时响应,就可以以告警的形式向外发送这些事件记录。


在这个传送过程中,告警配置中的不聚合、规则聚合和智能聚合这三种方式会对事件标题与内容进行对应的处理,最终成为利益相关方接收到的异常告警通知。(如下图所示)





再回到最初的问题,当我们借用监控器来对各类数据进行检测,十分期望在产生异常事件时,被通知对象能第一时间获取异常时刻下详细的上下文信息。这就要求创建者在配置监控器时,重视并了解如何定义、编辑需要通知的事件标题及内容。



模版变量

模版变量是编辑标题与内容的核心要素之一。以下是观测云支持的模板变量,帮助渲染动态文案。

事件标题

事件标题讲究不拖沓,即一句话就能阐明要点。这样当接收到事件通知时,在第一眼看到标题的情况下,就能大致了解事件内容。如:

  • Consul 集群里成员的状态存在异常

除了上述这样纯文本的标题,我们还可以在标题内插入模版变量。如:

  • 主机 {{ host }} 可用内存小于 10%

  • {{ service }} 服务的链路 Trace 错误率过高,错误率为 {{ ReConsult | to_fixed(2) }}%

事件内容

在指定事件内容时,我们可以借助模板语法来实现。接下来,我们会以几种常见的场景,展示事件内容通知的实际编辑效果。

场景一:模版变量

假设监控器 by 配置了 region 和 host,基于上表中的模板变量,我们可以编辑一份最基础的事件内容:

  • 事件标题:

监控器 {{ df_monitor_checker_name }} 发现 {{ df_dimension_tags }} 存在故障
复制代码
  • 事件内容:

地区:{{ region }}主机:{{ host }}主机:{{ host }}级别:{{ df_status }}检测值:{{ Result }}监控器:{{ df_monitor_checker_name }}(告警策略:{{ df_monitor_name }})
复制代码

那么,产生 error 事件后,经过渲染的事件输出如下:

  • 输出事件标题:

监控器 监控器001 发现 {"region":"hangzhou","host":"web-001"} 存在故障
复制代码
  • 输出事件内容:

地区:hangzhou主机:web-001主机:web-001级别:error检测值:90.12345监控器:监控器001(告警策略:团队001)
复制代码

场景二:模版变量+模版函数

除了如场景一这样直接展示事件中的字段值外,我们还可以使用模板函数对字段值进行进一步处理。采用模版函数能优化事件的通知内容输出,整合必要信息。

其组合用法形式为: {{ <模板变量> | <模板函数> }}

在观测云,我们可用的模板函数列表如下:

还是参考场景一中的示例,此时在使用模版函数的情况下(即 {{ df_dimension_tags | to_pretty_tags }}),事件标题与内容的写法分别为:

  • 事件标题:

监控器 {{ df_monitor_checker_name }} 发现 {{ df_dimension_tags | to_pretty_tags }} 存在故障
复制代码
  • 事件内容:

对象:{{ df_dimension_tags | to_pretty_tags }}时间:{{ date | to_datetime }}级别:{{ df_status | to_status_human }}检测值:{{ (Result * 100) | to_round(2) }}
复制代码

那么,产生 error 事件后,经过渲染的事件输出如下:

  • 输出事件标题:

监控器 我的监控器 发现 region:hangzhou, host:web-001 存在故障
复制代码
  • 输出事件内容:

检测对象:region:hangzhou, host:web-001检测时间:2022-01-01 01:23:45故障级别:重要检测值:9012.35
复制代码

场景三:模板分支

基于观测云现有的配置页面,假设我们期望在同一个事件内容框中描述不同等级下产生的异常,我们可以采用模版分支语法(if else)来实现。

语法大致写法如下:

{% if df_status == 'critical' %}紧急问题,请立即处理!{% elif df_status == 'error' %}重要问题,请处理{% elif df_status == 'warning' %}可能有问题,有空处理{% elif df_status == 'nodata' %}数据中断,请立即处理!
{% else %}没问题!
{% endif %}
复制代码

示例效果如下:

{% if  df_status != 'ok' %}等级:{{ df_status }}主机:{{ host }}内容:Elasticsearch JVM 堆内存的使用量为 {{ Result }}%建议:当前 JVM 垃圾的收集已经跟不上 JVM 垃圾的产生请及时查看业务情况
{% else %}等级:{{df_status}}主机:{{host}}内容:Elasticsearch JVM 堆内存告警已恢复
{% endif %}
复制代码

场景四:内嵌 DQL 查询函数

还有这样一种情况:即事件关注者除了希望看到监控器下产生的事件相关的内容,还想实现额外的数据查询,无论该类数据与当前监控器配置规则有关与否。此时,仅使用模板变量无法满足渲染需求。我们可以采用内嵌 DQL 查询函数来实现。

该函数支持在本工作空间下本次检测时间范围内(即 check_start_time 和 end_time 的范围)执行任意 DQL 语句,通常情况下,查询所得的第一条数据可在模板中作为模板变量使用,使用方式如下:

{% set dql_data = DQL("需要执行的 DQL 语句") %}某字段:{{ dql_data.some_field }}
复制代码

假设,我们需要查询 host 字段为 "my_server" 的数据,并将第一条数据赋值给 dql_data 变量:

编辑效果为:

{% set dql_data = DQL("O::HOST:(host, host_ip, os, datakit_ver) { host = 'my_server' }") %}
主机 OS:{{ dql_data.os }}
复制代码

此后的模板中即可使用 {{ dql_data.os }} 输出查询结果中的具体字段。

有时,所需执行的 DQL 语句需要传递参数。

假设监控器 by 条件中配置了 region 和 host,且事件内容的写法如下:

{% set dql_data = DQL("O::HOST:(host_ip, os) { region = ?, host = ? }", region, host) %}主机信息:IP:{{ dql_data.host_ip }}OS: {{ dql_data.os }}
复制代码

由于事件仅包含 region 和 host 模板变量用于标记不同的数据,不包含 IP 地址、操作系统等更多信息。那么,使用内嵌 DQL 可以通过 region 和 host 作为 DQL 查询参数获取对应数据,并使用 {{ dql_data.host_ip }} 等输出关联信息。

结论

无论处于上述哪种场景,我们的最终输出目标都是:利用观测云提供的模板变量,来自定义并精准捕获异常时刻下的上下文事件信息,以便相关关注者能够及时做出反应。

用户头像

观测云

关注

还未添加个人签名 2021-02-08 加入

云时代的系统可观测平台

评论

发布
暂无评论
精准捕捉异常时刻——从写好事件标题与内容开始_运维_观测云_InfoQ写作社区