告警与记录规则
Grafana Loki 包含一个名为 ruler 的组件。ruler 负责持续评估一组可配置的查询,并根据结果执行操作。
此示例配置从本地磁盘获取规则。
Ruler 存储提供了更多详细信息。
ruler:
storage:
type: local
local:
directory: /tmp/rules
rule_path: /tmp/scratch
alertmanager_url: https://
ring:
kvstore:
store: inmemory
enable_api: true
告警规则
我们支持兼容 Prometheus 的告警规则。引自 Prometheus 文档:
告警规则允许您基于 Prometheus 表达式语言表达式定义告警条件,并将触发的告警通知发送给外部服务。
Loki 告警规则与此完全相同,只是表达式使用 LogQL。
示例
一个完整的规则文件示例
groups:
- name: should_fire
rules:
- alert: HighPercentageError
expr: |
sum(rate({app="foo", env="production"} |= "error" [5m])) by (job)
/
sum(rate({app="foo", env="production"}[5m])) by (job)
> 0.05
for: 10m
labels:
severity: page
annotations:
summary: High request latency
- name: credentials_leak
rules:
- alert: http-credentials-leaked
annotations:
message: "{{ $labels.job }} is leaking http basic auth credentials."
expr: 'sum by (cluster, job, pod) (count_over_time({namespace="prod"} |~ "http(s?)://(\\w+):(\\w+)@" [5m]) > 0)'
for: 10m
labels:
severity: critical
记录规则
我们支持兼容 Prometheus 的记录规则。引自 Prometheus 文档:
记录规则允许您预先计算常用或计算成本高的表达式,并将结果保存为一组新的时间序列。
查询预计算结果通常比每次需要时执行原始表达式要快得多。这对于仪表盘尤其有用,因为仪表盘每次刷新都需要重复查询相同的表达式。
Loki 允许您运行指标查询以处理您的日志,这意味着您可以从日志中得出数值聚合,例如从 NGINX 访问日志中计算随时间变化的请求数量。
示例
name: NginxRules
interval: 1m
rules:
- record: nginx:requests:rate1m
expr: |
sum(
rate({container="nginx"}[1m])
)
labels:
cluster: "us-central1"
这个查询(expr
)将每 1 分钟(interval
)执行一次,其结果将存储在我们定义的指标名称(record
)中。这个名为 nginx:requests:rate1m
的指标现在可以发送到 Prometheus,在那里它将像其他任何指标一样被存储。
限制告警和记录规则样本
类似于Prometheus,您可以为告警规则生成的告警和记录规则生成的样本配置一个限制。此限制可以按组配置。使用限制可以防止错误的规则生成大量告警或记录样本。当超出限制时,规则生成的所有记录样本将被丢弃,如果是告警规则,则该规则的所有告警(活动的、待处理的或非活动的)都将被清除。此事件将记录为评估错误,并且规则健康状态将被设置为 err
。限制的默认值为 0
,表示没有限制。
示例
这里是一个规则组及其配置的限制示例。
groups:
- name: production_rules
limit: 10
interval: 1m
rules:
- alert: HighPercentageError
expr: |
sum(rate({app="foo", env="production"} |= "error" [5m])) by (job)
/
sum(rate({app="foo", env="production"}[5m])) by (job)
> 0.05
for: 10m
labels:
severity: page
annotations:
summary: High request latency
- record: nginx:requests:rate1m
expr: |
sum(
rate({container="nginx"}[1m])
)
labels:
cluster: "us-central1"
远程写入
使用记录规则,您可以按一定间隔持续运行这些指标查询,并将结果指标写入兼容 Prometheus 的远程写入端点。它们从日志条目生成 Prometheus 指标。
在撰写本文时,支持此功能的兼容后端有:
- Prometheus (
>=v2.25.0
):Prometheus 通常是一个基于拉取的系统,但自v2.25.0
起也允许直接向其写入指标。 - Grafana Mimir
- Thanos (
Receiver
)
这里是一个将数据发送到本地 Prometheus 实例的远程写入配置示例。
ruler:
... other settings ...
remote_write:
enabled: true
client:
url: https://:9090/api/v1/write
更多配置选项请参见ruler。
操作
请参阅记录规则页面。
用例
Ruler 与 Prometheus 的兼容性进一步强调了指标和日志的结合。对于希望开始基于日志使用指标和告警,或想知道这为何有用的人来说,我们认为以下是一些非常合适的用例。
黑盒监控
我们并不总是控制运行应用程序的源代码。负载均衡器和许多其他组件,无论是开源的还是第三方的闭源组件,都支持我们的应用程序,但它们不暴露我们想要的指标。有些甚至完全不暴露任何指标。Loki 告警和记录规则可以从日志生成指标并对系统状态进行告警,从而利用日志将这些组件纳入我们的可观测性堆栈。这是一种非常强大的方法,可以将高级可观测性引入传统架构。
事件告警
有时您想知道是否发生了 任何 特定事件的实例。基于日志的告警是处理这种情况的好方法,例如查找泄露的身份验证凭据示例
- name: credentials_leak
rules:
- alert: http-credentials-leaked
annotations:
message: "{{ $labels.job }} is leaking http basic auth credentials."
expr: 'sum by (cluster, job, pod) (count_over_time({namespace="prod"} |~ "http(s?)://(\\w+):(\\w+)@" [5m]) > 0)'
for: 10m
labels:
severity: critical
高基数源告警
另一个很好的用例是对高基数源进行告警。这些是难以/昂贵地记录为指标的数据,因为潜在的标签集非常庞大。一个很好的例子是在像 Loki 这样的多租户系统中按租户进行告警。这通常是在希望获得按租户指标和随之而来的基数爆炸(将单个 tenant 标签添加到现有的 Prometheus 指标会使其基数增加租户数量)之间进行的权衡。
在 LogQL 中创建这些告警很吸引人,因为这些指标可以在 查询时 提取,这意味着我们不会在指标存储中遭受基数爆炸的影响。
注意
例如,我们可以使用 LogQL v2 来帮助 Loki 监控 自身,当特定租户的查询耗时超过 10 秒时向我们发出告警!为此,我们将使用以下查询:
sum by (org_id) (rate({job="loki-prod/query-frontend"} |= "metrics.go" | logfmt | duration > 10s [1m])
。
与 Ruler 交互
Lokitool
由于规则文件与 Prometheus 规则文件相同,我们可以通过 lokitool
与 Loki Ruler 交互。
注意
lokitool 旨在针对多租户 Loki 运行。命令需要设置
--id=
标志为 Loki 实例 ID,或设置环境变量LOKI_TENANT_ID
。如果 Loki 运行在单租户模式下,所需的 ID 为fake
。
下面包含一个示例工作流程
# lint the rules.yaml file ensuring it's valid and reformatting it if necessary
lokitool rules lint ./output/rules.yaml
# diff rules against the currently managed ruleset in Loki
lokitool rules diff --rule-dirs=./output
# ensure the remote ruleset matches your local ruleset, creating/updating/deleting remote rules which differ from your local specification.
lokitool rules sync --rule-dirs=./output
# print the remote ruleset
lokitool rules print
Terraform
通过用于 Loki 的 Terraform 提供者,您可以使用 Terraform HCL 格式管理告警和记录规则。
terraform {
required_providers {
loki = {
source = "fgouteroux/loki"
}
}
}
# Provider config
provider "loki" {
uri = "http://127.0.0.1:3100"
org_id = "mytenant"
}
# Create an alert rule
resource "loki_rule_group_alerting" "test" {
name = "test1"
namespace = "namespace1"
rule {
alert = "HighPercentageError"
expr = <<EOT
sum(rate({app="foo", env="production"} |= "error" [5m])) by (job)
/
sum(rate({app="foo", env="production"}[5m])) by (job)
> 0.05
EOT
for = "10m"
labels = {
severity = "warning"
}
annotations = {
summary = "High request latency"
}
}
}
# Create a recording rule
resource "loki_rule_group_recording" "test" {
name = "test1"
namespace = "namespace1"
rule {
expr = "sum by (job) (http_inprogress_requests)"
record = "job:http_inprogress_requests:sum"
}
}
Cortex rules action
这个Cortex rules action 将 Loki 作为后端引入,这对于在 CI/CD 流水线中管理规则非常方便。它可用于在本地目录和远程 Loki 实例之间对规则进行 linting、diff 和同步。
- name: Lint Loki rules
uses: grafana/cortex-rules-action@master
env:
ACTION: check
RULES_DIR: <source_dir_of_rules> # Example: logs/recording_rules/,logs/alerts/
BACKEND: loki
- name: Deploy rules to Loki staging
uses: grafana/cortex-rules-action@master
env:
CORTEX_ADDRESS: <loki_ingress_addr>
CORTEX_TENANT_ID: fake
ACTION: sync
RULES_DIR: <source_dir_of_rules> # Example: logs/recording_rules/,logs/alerts/
BACKEND: loki
调度和最佳实践
扩展 Ruler 的一种选择是横向扩展它。然而,在运行多个 Ruler 实例时,它们需要协调以确定哪个实例将评估哪个规则。类似于 ingesters,Rulers 建立一个哈希环来划分评估规则的职责。
所有可能的配置完整列在配置文档中,但为了在多个 Ruler 之间分片规则,必须通过标志 (-ruler.enable-api
) 或配置文件参数启用规则 API。其次,Ruler 需要配置自己的环。从那里开始,Rulers 将自动进行规则的分片和分配处理。与 ingesters 不同,Rulers 不会移交职责:每次将 Ruler 添加到或从环中移除时,所有规则都会随机重新分片。
一个完整的启用分片的 Ruler 示例是
ruler:
alertmanager_url: <alertmanager_endpoint>
enable_alertmanager_v2: true # true by default since Loki 3.2.0
enable_api: true
enable_sharding: true
ring:
kvstore:
consul:
host: consul.loki-dev.svc.cluster.local:8500
store: consul
rule_path: /tmp/rules
storage:
gcs:
bucket_name: <loki-rules-bucket>
Ruler 存储
Ruler 支持以下存储类型:azure
, gcs
, s3
, swift
, cos
和 local
。大多数类型的存储与分片 Ruler 配置以显而易见的方式协同工作,即配置所有 Ruler 使用相同的后端。
本地实现从本地文件系统读取规则文件。这是一个只读后端,不支持通过Ruler API进行规则的创建和删除。尽管它读取本地文件系统,但如果操作员注意将相同的规则加载到每个 Ruler 上,这种方法仍然可以用于分片 Ruler 配置。例如,这可以通过将一个Kubernetes ConfigMap挂载到每个 Ruler Pod 上来实现。
一个典型的本地配置可能看起来像这样
-ruler.storage.type=local
-ruler.storage.local.directory=/tmp/loki/rules
使用上述配置,Ruler 将期望以下布局
/tmp/loki/rules/<tenant id>/rules1.yaml
/rules2.yaml
Yaml 文件应兼容 Prometheus,但包含本文档开头指定的 LogQL 表达式。
远程规则评估
在较大的部署和复杂的规则下,在本地评估模式下运行 Ruler 会导致结果与您在 Grafana 中看到的结果不一致或不完整的问题。为了解决这个问题,请使用远程评估模式针对查询前端评估规则。更详细的解释可以在可伸缩性文档中找到。
未来改进
为了提高此服务的健壮性,将有几项改进。顺序不分先后:
- 后端指标存储适配器,用于生成的告警规则数据。
杂项详情:指标后端 vs 内存
目前,Loki Ruler 与后备的 Prometheus 存储是解耦的。通常,评估规则的结果以及告警状态的历史都存储为时间序列。Loki 无法存储/检索这些数据,因此它独立于 Prometheus 等运行。作为一种变通方法,Loki 在内存中保留了一个小型存储,其目的是在重新调度或重新分片 Ruler 时懒加载过去的评估结果。将来,Loki 将支持可选的指标后端,允许存储这些指标以用于审计和性能优化。