☰
使用 Loki Canary 审计 Loki 集群的日志采集延迟与正确性
2026/10/9 22:59:02 网站建设 项目流程

使用 Loki Canary 审计 Loki 集群的日志采集延迟与正确性

【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki

Loki Canary 是 Loki 项目自带的一个独立守护程序,专门用于审计 Grafana Loki 集群的日志捕获性能:它持续生成人工日志、推送到 Loki,再通过 WebSocket 尾随(tail)与直接查询的方式回读这些日志,从而验证 Loki 是否存在丢日志、乱序、重复或高延迟问题。读完本文,你将掌握 Loki Canary 的工作原理、四类自检能力(Spot Check / Metric Test / Cache Test / 控制端点)、全部命令行参数、Binary / Docker / Kubernetes / 源码四种安装方式,以及基于 Systemd + Alloy + Prometheus 的完整监控部署方案与常见故障排查方法。

什么是 Loki Canary

Loki Canary 是一个独立于 Loki 主进程之外运行的应用程序,其定位是审计日志捕获性能的"金丝雀":当 Loki 集群出现问题时,它往往是最先发出信号的组件。它生成人工日志行(artificial log lines)并发送给 Loki 集群,同时与 Loki 通信捕获关于这些人工日志行的指标,最终以 Prometheus 时间序列指标的形式暴露出来,供 Prometheus / Alloy 抓取与告警。

其整体工作流如下(对应文档中的 mermaid 图):

loki-canary --> log file --> agent(Alloy / promtail) --> push --> Loki loki-canary ----------------------------------------------------------> Loki (WebSocket tail)

Loki Canary 每次向标准输出写入一条日志,并把对应时间戳保存在内部数组中。日志内容形如:

1557935669096040040 ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp

其中时间戳(纳秒)才是关键信息,p字符只是填充字节,用于把每条日志的大小调整到-size指定的字节数。从源码看,这一格式由 writer.go 中的LogEntry = "%s %s\n"定义,写入循环 writer.go 会按-interval周期生成time.Now()的纳秒时间戳,并动态计算填充长度,使整行长度精确匹配-size。

Loki Canary 的标准输出应被重定向/采集到文件中,再由采集 Agent(如 Grafana Alloy、promtail)读取该文件并推送至 Loki。与此同时,Loki Canary 会通过 WebSocket 连接 Loki 并 tail 自己创建的日志流;每当 WebSocket 收到一条日志,就把日志消息中的时间戳与内部数组比对。

收到日志时的三种判定

比对逻辑实现在 comparator.go 的entryReceived方法中,按以下三种情况处理:

  • 恰好是数组中的下一条待接收日志:将其从数组移除,并把(当前时间 - 日志时间戳)记录到response_latency直方图。这是正常行为。
  • 不是数组中的下一条:同样将其从数组移除并记录响应时间到response_latency直方图,同时递增out_of_order_entries计数器(源码中out_of_order_entries_total)。
  • 根本不在数组中:会与一份"已确认接收列表"(acknowledged entries)比对,以递增duplicate_entries计数器(重复接收)或unexpected_entries计数器(意外接收,例如此前已被判定为丢失)。

后台清理与"真丢失"确认

在后台,Loki Canary 还运行一个定时器遍历内部数组(对应pruneEntries,见 comparator.go):

  1. 任何超过-wait时长(默认 60s)仍未收到的条目,会从数组中移除,并递增websocket_missing_entries计数器;
  2. 随后立即直接查询 Loki,判断这些条目是真的丢失,还是仅 WebSocket 没收到;
  3. 该直接查询会按-pruneinterval(默认 60s)重复执行,只要条目仍处于缺失状态;confirmMissing实现见 comparator.go,查询时会额外把时间范围前后各放宽 10 秒以容忍时钟误差;
  4. 一旦某条目缺失时长超过-max-wait(默认 5m),Loki Canary 放弃它,将其移出列表并递增missing_entries计数器。

附加查询能力

Spot Check(抽查)

从 1.6.0 版本起,Canary 会持续对部分结果做抽查,确认它们确实存在于 Loki 中。这对于验证日志从 ingester 内存到存储(store)的落盘转换过程是否丢数据非常有帮助,因为 WebSocket tail 无法覆盖这一环节。

  • -spot-check-interval:以该间隔从日志流中抽取一条日志,存入单独的抽查列表;
  • -spot-check-max:抽查列表最多回溯多远(超过即丢弃);
  • -spot-check-query-rate:每隔该间隔,对列表中的每个条目查询一次 Loki,命中则递增loki_canary_spot_check_entries_total,缺失则递增loki_canary_spot_check_missing_entries_total。

默认-spot-check-interval=15m、-spot-check-max=4h,意味着运行 4 小时后 Canary 将维护一个约 16 条记录的抽查列表,并每分钟(默认-spot-check-query-rate=1m)查询一次。如果你的 Canary 实例很多,请务必注意这会带来可观的查询负载。源码中spotCheckEntries的实现位于 comparator.go,对每条抽查记录会查询 ±10 秒窗口并与回读时间戳精确比对。

注意:如果使用-out-of-order-percentage测试乱序日志摄入,不要把两个乱序时间范围参数(-out-of-order-min/-out-of-order-max)设到太久远的过去。默认值已足以正确测试该功能,设太远会与 Spot Check 测试产生冲突。使用-out-of-order-percentage时,还需要在 Alloy 配置中通过 pipeline stages(例如loki.process组件)在日志推送到 Loki 前把时间戳正确设置为日志自带的时间戳。

Metric Test(指标测试)

Loki Canary 会运行count_over_time指标查询,验证 Loki 中存储的日志速率与 Canary 实际产生日志的速率一致:

  • -metric-test-interval(默认 1h):运行指标测试的周期;
  • -metric-test-range(默认 24h):count_over_time查询的时间范围。

默认情况下每 1 小时执行一次 24h 范围的 instant-query。首次指标测试会在启动后的-metric-test-interval内的随机时刻运行(源码见 comparator.go,首次 tick 使用随机时长、之后mt.Reset恢复固定周期),这样同时启动的大量 Canary 不会在同一时刻轰击 Loki。

如果 Canary 运行时长不足-metric-test-range(如只运行 10 分钟),查询范围会被截断为 Canary 的实际运行时长,从而可以计算自启动以来的速率(见 comparator.go 中的adjustedRange逻辑)。Canary 会计算范围内期望的日志条数,与 Loki 返回的实际条数比对:期望值写入loki_canary_metric_test_expected指标,实际值写入loki_canary_metric_test_actual指标。要看差值,用前者减去后者即可——这正是 Loki mixin 中 Loki Canary 仪表盘的做法(相关仪表盘声明见 dashboards.libsonnet 中对loki-canary-dashboard的导入)。

需要说明的是:基于查询速率推算期望值的计算方法并不完美,偏差几个日志条目是正常的;超过 3~4 条的偏差则属于异常,应引起关注。

Cache Test(缓存一致性测试)

Loki Canary 还可以校验 Loki 的查询结果缓存是否与未缓存查询返回一致的结果,用于捕捉缓存失效类 Bug(缓存的响应与重新执行查询的结果不再匹配)。

  • -cache-test-interval(默认 15m):运行周期;
  • -cache-test-range(默认 24h):查询范围;
  • -cache-test-now(默认 1h):查询执行时间点(--now)回拨多久,使测试指向一个稳定的历史窗口而不是持续移动的"最新数据",保证两次查询针对同一份数据。

每次测试会执行两次相同的count_over_timeinstant-query:一次正常执行(走缓存),一次携带Cache-Control: no-cache请求头绕过缓存(源码见 reader.go 与 comparator.go)。每次尝试递增loki_canary_cache_test_query_results_total(带status="success"或status="failure"标签);若两次结果不同,则递增loki_canary_cache_test_query_results_diff_total。

由于查询窗口不能早于 Canary 进程自身的启动时间,在-cache-test-now尚未经过(即进程启动不足该时长)之前,Cache Test 会被跳过并输出一条日志到标准错误。

Control(动态暂停/恢复)

Loki Canary 暴露两个 HTTP 端点用于动态挂起/恢复进程,方便快速禁用或重新启用金丝雀:向/suspend或/resume发送 HTTP GET 请求即可。在源码 main.go 中,/suspend调用c.stop(),/resume调用startCanary()(内部先stop()再重建 writer/reader/comparator 三件套),实现安全重启。

暴露的指标

Loki Canary 在-port指定的端口(默认3500)上以 Prometheus 格式暴露所有指标,路径为/metrics。除了前文提到的计数器外,还包含(指标定义集中位于 comparator.go 与 reader.go):

  • loki_canary_entries_total:Canary 写入的日志条目总数;
  • loki_canary_duplicate_entries_total:通过 WebSocket 收到不止一次的日志条数;
  • loki_canary_unexpected_entries_total:收到的意外日志条数(例如此前已被报告为缺失);
  • loki_canary_ws_reconnects_total:WebSocket 重连次数(仅统计"失败后成功重连",见 reader.go);
  • loki_canary_ws_pings_total:WebSocket 连接收到的 ping 消息次数(通过自定义 ping handler 计数,见 reader.go);
  • loki_canary_metric_test_request_duration_seconds:指标测试查询耗时的直方图;
  • loki_canary_spot_check_request_duration_seconds:抽查查询耗时的直方图。

此外,response_latency_seconds直方图记录日志从写入到回读的端到端延迟,桶数量由-buckets(默认 10)控制,采用指数桶(从 0.5s 起倍增,见 comparator.go)。

安装

二进制安装

Loki 的每次 Release 都会为常见平台发布loki-canary压缩包:

  1. 从 Loki Releases 页面下载并解压与你平台匹配的压缩包;

  2. 赋予可执行权限并移动到 PATH:

    chmod +x loki-canary sudo mv loki-canary /usr/local/bin/loki-canary

必须指定 Loki 地址:通过-addr参数或设置环境变量LOKI_ADDRESS,二选一。若两者都未设置,Loki Canary 会打印Must specify a Loki address with -addr or set the environment variable LOKI_ADDRESS并退出(校验逻辑见 main.go)。

Docker 安装

Loki Canary 也以 Docker 容器镜像形式发布到 Docker Hub(grafana/loki-canary)。镜像 tag 跟随 Loki 版本,请使用与你运行的 Loki 版本一致的 tag:

# 将 tag 改为最近的 release 版本 docker pull grafana/loki-canary:3.7.3

镜像入口点就是loki-canary二进制本身,因此镜像名之后的所有参数都会直接透传给 canary:

docker run --rm \ -p 3500:3500 \ grafana/loki-canary:3.7.3 \ -addr=loki:3100 \ -labelname=instance \ -labelvalue=loki-canary-1

指标端口(默认3500)必须发布出来,Prometheus 或 Alloy 才能抓取。

Kubernetes 安装

最简单的运行方式:

kubectl run loki-canary --image=grafana/loki-canary:latest --restart=Never \ --image-pull-policy=IfNotPresent --labels=name=loki-canary -- -addr=loki:3100

更复杂的做法是部署为 DaemonSet。仓库的production目录下提供了 Tanka 配置,位于 production/ksonnet/loki-canary(含loki-canary.libsonnet与config.libsonnet),可通过jsonnet-bundler导入:

jb install github.com/grafana/loki/production/ksonnet/loki-canary

然后在 Tanka 环境的main.jsonnet中类似这样使用:

local loki_canary = import 'loki-canary/loki-canary.libsonnet'; loki_canary { loki_canary_args+:: { addr: "loki:3100", port: 80, labelname: "instance", interval: "100ms", size: 1024, wait: "3m", }, _config+:: { namespace: "default", } }
示例:独立 Pod
--- apiVersion: v1 kind: Pod metadata: labels: app: loki-canary name: loki-canary name: loki-canary spec: containers: - args: - -addr=loki:3100 image: grafana/loki-canary:latest imagePullPolicy: IfNotPresent name: loki-canary resources: {} --- apiVersion: v1 kind: Service metadata: name: loki-canary labels: app: loki-canary spec: type: ClusterIP selector: app: loki-canary ports: - name: metrics protocol: TCP port: 3500 targetPort: 3500
示例:DaemonSet
--- kind: DaemonSet apiVersion: apps/v1 metadata: labels: app: loki-canary name: loki-canary name: loki-canary spec: selector: matchLabels: app: loki-canary template: metadata: name: loki-canary labels: app: loki-canary spec: containers: - args: - -addr=loki:3100 image: grafana/loki-canary:latest imagePullPolicy: IfNotPresent name: loki-canary resources: {} --- apiVersion: v1 kind: Service metadata: name: loki-canary labels: app: loki-canary spec: type: ClusterIP selector: app: loki-canary ports: - name: metrics protocol: TCP port: 3500 targetPort: 3500

从源码编译

如果以上方式都不满足需求,可以自行编译:

  1. 克隆源码树:

    git clone https://gitcode.com/GitHub_Trending/lok/loki
  2. 编译二进制:

    make loki-canary
  3. 可选:构建容器镜像:

    make loki-canary-image

(对应 Makefile 目标与cmd/loki-canary下的Dockerfile/Dockerfile.cross保持一致。)

典型调用示例

以下示例只使用二进制支持的参数;完整参数清单见下文"配置"一节。

最小本地运行(无认证、无 TLS)

向标准输出写入人工日志,通过 WebSocket 回读,并在默认端口3500暴露指标:

loki-canary \ -addr=localhost:3100 \ -labelname=instance \ -labelvalue=loki-canary-1

默认情况下 canary 只通过 WebSocket 读取日志,推送日志仍需要 Agent(如 Grafana Alloy)将它的标准输出送进 Loki。完整的 Systemd + Alloy 示例见下文"Monolithic 模式部署"。

Push 模式对接认证的多租户 Loki

让 canary 直接把日志推送到 Loki(不再依赖独立 Agent),使用 Basic 认证与X-Scope-OrgID租户头:

loki-canary \ -addr=loki.example.com:3100 \ -push=true \ -user=canary \ -pass="$LOKI_PASSWORD" \ -tenant-id=team-a \ -labelname=instance \ -labelvalue=loki-canary-team-a \ -interval=500ms \ -size=512

关于-streamvalue的默认值:官方文档早期描述为"即使-push=true也始终默认stdout",但从当前仓库源码 main.go 看,实际行为是:未显式设置时,非 push 模式默认stdout,push 模式默认push。无论哪种情况,如果依赖 stream 标签来区分 push 模式与 stdout 模式的 canary,都建议显式设置-streamvalue,以免与预期不符。

使用自定义客户端证书通过 TLS 连接

连接启用 TLS 的 Loki 端点。启用-tls后 WebSocket 连接会从ws://切换为wss://:

loki-canary \ -addr=loki.example.com:443 \ -tls=true \ -cert-file=/etc/loki-canary/client.crt \ -key-file=/etc/loki-canary/client.key \ -ca-file=/etc/loki-canary/ca.crt \ -labelname=instance \ -labelvalue=loki-canary-tls

如果提供了-cert-file、-key-file、-ca-file中的任意一个却没有同时设置-tls=true,canary 会以Must set --tls when specifying client certs退出(校验逻辑见 main.go)。

配置

Loki 地址必须通过-addr参数或LOKI_ADDRESS环境变量传入;如果 Loki 启用了 TLS,还必须提供-tls=true,此时 WebSocket 连接将使用wss://而非ws://。

-labelname与-labelvalue也应始终提供:它们用于让 Loki Canary 过滤日志流,只处理当前实例的日志。务必保证每个 Canary 实例的这两个值全局唯一——Grafana Labs 的 Tanka 配置正是把 Pod 名称作为 label value 传入的。

注意:-labels参数只覆盖用于"确认缺失条目"与"抽查结果"的直接查询选择器。WebSocket tail 连接、Metric Test 与 Cache Test 使用的查询,始终由-labelname/-labelvalue与-streamname/-streamvalue构造选择器,会忽略-labels(见 reader.go 的buildLabelSelector:只有-labels为空时才使用 labelname/streamname 组合)。因此若使用-labels,请确保它与-labelname/-labelvalue(以及-streamname/-streamvalue)指向的是同一条流,否则这些查询会打到不同的数据上。

如果 Loki Canary 报告的unexpected_entries数量很高,说明 canary 可能等待得不够久,应把-wait的值调大到 60s 以上。

注意-pruneinterval与-interval的关系:例如以 10ms 间隔(每秒 100 条日志)、60s prune 间隔运行时,每分钟将写入 6000 条日志。如果这些日志都没通过 WebSocket 收到,canary 会直接查询 Loki 判断是否彻底丢失——但查询结果上限是 1000 条(见 reader.go 中 query_range 请求的limit=1000),因此即使日志确实进了 Loki,也无法一次性全部返回。

同理,如果调低pruneinterval,所有 canary 会按该间隔同时去查询缺失日志,有造成**拒绝服务(DoS)**的风险。

全部命令行参数

参数说明默认值
-addr stringLoki 服务器 URL:Port,例如loki:3100;也可用环境变量LOKI_ADDRESS设置无(必填)
-buckets intresponse_latency直方图的桶数量10
-cache-test-interval durationCache Test 查询的运行间隔15m
-cache-test-now durationCache Test instant-query 执行时间点(--now)回拨的时长1h
-cache-test-range durationCache Test instant-query 的时间范围24h
-ca-file string连接 Loki 时可选使用的客户端证书权威(CA)空
-cert-file string可选使用的客户端 PEM 编码 X.509 证书空
-insecure允许不安全的 TLS 连接(跳过证书校验,仅建议测试环境使用)false
-interval duration日志条目生成间隔1s
-key-file string可选使用的客户端 PEM 编码 X.509 私钥空
-labels string逗号分隔的查询标签,如service=loki,app=canary;解析逻辑简单,标签值不能含逗号或特殊字符、不要加引号;覆盖 labelname 与 streamname(仅影响直接查询)空
-labelname string该实例在日志选择器中使用的标签名name
-labelvalue string该实例在日志选择器中使用的唯一标签值loki-canary
-max-wait duration对 WebSocket 缺失条目持续查询 Loki 多久后才报告为缺失5m
-metric-test-interval durationMetric Test 查询的运行间隔1h
-metric-test-range durationMetric Test instant-query 的时间范围;在 canary 运行时长达到该值之前,会截断为实际运行时长24h
-out-of-order-max duration乱序条目的最大回拨时间1m
-out-of-order-min duration乱序条目的最小回拨时间30s
-out-of-order-percentage int以乱序方式发送的日志条目百分比(0-100)0
-pass stringLoki 密码;该凭据需同时具备 Loki 端点的读写权限空
-port intloki-canary 暴露指标的端口3500
-pruneinterval duration检查"已发送 vs 已接收"的频率,也是向 Loki 派发缺失日志查询的频率1m
-push直接把日志推送到指定 Loki 地址false
-query-append string追加到 Canary 查询的 LogQL 过滤器,例如\| json \| line_format \{{.log}}``空
-query-timeout duration等待 Loki 查询响应的超时时间10s
-size int每条日志行的字节数100
-spot-check-initial-wait duration抽查开始前等待的时长10s
-spot-check-interval duration从已发送条目中抽取单条结果并抽查的间隔;例如默认 15min 表示每 15 分钟保存一条,然后每隔-spot-check-query-rate重新查询,直到达到-spot-check-max15m
-spot-check-max duration抽查条目在被丢弃前的回溯时长4h
-spot-check-query-rate durationCanary 查询当前全部抽查条目列表的间隔1m
-streamname string该实例在日志选择器中使用的流名stream
-streamvalue string该实例在日志选择器中使用的唯一流值;未显式设置时默认stdout(push 模式为push)stdout/push
-tenant-id string写入X-Scope-OrgID头的租户 ID空
-tls连接 Loki 是否使用 TLSfalse
-user stringLoki 用户名空
-version打印构建版本信息false
-wait duration通过 WebSocket 等待日志条目的时长,超时后开始查询 Loki 确认1m
-write-max-backoff duration推送重试的最大退避时间5m
-write-max-retries int推送日志条目的最大重试次数10
-write-min-backoff duration首次重试前的初始退避时间500ms
-write-timeout duration等待 Loki 写入响应的超时时间10s

(以上参数均可在 main.go 中找到对应 flag 定义与默认值。)

Push 模式下的日志批处理

除上述参数外,还有两个 flag 控制-push模式下日志推送的批处理行为(实现在 batched_push.go):

  • -logs-batch-size:按给定大小批量发送日志到 Loki;值为0或1表示禁用批处理、每条立即发送(默认1)。源码中DefaultLogBatchSize = 1;
  • -logs-batch-size-max:-logs-batch-size的上限(默认20,对应DefaultLogBatchSizeMax = 20)。只有同时提高了 canary 的内存限制时才应调大它。

批处理的刷盘条件有三:达到批大小上限、30 秒超时、writer 终止(见 batched_push.go 的注释)。校验规则(-logs-batch-size非负、-logs-batch-size-max大于 0、且 size 不超过 max)见 main.go。

常见配置错误排查

Canary 立即退出并提示 "Must specify a Loki address"

如果看到:

Must specify a Loki address with -addr or set the environment variable LOKI_ADDRESS

说明未提供 Loki 地址。请设置-addr(例如-addr=loki:3100)或环境变量LOKI_ADDRESS。该值是host:port格式,不要带http://或https://协议前缀;需要安全连接时使用-tls=true。

读不到任何条目,日志全部判定缺失

如果 canary 持续写日志,但loki_canary_missing_entries_total不断攀升、response_latency无任何记录,最常见的原因是canary 写入与查询所用的标签不一致:

  • canary 用-labelname/-labelvalue(以及-streamname/-streamvalue)过滤日志流;把标准输出送进 Loki 的 Agent 必须打上同样的标签。如果 Alloy 或 promtail 配置附加了不同标签,canary 的读取查询将匹配不到任何数据;
  • 每个 canary 实例必须使用唯一的-labelvalue。两个 canary 共用同一标签值时,会互相读到对方的日志,并报出乱序或意外条目;
  • 如果设置了-labels,请记住它只覆盖直接查询的选择器、不覆盖 WebSocket tail。请确保-labels构造的选择器与-labelname/-streamname构造的选择器都匹配采集时附加的标签。

要确认选择器是否正确,可以在 Grafana 或logcli中直接运行 canary 会构造的同款查询(例如{name="loki-canary", stream="stdout"}),检查是否能返回 canary 的日志行。

认证失败(401 或 403)

如果推送或查询返回 HTTP 401/403,通常是 Basic 认证凭据或租户头不正确:

  • 必须同时提供-user与-pass。密码凭据需要有读写权限,因为 canary 既要查询、又要(-push模式下)写入;

  • 多租户 Loki 必须设置-tenant-id,让 canary 发送正确的X-Scope-OrgID头。租户 ID 缺失或错误时,典型表现是查询结果为空,或报错:

    no org id

TLS 错误

  • 未启用 TLS 却指定了客户端证书,会快速失败并提示Must set --tls when specifying client certs。-cert-file、-key-file、-ca-file必须与-tls=true成对使用;
  • x509: certificate signed by unknown authority说明 canary 不信任服务器证书。请用-ca-file提供 CA;仅测试环境可设-insecure跳过校验,生产环境不要使用;
  • 启用-tls后,请确认-addr指向 TLS 端口(例如:443或网关的 HTTPS 端口),因为 WebSocket 连接会切换为wss://。

Monolithic 模式部署

以下演示在 Loki 的 monolithic(单二进制)部署模式下,使用 Systemd、Alloy 与 Prometheus 完整搭建 Loki Canary 监控。

Systemd

创建 systemd 服务文件,把 Loki Canary 的标准输出写入/var/log/loki-canary.log:

[Unit] Description=Loki Canary Documentation=operations/loki-canary [Service] User=loki ExecStart=/usr/bin/loki-canary -addr=localhost:3100 -labelname=job -labelvalue=loki_canary -streamname=job -streamvalue=loki_canary Restart=on-failure RestartSec=5 StandardOutput=append:/var/log/loki-canary.log StandardError=journal [Install] WantedBy=multi-user.target

-labelname和-labelvalue指定用于识别 Loki Canary 日志的标签对;-streamname和-streamvalue指定额外的标签对,默认分别是stream和stdout,需要不同取值时可显式设置。如果不需要额外标签,可以把两个标签对设为相同值。额外的标签也可以在 Alloy 抓取日志时再附加。

使用 Alloy 抓取日志

loki.source.file "canary" { forward_to = [loki.write.local.receiver] targets = [{ __path__ = "/var/log/loki-canary.log", job = "loki_canary", }] } loki.write "local" { endpoint { url = "http://localhost:3100/loki/api/v1/push" } }

使用 Alloy 或 Prometheus 抓取指标

用 Alloy 抓取:

prometheus.scrape "loki" { targets = [{__address__ = "localhost:3100"}] forward_to = [prometheus.remote_write.default.receiver] } prometheus.remote_write "default" { endpoint { url = "<PROMETHEUS_REMOTE_WRITE_URL>" } }

用 Prometheus 抓取:

scrape_configs: - job_name: loki-canary static_configs: - targets: ['localhost:3500']

小结

Loki Canary 是 Loki 集群健康度的一线哨兵:通过"写入人工日志 → Agent 推送 → WebSocket/直接查询回读 → 指标对比"的闭环,它可以持续捕捉丢日志、乱序、重复、端到端延迟异常以及查询缓存失效等问题。配合本文介绍的 Spot Check、Metric Test、Cache Test 三类自动校验,以及/metrics、/suspend、/resume等控制面,运维人员可以用很小的成本构建起一套面向日志摄入链路的自动化巡检体系。相关的完整实现均可直接阅读本仓库源码:入口与参数解析在 cmd/loki-canary/main.go,核心比对与指标在 pkg/canary/comparator/comparator.go,WebSocket 回读与查询在 pkg/canary/reader/reader.go,日志生成与推送在 pkg/canary/writer,Kubernetes/Tanka 部署模板在 production/ksonnet/loki-canary。

【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询