跳转至

Prometheus 指标

应用在 /metrics 上暴露 Prometheus 指标。可以抓取它们,在 Grafana 或任何兼容 Prometheus 的系统中构建仪表板,对缓存命中率设置告警——按你的需要使用。指标地址和刷新设置同样可以在管理 → 集成中查看。

预填充流量同样会被统计,与仪表板一致

预填充守护进程和其他客户端一样通过缓存下载,因此它的流量会记录在自己的客户端 IP 下,通常是 127.0.0.1。/metrics 和仪表板都会统计这部分流量,两者的数字一致。

一次预填充运行几乎全是未命中字节,因此会在一段时间内拉低所有命中率序列。故障排除中说明了其中的算法,以及如何在视图中过滤掉该守护进程。

客户端排除现在同样作用于 /metrics

在管理 → 客户端中被排除的客户端,现在不仅会从应用界面中移除,也会从 /metrics 中移除。它不再出现在 lancache_client_bytes_total 以及其余 lancache_client_* 序列中,其字节数也不再计入 lancache_service_* 系列和全局总计。两种模式都会生效:仅统计让客户端仍显示在下载和实时速度中,但不计入总计和命中率;隐藏则将其从所有位置移除。

如果你排除了任何客户端,相关序列会在包含此更改的版本上出现下降。历史数据不会被改写,但从该版本起的每个值都会低于此前的对应值。请重新检查所有依据旧数值调整过的 rate() 面板和告警阈值。

这也是把预填充流量挡在 Prometheus 之外的方法:在管理 → 客户端中排除该守护进程的客户端 IP,通常是 127.0.0.1。

可用指标

最常用的几个序列:

指标 描述
lancache_cache_capacity_bytes 总存储容量
lancache_cache_used_bytes 当前已用空间
lancache_cache_free_bytes 剩余可用空间
lancache_cache_hit_bytes_total 节省的带宽(缓存命中)
lancache_cache_miss_bytes_total 新下载的数据
lancache_cache_hit_ratio 缓存命中率(0-1)
lancache_active_downloads 当前活跃下载数
lancache_active_clients 近期活跃客户端数
lancache_service_downloads_total 按服务统计的下载量
lancache_service_bytes_total 按服务统计的带宽
lancache_service_hit_ratio 按服务统计的命中率
lancache_client_bytes_total 按客户端统计的带宽

还有更多——吞吐量、按小时的分解统计、缓存增长趋势、距离写满的预计天数、高峰时段统计,以及按服务的命中/未命中序列。在浏览器中打开 /metrics 即可看到带说明文字的完整指标集。

按游戏统计的指标

指标 描述
lancache_game_bytes 该游戏累计提供的字节数
lancache_game_cache_hit_bytes 从缓存提供的字节数
lancache_game_cache_miss_bytes 从上游获取的字节数
lancache_game_downloads 下载次数
lancache_game_cache_hit_ratio 该游戏的命中率(0-1)
lancache_game_active_downloads 当前活跃或最近 5 分钟内结束的下载数

这六个指标都带有相同的三个标签:service、game 和 app_id。service 的值为小写,与 lancache_service_bytes_total 已经使用的值一致,因此两组指标可以关联。注意 Xbox 流量在这里按其原始服务名分别出现,而应用自己的界面会把它们合并显示。

app_id 对 Steam 游戏是 Steam 应用 ID,对 Epic 游戏是 Epic 应用 ID,对暴雪、Riot 和 Xbox 这类按名称识别的游戏则是 0,与缓存检测为它们存储的值相同。它的作用是:即使游戏在目录中被改名,序列仍然保持同一身份。

只有按累计字节数排名靠前的游戏会被导出,默认 50 个,可以在管理 → 集成 → 刷新和抓取速率中修改上限。跌出前 N 名的游戏会直接停止导出,而不是上报 0,因此它的曲线会干净地结束,而不会掉到底部。修改上限会在下一个刷新周期生效,所以最多需要等待一个完整的数据刷新间隔。

这六个指标统计缓存记录过的所有下载,包括缓存文件此后已被驱逐的下载,这与本页其他下载类指标的口径一致。

磁盘上的游戏

指标 描述
lancache_game_cache_bytes 该游戏在磁盘上占用的字节数(未去重)
lancache_game_cache_files 该游戏找到的缓存文件数
lancache_games_on_disk_bytes 归属于游戏的总字节数,已去重
lancache_games_on_disk_count 磁盘上找到的游戏数量
lancache_identified_service_bytes 归属于某个服务但未归属到任何游戏的总字节数,已去重
lancache_detection_computed_timestamp 磁盘数据最近一次计算的时间,Unix 时间戳

磁盘类指标会跳过已驱逐的游戏,与"磁盘上的游戏"视图的做法一致,因此两者的数字相符。之所以提供 lancache_detection_computed_timestamp,是因为这些数字只在缓存扫描或移除操作时才会重新计算。没有它的话,一条水平的曲线既可能表示确实没有变化,也可能表示根本没有运行过计算。

按游戏统计的磁盘字节数加起来不等于总量

lancache_games_on_disk_bytes 在所有游戏和所有服务之间做了去重,因为 lancache 会在不同游戏之间共享缓存对象。而按游戏统计的 lancache_game_cache_bytes 是原始值,共享对象会在每个用到它的游戏中各计一次。

因此把按游戏的序列相加得到的数字会大于总量。这是预期行为而非缺陷,应用自己的仪表板也是把这两个数字并排显示的。

Steam 映射覆盖率

指标 描述
lancache_steam_unknown_game_bytes 未能识别出游戏名称的 Steam 下载所提供的字节数
lancache_steam_unknown_game_downloads 未能识别出游戏名称的 Steam 下载次数

这两个指标刻意只针对 Steam。WSUS 和裸机流量按设计本来就不带游戏名称,如果统计所有无名称的下载,会把一个完全正常的部署报告成有问题。

局域网活动

指标 描述
lancache_event_bytes 标记到该活动的下载所提供的字节数
lancache_event_cache_hit_bytes 该活动的缓存命中字节数
lancache_event_downloads 该活动的下载会话数
lancache_event_cache_hit_ratio 该活动的命中率(0-1)

这四个指标都带有 event(显示名称)和 event_id。它们只统计已标记的下载,与仪表板活动筛选使用的集合相同,并且和其他 /metrics 指标一样遵守客户端排除规则。

只导出按字节数排名前 50 的活动。没有已标记下载的活动会被省略,而不是上报 0。它们都是 gauge:请直接绘制。仪表板上按活动开始时间对齐的叠加曲线不会从这里导出——Prometheus 抓取的是累计值,而不是从每个活动开始起按小时的序列。

哪些指标可以配合 rate() 使用

以 _total 结尾的名称按惯例表示计数器,而 rate()、irate() 和 increase() 都是为计数器设计的。上面这些新指标没有一个带 _total,也没有一个适合配合 rate() 使用。

它们全都是 gauge 类型,并且数值确实可能下降:当某个服务不再出现在日志文件中时,旧的下载记录会被清理;驱逐也会把游戏从磁盘上移除。rate() 会把任何下降当成计数器重置,从而制造出一个根本没有发生过的巨大尖峰。

请直接绘制它们的曲线,如果需要变化速率,可以使用 delta() 或 deriv()。avg_over_time()、max_over_time()、topk() 和 sum() 都可以正常使用。

这确实让新名称与 lancache_service_bytes_total 及其同类不一致,后者同样是 gauge 类型却带着 _total 后缀。那些名称保持不变,因为改名会破坏所有已经在使用它们的仪表板。新名称按其真实类型命名,而不是延续旧有的这个错误。

Prometheus 配置

scrape_configs:
  - job_name: 'lancache-manager'
    static_configs:
      - targets: ['lancache-manager:80']
    scrape_interval: 30s
    metrics_path: /metrics

如果你设置了 Security__RequireAuthForMetrics=true,加上 Bearer 认证:

    authorization:
      type: Bearer
      credentials: 'your-api-key-here'

查询示例

# 缓存命中率百分比
lancache_cache_hit_ratio * 100

# 过去 24 小时节省的带宽
increase(lancache_cache_hit_bytes_total[24h])

# 缓存使用量(GB)
lancache_cache_used_bytes / 1024 / 1024 / 1024

# 带宽占用最高的 10 个游戏
topk(10, lancache_game_bytes)

# 按游戏统计的命中率百分比
lancache_game_cache_hit_ratio * 100

# 未能匹配到游戏的 Steam 字节数占比
lancache_steam_unknown_game_bytes / lancache_service_bytes_total{service="steam"}

# 每个局域网活动提供的字节数
topk(8, lancache_event_bytes)

最后这条查询两边的后缀不一致,这不是笔误。lancache_steam_unknown_game_bytes 是新增的 gauge 之一,不带 _total;lancache_service_bytes_total{service="steam"} 是已有序列,保留了它发布时的后缀。两边都是统计字节数的 gauge,所以这个比值本身是正确的。