dream-mo / prom-elastic-alert

Prometheus & Alerting With ElasticSearch
Apache License 2.0
118 stars 11 forks source link

【问题】关于使用的疑惑 #9

Open Zhang21 opened 1 month ago

Zhang21 commented 1 month ago

你好。我看了使用文档,是直接把日志告警发送到 prometheusalert。我想请问这些日志告警的信息也存在与 metrics 里吗?我想通过 promtheus 和 alertmanager 配置和静默告警,然后再通过 prometheusalert 来发送告警信息。这是是可以的吗?

# 目前项目是这样
es -> prom-elastic-alert -> redis -> alertmanager -> prometheusalert

# 我希望统一接入 prom,便于管理
es -> prom-elastic-alert -metrics> prometheus -promql> alertmanager -> prometheusalert
Zhang21 commented 1 month ago

统一使用 prom 来配置和发送告警,不需要软件内置的发送告警。

image

Zhang21 commented 1 month ago

如果我不需要软件内置的告警,那么也必须要强依赖与 redis 和 alertmanager 么?这个可以解耦吗?

Zhang21 commented 1 month ago

日志告警的信息能存到 metrics 里,通过 prom 来获取吗?

目前的 metrics:

prom_elastic_alert_info
prom_elastic_alert_link_redis
prom_elastic_alert_query
prom_elastic_alert_rule

这几个指标没啥用啊,说明不了我的规则是否触发。如果加一个告警规则是否触发的指标。

# 能把 hit 是的日志内容 message 拿到,然后填充到 label message 中么?
# 0 规则没有触发,1 规则触发。
prom_elastic_alert_rule_hit{index="index-01", unique_id="测试告警03", message="logs key words"} 1

# promql
prom_elastic_alert_rule_hit > 0

就可以通过 prometheus 对这个 metrics 写 promql 来配置告警规则,好管理一些。

最简单的是不获取 message 字段,直接复用 rule 指标的 label,只告诉是否触发了告警,具体内容直接去日志中心找。

Zhang21 commented 1 month ago

问题:关于时间戳

prom-elastic-alert 里面的查询时间,是 utc 还是 cst ?ES 里面时区是 utc 的。我向 ES 中构造的数据两个时间都用了,但 query 都没有命中。elastialert 我记得是 utc 时间,但它能命中。指定了参数 --zone=UTC 还是无法命中。

es dsl query: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax

{"@timestamp": "2024-09-13T08:25:59.050", "message": "test"}
{"@timestamp": "2024-09-13T16:25:59.050", "message": "test"}

DEBU[2024-09-13 16:27:30] rules: rules/demo.rule.yaml index: test-* dsl: {"query":{"bool":{"must":[{"query_string":{"query":"message:test"}},{"range":{"@timestamp":{"format":"strict_date_optional_time","gte":"2024-09-13T16:17:29.512+08:00","lte":"2024-09-13T16:27:29.512+08:00"}}}]}}} hits_num: 0
Zhang21 commented 1 month ago

/alert/message?key=xxx 从 redis 里获取的告警信息,然后渲染了告警信息展示页面。

是不是可以通过这个,把告警信息生成为 metrics 便于 prom 抓取。

但是我目前无法命中告警规则,暂时无法预览这个告警页面效果,后面看看为什么无法触发告警。

redis key 里存放了 es 信息和触发告警的文档的 ids: [id1, id2...] 列表,然后遍历这个列表展示在页面上。key 默认 1d 的过期时间。

通过 id 从 es 中查出来的是所有字段,但如果接入 prom,其实就只需要一个 id 中的 message 日志字段即可。

如何拿到 redis 的 key 的名称?生成的 redis key 是不是应该加一个 debug 日志?

加个 debug 输出 Match.ids 和 key 的内容。 md5(ids) - key

Zhang21 commented 1 month ago

我在 kibana 界面通过 dsl 可以查询到数据,但程序无法命中。

image

Zhang21 commented 1 month ago

使用 es v7 能正常触发,es v8 有问题。但官方文档这个 ealsticsearch v7 是兼容 v8 的。

// 在 Elasticsearch 7.x 及更高版本(包括 8.x)中,DocumentType(即文档类型)已经逐步被弃用
// DocumentType: []string{"_doc"},

注释这个查询条件,重新编译代码后,es v7 和 es v8 都可以通用 go elasitcsearch v7 库。

https://github.com/dream-mo/prom-elastic-alert/blob/13b191f20f460feb300d325f4c16cf3c09c5a1a4/utils/xelastic/elastic_client_v7.go#L56

Zhang21 commented 1 month ago

现在需要在触发告警的时候,把这个告警指标推送给 metrics。

应该是加入到 run.go,如何从 ES 中获取 message 并将这个 label 写入 metrics?

最简单的是不获取 message 字段,直接复用 rule 指标的 label,只告诉是否触发了告警,具体内容直接去日志中心找。

逻辑:

1,获取 redis key,是否可以直接在 pushAlert() 中,通过 key 到 id 到 es 到 metrics? 1,从 redis 获取 key ids[0],有可能多个 key 里的规则是同一条,因此需要对内容去重,只获取同一个规则的一个 id 即可。 1.1,没有去重应该问题也不大,不过是多了几个 metric 和 label,但告警去重其实 alertmanager 是支持的,因此不用担心一下发送很多条。 1.2,还可以将 key 的过期时间设置足够小(比如 mins: 10),这样也不用担心一直发送告警。 2,使用 id 从 es 获取内容,提取 message 字段 3,将 message 字段作为 label 写入 metric

Zhang21 commented 1 month ago

run.gorunRuleQuery 里获取到了 hits_num,看下怎么把这个值传递给 metrics rule_hit

# 新指标
prom_elastic_alert_rule_hit

# 指标怎么传递的
addQueryMetrics(run.go runRuleQuery) -> collectQueryMetrics(prometheus.go)
Zhang21 commented 1 month ago

done!

Zhang21 commented 1 month ago

是否需要把告警命中的 message 字段的内容,作为 rule_hit 指标的 label 传入,这样告警通知里就能拿到日志内容,而不必再去 kibana 或 prom-elastic-alert 里查看告警日志内容。

获取规则命中列表的第一个 内容(hits[0].message)就可以了,其他内容都是重复的,没必要。

但是规则里的 dsl query 查询内容,不一定就是 message 字段。

# 目前
prom_elastic_alert_rule_hit{uniqeid="xxx", path="xxx", es_address="xxx", index="xxx"} value

# 计划
prom_elastic_alert_rule_hit{uniqeid="xxx", path="xxx", es_address="xxx", index="xxx", message="命中的日志内容"} value


告警通知内容示例:

description: "日志告警名称 {{ $labels.uniqueid }} 日志内容: {{ $labels.message }}"