skywalking设置全局告警配置@IgnoredException

1 阅读10分钟

转载自博客:blog.csdn.net/zz184358426… 背景 skywalking 9.7.0,地址:Backend setup | Apache SkyWalking

helm:skywalking-helm:4.5.0,地址:skywalking-helm/chart/skywalking/values.yaml at v4.5.0

首先来说一下为什么使用skywalking告警?

在我们目前的架构体系中:

prometheus:通过node exporter监控硬件级的监控,通过grafana来做告警(注意:grafana仅部分图支持告警)

当然也可以监控业务级别的,但是这些指标需要业务人员提供,而业务人员又需要额外开发自定义指标,是一种双向配合的方式,比较麻烦

ELK:通过日志埋点,在grafana配置ES数据源,通过捕获关键字类型,从而到达一种监控告警,但是这种局限很明显,需要将业务数据采集到es里面,不够方便快捷

目前时间比较紧,开发人员较少,再加上我们已经使用上了skywalking,需要快速告警下面几个指标:

接口成功率; 接口响应时间; 响应时间百分比 等等一些指标,来保证我们系统的稳定性,

由于上述指标对于skywalking都是现成的,想快速实现我们的需求,所以打算先通过skywalking告警来实现我们的需求

但这对于专业的监控告警系统,这样做不太好,因为告警的应该统一收口,在一个地方来配置,比如grafana;

因为告警的本质是通过采集日志,然后通过这些日志来进行定制告警,后续可以进行优化,这些不是本文章的主题

实践 k8s部署skywalking看看这个:k8s部署skywalking(helm)

本地实践的话,需要去官方下载一个APM,地址:Downloads | Apache SkyWalking 9.7.0本地玩的话,默认配置是JDK17哈,各位校验一下自己的Java环境

注意,这里的告警是在skywalking-oap服务端的,不是客户端哈

告警配置属性 告警模块相关配置文件路径:

打开之后官方默认了一些规则,官方查看:Alerting | Apache SkyWalking

接下来来解释一些这些属性的含义

Rule name:规则名称。需要保证唯一,必须以 _rule 结尾

Expression:告警表达式。

Include names:告警规则生效包含的实体名列表。本质是一个array,可以配置多个,但需要注意的是,这个是全匹配

我们在集成 Agent 的时候,一般都会设置 Service group。举个栗子: SW_AGENT_NAMESPACE:"dev" SW_AGENT_NAME:"dev::example-name" 当我这样定义时,service name 应该写成 dev::example-name|dev|,参考:Table of Agent Configuration Properties | Apache SkyWalking

Exclude names:告警规则不生效包含的实体名列表,本质是一个array,可以配置多个,但需要注意的是,这个是全匹配

Include names regex:和 Include names 一样。只不过是正则表达式字符串

Exclude names regex:和 Exclude names 一样。只不过是正则表达式字符串

Tags:自定义的 k-v 对(这个目前感觉只是增加一个自定义的提示信息的)

Period:表达式计算结果的缓存时间,也可以理解为没隔多长时间采集一次数据;

Silence Period:静默时间。例如我有一个规则,1分钟会触发一次,当我把Silence Period配置为 3 时。那就是3分钟内,不会发送一次请求到 hook

Hooks:向外界发送通知的方式 ,本质上都是 WebHook。

告警表达式 以下列示例解释:

rules:

service_sla 代表的是服务响应成功率

service_sla_rule: # sum(service_sla < 8000) 该表达式表示的是 服务的响应成功率低于80%的次数 # >= 2 是关键,表达式每分钟算一次(这是我看了文档后猜的,应该没问题), 那这里就表示最近2分钟服务SLA都低于90% expression: sum(service_sla < 8000) >= 2 # 字符串匹配写法 include-names: - 'dev::example|dev|' # 正则写法:所有dev组的 include-names-regex: '^dev::.*' # 表达式计算结果缓存时长,表达式每一分钟计算一次,我表达式中设置了>=2 # 所以period 应该设置一个大于2的值,这样能避免重复计算 period: 10 # 静默时间,如果服务有10分钟SLA是低于90的,那么m2的时候会提醒。 # 下一次本来是m3提醒的,我设置了2,所以等到m5再次计算表达式的时候才会在提醒 silence-period: 3 # 自定义 tags,key-value形式 tags: level: ERROR # 告警文本,{name} 是内置变量,代表服务名称,本地实际测试还有一个id,用来表示告警id,用法{id} message: '服务{name}成功率小于100%' hooks: webhook: default: # 是否默认 is-default: true # 配置url urls: - http://127.0.0.1/notify/ - http://127.0.0.1/go-wechat/ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 实际例子 service维度 所有服务SLA在最近3分钟内小于100

service_success_rule: expression: sum((service_success / 100) < 100) >= 3 period: 5 silence-period: 5 message: '服务 SLA 低于 100%' 1 2 3 4 5 prod分组下,所有服务SLA在最近3分钟小于100

service_success_rule: expression: sum((service_success / 100) < 100) >= 3 include-names-regex: '^prod::.*' period: 5 silence-period: 5 message: '服务 SLA 低于 100%' 1 2 3 4 5 6 endpoint维度 endpoint跟service不同的是,它的规则为:

xxx接口 in group::服务 1 单接口SLA在最近3分钟内小于100

endpoint_sla_rule: expression: sum((endpoint_sla / 100) < 100) >= 3 include-names: - 'GET:/test/custom1 in dev::example|dev|' period: 5 message: '此接口 SLA 低于 100%' 1 2 3 4 5 6 prod分组下,所有接口(排除指定接口)SLA在最近3分钟内小于100

endpoint_sla_rule: expression: sum((endpoint_sla / 100) < 100) >= 3 exclude-names: - 'GET:/test/custom1 in dev::example|dev|' include-names-regex: '.* in prod::.*' period: 5 message: '此接口 SLA 低于 100%' 1 2 3 4 5 6 7 DB维度 所有DB SLA 最近1分钟内小于100

database_access_sla_rule: expression: sum((database_access_sla / 100) < 100) >= 1 period: 3 message: 'DB SLA 低于 100%' 1 2 3 4 配置webhook 飞书 hooks: feishu: default: is-default: true text-template: | { "msg_type":"text", "content": { "text": "Apache SkyWalking Alarm: \n %s." } } webhooks: - url: open.feishu.cn/open-apis/b… 1 2 3 4 5 6 7 8 9 10 11 12 13 skywalking默认提供的指标 目前skywalking定义的指标存在与下列目录下,以*.oal为结尾的文件

部分指标释义如下:

code 解释 备注 service维度 service_resp_time 服务的平均响应时间 service_sla 服务的成功率 service_cpm 服务每分钟调用次数 服务实例指标 service_instance_sla 服务实例的成功率 service_instance_resp_time 服务实例的平均响应时间 service_instance_cpm 服务实例每分钟调用次数 endpoint维度 endpoint_cpm 端点每分钟调用次数 endpoint_avg 端点平均响应时间 endpoint_sla 端点成功率 JVM 指标, JVM 相关的指标, 只有当 javaagent 启用时才有效 instance_jvm_cpu instance_jvm_memory_heap instance_jvm_memory_noheap instance_jvm_memory_heap_max instance_jvm_memory_noheap_max instance_jvm_young_gc_time instance_jvm_old_gc_time instance_jvm_young_gc_count instance_jvm_old_gc_count 服务关系指标, 代表服务之间调用的指标 指标的 ID 只能在拓扑图查询中获取 service_relation_client_cpm 在客户端每分钟检测到的调用次数 service_relation_server_cpm 在服务端每分钟检测到的调用次数 service_relation_client_call_sla 在客户端检测到的成功率 service_relation_server_call_sla 在服务端检测到的成功率 service_relation_client_resp_time 在客户端检测到的平均响应时间 service_relation_server_resp_time 在服务端检测到的平均响应时间 端点关系指标, 代表相互依赖的端点之间的指标. 只有在追踪代理启用时有效. 指标 ID 只能在拓扑查询中获得. endpoint_relation_cpm endpoint_relation_resp_time 拓展 skywalking什么类型的信息会触发报警 默认情况下,当你Http status为非200的时候,skywalking会识别到这是一个失败的请求;

在实际场景中,我们业务可能会遇到这种情况,就是响应码为200,但是项目中做了异常全局处理,这种情况应该告警的。针对这种情况,想要让skywalking不触发告警,需要使用ActiveSpan.error()

引入pom

org.apache.skywalking apm-toolkit-trace 9.2.0 1 2 3 4 5 示例代码:

import org.apache.skywalking.apm.toolkit.trace.ActiveSpan; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice public class GlobalExceptionHandler {

@ExceptionHandler({MyCustomException.class})
public ResponseEntity<String> handleMyCustomException(MyCustomException e) {
    // 使用ActiveSpan.error()标记异常
    ActiveSpan.error(e);

    // 返回正常的响应,但SkyWalking会记录异常
    return new ResponseEntity<>("Handled MyCustomException: " + e.getMessage(), HttpStatus.OK);
}

} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 这种情况状态码是200,但是skywalking也会告警的。

忽略指定异常告警 这种方式是基本skywalking客户端的方式进行修改!!!!!!!

场景:

在业务使用过程中,我们会添加全局异常处理,当程序错误的时候,统一返回处理。

但是我们也会有这种场景:我们可能会抛出一些自定义的异常,而这些异常,并不是程序错误或者未知的错误,而是非常明确的终态,用来告知调用方一些信息,这种的我们想让skywalking不要报警,该怎么做呢?

在下述示例中,SkyException为我们要忽略报警的异常,MyCustomException为全局处理异常

SkyException

@Slf4j public class SkyException extends RuntimeException{

public SkyException(String message) {
    super(message);
}

}

1 2 3 4 5 6 7 8 MycustomException

@Slf4j public class MycustomException extends RuntimeException{

public MycustomException(String message) {
    super(message);
}

}

1 2 3 4 5 6 7 8 接口:

@GetMapping("/test") public Integer pay(@RequestParam("id") Integer id) { throw new SkyException("skywalking忽略告警异常"); }

@GetMapping("/test2") public Integer pay(@RequestParam("id") Integer id) { return 1/0; }

1 2 3 4 5 6 7 8 9 10 全局异常处理

@RestControllerAdvice public class GlobalExceptionHandlers {

@ExceptionHandler(SkyException.class)
public Integer skyException(SixException e) {
    // 使用ActiveSpan.error()标记异常
    ActiveSpan.error(e);
    return 1;
}

@ExceptionHandler(MycustomException.class)
public Integer mycustomException(SevenException e) {
    // 使用ActiveSpan.error()标记异常
    ActiveSpan.error(e);
    return 1;
}

}

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 在上述情况下,访问/test1和/test2都会触发skywalking告警,如果我们想让SkyException不告警的话,有两种方式

skywalking默认的环境变量 引入jar包,采用注解方式 环境变量的方式 修改jvm启动参数,当需要忽略多个异常时,使用逗号“,”分隔。如下所示。

-javaagent:/opt/skywalking-agent-9.2.0/skywalking-agent.jar -Dskywalking.agent.service_name=sky-demo -Dskywalking.collector.backend_service=127.0.0.1:11800 -Dskywalking.statuscheck.ignored_exceptions=com.xx.xxx.SkyException

1 2 3 4 5 修改完成后重新启动服务即可

如果是k8s的方式,注入环境变量: SW_STATUSCHECK_IGNORED_EXCEPTIONS:com.xx.xxx.SkyException

注解方式 引入pom

org.apache.skywalking apm-toolkit-trace 8.9.0 1 2 3 4 5 在要忽略的异常上添加注解@IgnoredException,等同于添加配置statuscheck.ignored_exceptions。

@Slf4j @IgnoredException public class SkyException extends RuntimeException{

public SkyException(String message) {
    super(message);
}

} 1 2 3 4 5 6 7 8 忽略链路插件 在skywalking控制台显示页面上,我们想让一些调用不显示链路,比如健康心跳显示,机器人巡检等功能,这些对于我们业务使用来说,不怎么关注,而且他们的触发频率很高,会有大量的链路,有时候直接把我们真正关心的链路给耍没了,那么这种场景,该怎么处理呢?

比如我不想让Lettuce/INFO在skywalking链路中显示

这种方式需要一个插件,进入optional-plugins文件夹,将jar包apm-trace-ignore-plugin-8.16.0.jar复制到plugins文件夹中

配置

忽略调用链路的配置有两种:

系统变量; 配置文件。 系统变量优先级大于文件。

其配置的路径应匹配Ant Path规则,如/path/*、/path/**、/path/?。

系统变量

在系统变量中添加skywalking.trace.ignore_path来配置要忽略的接口,多个接口之间用逗号“,”分隔。

配置文件

在config文件夹中添加配置文件apm-trace-ignore-plugin.config,在该配置文件中添加以下配置

trace.ignore_path=/your/path/1/,/your/path/2/

我们要忽略掉eureka心跳检测的接口,则在配置文件中添加以下配置

trace.ignore_path=Lettuce/INFO

这样设置后,skywalking链路中不会在有该接口了

参考文献