Zabbix 基于 Statsd 实现对 Kong APIGateway 的监控

最近有个 Zabbix 监控 Kong 的需求,查了一下网上并没有很多资料,遂研究官方文档,发现 Kong 支持把监控数据传到 Statsd 中,而 Statsd 可以将 Zabbix 作为 backend,所以大体的架构如下

Kong ---> Statsd ---> Zabbix

配置过于简单,这里就不写了

问题排查

但是当笔者将 Statsd 和 statsd-zabbix 插件部署好之后发现一些问题

这是 zabbix-sender 报的错误,服务端并没有接收我们的监控指标,原因是在 Zabbix 中的 Host 并没有对应的 item key

26 Nov 01:02:49 - INFO: statsd-zabbix-backend: processed: 0; failed: 41; total: 41; seconds spent: 0.000768

监控指标都是是基于 Kong 中不同的 Service/Consumer,由于 Service 是动态的,没有办法写死 item key,只能定义好 Low-Level-Discovery 并结合 Item prototypes 自动生成对应的 item key

那么先需要在 zabbix 中定义 Low-Level-Discovery 规则来自动发现 Kong 的 Service,这里笔者通过 Kong Admin API 实现

# /etc/zabbix/zabbix_agentd.d/kong_service_discovery.conf
UserParameter=kong.service.discovery,curl localhost:8001/services 2> /dev/null| jq '[.data[] | {"{#SERVICENAME}": .name}]'

这就算是实现了 Service 的发现,通过 zabbix_get 可以动态拿到当前所有的 Service

# zabbix_get -s 127.0.0.1 -p 10050 -k kong.service.discovery
[
{
"{#SERVICENAME}": "example-service"
},
{
"{#SERVICENAME}": "example2-service"
}
]

然后笔者发现新的问题,就是 Zabbix 的 item key 的宏只能定义在 参数/[] 中,无法定义在 item.key 本身

# 笔者想基于 zabbix 的宏定义这样的 item key
kong.{#SERVICENAME}.request.count[total]

# 但事实上,zabbix 只支持以下格式的定义
kong.request.count[{#SERVICENAME},total]

Kong 传输给 Statsd 的数据格式为

kong.<service_name>.request.count

而笔者期望得到的数据格式为

kong.request.count[service_name]

所以我们还要对传输的数据进行转换,这里笔者经过调研决定单独修改 statsd-zabbix-backend 的代码,修改过的代码

最后 Statsd 传输给 Zabbix 的数据格式如下

26 Nov 01:14:09 - DEBUG: statsd-zabbix-backend: Zabbix server -> kong.request.count[example-service,total] -> 0
26 Nov 01:14:09 - DEBUG: statsd-zabbix-backend: Zabbix server -> kong.request.count[example-service,avg] -> 0
26 Nov 01:14:09 - DEBUG: statsd-zabbix-backend: Zabbix server -> kong.request.status.500[example-service,total] -> 0
26 Nov 01:14:09 - DEBUG: statsd-zabbix-backend: Zabbix server -> kong.request.status.500[example-service,avg] -> 0
26 Nov 01:14:09 - DEBUG: statsd-zabbix-backend: Zabbix server -> kong.request.status.total[example-service,total] -> 0
26 Nov 01:14:09 - DEBUG: statsd-zabbix-backend: Zabbix server -> kong.request.status.total[example-service,avg] -> 0
26 Nov 01:14:09 - DEBUG: statsd-zabbix-backend: Zabbix server -> kong.latency[example-service,lower] -> 0
26 Nov 01:14:09 - DEBUG: statsd-zabbix-backend: Zabbix server -> kong.latency[example-service,upper] -> 0

最后我们只需要在 Zabbix Web 页面创建对应的规则即可,效果如下

image-20191126011530471

image-20191126011545851

image-20191126012047758

后续继续定义 Trigger prototypes 就可以作为基础模板正常使用了

总结

当然还有一些问题的,比如 status_count_per_user 这个指标是同时包含 Service 和 Consumer 的,笔者暂时还没有对所有 Consumer 进行 Low-Level Discovery,所以还没有支持。

upstream_latency 这个指标从 Kong 发到 Statsd 就是有问题的。

经过测试过后非常不建议使用 Zabbix 来监控 Kong,原因如下

  1. 没有官方的支持
  2. 引入 Statsd 会增加监控架构的复杂性
  3. statsd-zabbix 插件已经两年没更新了

最后如果真的有 Zabbix 监控 Kong 的需求,建议还是单独开发插件,而不是使用本文的方案。