ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Kener v4.1.0 版本更新详解:Confirmation Threshold、维护事件状态机与 v4 API 扩展

Kener v4.1.0 版本更新详解:Confirmation Threshold、维护事件状态机与 v4 API 扩展
  • 可观测性
  • 后端
  • 前端
  • 运维

【免费下载链接】kener

Stunning status pages, batteries included!

项目地址:https://gitcode.com/gh_mirrors/ke/kener
点击查看免费下载

本文基于 Kener(一款开箱即用的状态页与监控平台)官方仓库中的 v4.1.0 变更日志(changelog),逐项解析该版本的七项新特性、五项改进与三项缺陷修复。读完后,你将掌握 Kener v4.1 中 Confirmation Threshold(宽限期)的完整工作机制与验证方法、维护事件的 Complete/Cancel 手动状态迁移规则、页面级展示设置(Page settings)的 API 用法,以及~home页面寻址、按 tag 删除监控器等 v4 REST API 的具体行为与底层实现。

1. 新特性总览

v4.1.0 的官方变更日志位于 v4.1.0.md/docs/content/v4/changelogs/v4.1.0.md),其内容划分为 New features、Improvements、Bug fixes 三大部分。当前仓库package.json中的版本号为4.1.7,即 v4.1.x 系列的后续修订版本,本文描述的所有行为均以当前仓库源码为准。

1.1 Confirmation Threshold(宽限期 / Grace period)

这是 v4.1.0 最重要的特性:监控器现在可以要求连续 N 次检查都出现状态翻转,才将新状态写入时间线,让瞬时的网络抖动(transient blips)不再侵蚀 uptime 百分比或污染按天状态条(day bars)。

配置方式:

  • 在Monitor → General Settings中设置每个监控器独立的Grace period,取值1–60,默认1(即关闭);
  • 或通过 v4 监控器创建/更新 API 的confirmation_threshold字段设置:
PATCH /api/v4/monitors/{monitor_tag} { "confirmation_threshold": 5 }

该字段被校验为1到60之间的整数。完整的参数说明与示例见仓库文档 Grace Period/docs/content/v4/monitors/grace-period.md)。

源码视角:双列设计与一次性的抖动抑制

该特性由数据库迁移 20260613120000_add_confirmation_threshold_and_raw_status.ts 落地,为monitors表新增confirmation_threshold列(unsigned integer,非空,默认1),为monitoring_data表新增raw_status列(可空文本)。这正对应 changelog 的表述:抑制只在计划检查的写路径上发生一次——monitoring_data.raw_status记录每次检查实际观察到的状态,而status保存"已确认"的一侧。

核心逻辑实现于 confirmationThreshold.ts,其resolveConfirmedStatus函数遵循明确的顺序契约(源码注释中写明必须在当前分钟行持久化之前调用):

  1. 中性观察直通:NO_DATA观察不参与计数——既不推进也不重置 pending 计数,按原样(灰色)写入;
  2. 锚点(anchor)取最近一次真实观察的已确认状态;冷启动或同侧观察立即提交;
  3. 异侧观察:回看最近threshold + LOOKBACK_BUFFER(buffer 为 10)行,统计连续 pending 次数,遇到 incident/maintenance 叠加行(overlay)即停止——叠加窗口是硬边界,计数在其后重新开始;
  4. 连续次数达到阈值时调用backfillConfirmedStatus回溯回填:确认的宕机从其第一次失败检查起即记为DOWN,恢复对称地处理,因此故障起止时间保持精确;
  5. 未达到阈值时保持确认侧状态(pendingHold: true),期间被"扣住"的样本仍保留真实延迟和错误文本,并打上| Status held during grace period标签。

几个值得注意的边界语义(与 Grace Period 文档/docs/content/v4/monitors/grace-period.md) 一致):

  • 按次数而非按时间:5就是连续 5 次检查,每分钟 cron 下约等于 5 分钟;
  • DEGRADED计入"非UP"一侧:在DOWN与DEGRADED之间抖动仍会确认不健康,但已处于不健康区间内的严重度切换(DOWN ↔ DEGRADED)立即记录;
  • 只统计计划检查,手动/API 推送的数据与默认状态填充不经过抑制;
  • 分组监控器按成员的已确认状态评分,成员的宽限期自动向上传播;
  • 与告警的交互:告警在已抑制的时间线上求值,因此有效延迟取max(grace period, failure threshold)——是两者中的较大者,而非相加。

官方给出的验证步骤(grace period = 3):

  1. 在测试监控器上设置 grace period 为3并保存;
  2. 让目标连续失败 2 次 → 状态保持UP;
  3. 第 3 次连续失败 → 状态翻转为DOWN,前 2 个样本被回填为DOWN;
  4. 恢复目标 → 连续 3 次成功后回到UP。

选型建议(原文档 TIP):宽限期应略长于典型的瞬时抖动,但又不能长到拖慢真实故障的捕获;每分钟检查的监控器从3–5起步较为合适。

1.2 手动完成/取消维护事件(Manual maintenance event transitions)

单个维护事件现在可以在维护管理 UI 中被手动标记为完成或取消,让记录的时间线与实际情况一致:

  • 新的Complete和Cancel操作将事件移动到终态COMPLETED或CANCELLED,并相应调整end_date_time;
  • 终态是最终状态——已完成或已取消的事件不可再编辑;
  • v4 API 支持状态迁移与时间窗口编辑,且两者互斥(不能在同一请求中同时提交);
  • 订阅者会收到迁移通知。
源码视角:状态机与互斥约束

API 侧实现在 events/[event_id]/+server.ts:当请求体包含status时进入"迁移模式",若同时携带start_date_time/end_date_time直接返回 400(Cannot update status and start/end times in the same request),且status只接受COMPLETED或CANCELLED。

控制层 UpdateMaintenanceEventStatus 定义了完整的状态机:

  • 允许的迁移为ONGOING → COMPLETED,以及SCHEDULED/READY/ONGOING → CANCELLED,其余组合抛出Cannot transition event from ... to ...;
  • 已开始的ONGOING 事件被结束时,end_date_time会被移动到实际结束时刻——源码约束其不早于第一分钟(start_date_time + 60)、不晚于原计划结束时间:Math.min(end_date_time, Math.max(now, start + 60)),即"记录反映实际发生的事";未开始的事件保留原计划窗口;
  • 迁移成功后,若站点级通知设置中event_types.ended开启,则通过subscriberQueue推送"has been completed"/"has been cancelled"的维护通知。

完整设计说明可继续查看 Maintenance Events 文档/docs/content/v4/maintenances/events.md)。

1.3 "None" 类型监控器的 Last known status

None类型监控器(不主动探测、等待外部推送数据的监控器)现在可以可选地复用上一次已知的状态(status、latency 与 source),而不是在无数据推送时报告无数据。在监控器配置 UI 中有一个新复选框启用该行为。

从源码结构看,实现位于 noneCall.ts:当type_data.overrideWithLastKnownStatus为真时,调用GetLastKnownStatus(monitor.tag)取最近一条记录,且仅当最后一条记录的type为MANUAL时才返回其status/latency,否则返回null走无数据路径。配置项定义在 monitor.ts 类型文件,管理 UI 复选框见 monitor-none.svelte/manage/app/monitors/[tag]/types/monitor-none.svelte)。

1.4 Page settings:页面级展示设置

状态页新增了每页面独立的展示控制,既可在 manage UI 配置,也可通过 v4 pages API 操作:

  • Per-page status history——移动端(默认30)与桌面端(默认90)各自独立的天数,均限制在1–365;
  • Monitor layout styles——在default-list、default-grid、compact-list、compact-grid四种布局中选择;
  • Meta / social overrides——页面级 title、description 与预览图。

这些默认值在源码中集中定义于 global-constants.ts(DEFAULT_STATUS_HISTORY_DAYS_DESKTOP: 90、DEFAULT_STATUS_HISTORY_DAYS_MOBILE: 30、STATUS_HISTORY_DAYS_MIN/MAX: 1/365、MONITOR_LAYOUT_STYLES四元组),与文档完全吻合。

API 行为有两个关键设计,实现在 pageSettings.ts:

  1. 深度合并(deep-merge)的PATCH语义:applyPageSettingsPatch只写入请求中出现的键,存储 JSON 中的其余键(包括模块不认识的键)全部保留,"API 写入永远不会抹掉应用其他部分写入的设置";
  2. 校验拒绝:validatePageSettings对类型做逐叶子检查(布尔、非负整数、天数范围、布局样式枚举),非法 payload 返回 400 验证错误。

值得注意的存储边界细节:存储 JSON 中 meta 字段使用 camelCase(metaPageTitle等,由 manage UI 写入),而 v4 API 对外暴露 snake_case,映射集中在这一个存储边界模块中完成;读侧toApiPageSettings还会忽略存储中类型不符或越界的值(例如手工编辑产生的days: 999),保证 API 响应始终符合 schema。

页面 API 的完整请求处理(含page_path净化、重复路径冲突检查等)见 pages/[page_path]/+server.ts。

1.5 监控器列表的行内开关(Inline monitor toggles)

Manage → Monitors列表现在支持就地切换监控器的active/inactive状态与可见性(visibility),无需为改一个布尔值打开完整的编辑页。该改动属于管理 UI 层的交互优化,对应列表页 manage/app/monitors/manage/app) 下的监控器列表组件。

1.6 API:用~home寻址首页

首页以空字符串路径存储,此前无法通过 REST API 寻址。v4.1.0 起:

  • GET/PATCH/DELETE /api/v4/pages/~home指向首页;
  • 列表与单页响应将其page_path渲染为~home,"你读到的正是你能寻址的";
  • PATCH接受除固定首页路径外的所有字段;
  • DELETE对首页返回 400(Cannot delete the home page),与 manage UI 侧DeletePage强制的同一不变量一致;
  • 未匹配的/api/路由现在返回 JSON 404,而不是回落到 HTML 页面(见 hooks.server.ts 中各中间件对未解析资源的 JSON 404 响应)。

常量定义于 global-constants.ts:HOME_PAGE_TOKEN: "~home"。API 处理器中还处理了一个读改写陷阱:客户端读到~home后原样回传,服务端将其视为"不修改路径";而尝试把首页路径改成非空值会被拒绝(Home page path cannot be changed)。

1.7 API:incident 与 maintenance 响应携带绝对url

v4 API 响应新增绝对url字段,消费方可以直接链接而无需自行拼接 id:

响应对象url形式
Incident<site>/incidents/<id>
Maintenance(list/get/create/update)<site>/maintenances/<id>?type=maintenance
Maintenance event<site>/maintenances/<event_id>

URL 由配置的 Site URL 加 base path 构建。源码中可验证该实现模式,例如维护列表/详情响应的 url 字段构建/api/v4/maintenances/+server.ts#L81):siteUrl + serverResolver('/maintenances/' + maintenance.id + '?type=maintenance'),事件响应同样使用(await GetSiteURL()) + serverResolver(...)。

1.8 API:按 tag 删除监控器

新增DELETE /api/v4/monitors/{monitor_tag}端点,走与管理 UI 相同的删除路径。更重要的是修复了删除时的清理问题:监控器删除现在显式清理 alert-config 行(v2 告警及 trigger/monitor 连接表),修复了 SQLite 遗留的孤儿行——SQLite 从不强制执行ON DELETE CASCADE外键;共享的 alert config 会保留到最后一个引用它的监控器被解除绑定。

清理链完整体现在 DeleteMonitorCompletelyUsingTag 中,按序执行:删除监控数据 → 删除 incident 关联 → 删除 v2 告警 →删除 alert-config 关联(deleteMonitorAlertConfigsByMonitorTag)→ 删除页面关联 → 删除维护关联 → 从分组移除 → 清缓存 → 最后删除监控器行本身。API 入口在 monitors/[monitor_tag]/+server.ts。

2. 改进(Improvements)

2.1 列表视图渲染富文本维护描述

维护描述现在在所有列表视图中以净化后的 HTML渲染——首页、自定义页面、监控器页面、事件页面和 embed 组件,与详情页保持一致:HTML 格式与换行正确显示,不再出现字面标签;由于渲染面向匿名访客,全程保留净化(sanitization)步骤。

2.2 分组监控器选择器支持搜索

Group monitor picker 新增搜索栏,让在拥有数百个监控器的实例上按名称查找并添加监控器成为可能,不必再滚动扁平列表。

2.3 数据库连接池调优与健康检查

数据库层现在会调优连接池规模、将池边界钳制到安全值、保护 Redis 探测逻辑,并加固错误页面;启动时会记录当前配置的数据库类型,便于诊断。

2.4 更广泛的告警求值

连续状态与延迟检查现在统计所有对告警可见的样本类型,提升告警可靠性;手动提交的数据在更新后会触发一次尽力而为(best-effort)的告警重新求值。

2.5 本地化

  • 新增**乌克兰语(Ukrainian)**翻译,仓库 locales/uk.json 已存在;
  • 修复法语语言包字符串中的语法错误;
  • 更新默认 v4 告警正文描述——旧文案仍引用 v4 之前的模板变量。

3. 缺陷修复(Bug fixes)

3.1 Overall status 采用 worst-wins 排序

聚合状态在所有组件中一致遵循DOWN > DEGRADED > MAINTENANCE > UP的最坏状态优先排序,进行中的维护不再掩盖真实宕机。该折叠逻辑的规范注释位于 clientTools.ts("the worst state wins"),并影响页面横幅与_徽标等多监控器聚合场景。

3.2 社交预览图使用绝对 URL

og:image与twitter:imagemeta 标签现在会前缀 Site URL,修复了因相对路径导致预览失败的问题。

3.3 修复公开页头叠加

公开页面上固定导航栏与粘性主题栏背后现在共用一个单一磨砂(frosted)背景,页面内容不再在滚动时透出。

4. 小结

v4.1.0 的主线可以概括为三件事:让状态数据更诚实(Confirmation Threshold 用raw_status/status双列把"观察到的"与"确认的"分离,瞬态抖动不再污染 uptime),让运营操作更贴近现实(维护事件可手动 Complete/Cancel、监控器列表行内开关),让 API 更完整(~home寻址、绝对url、按 tag 删除监控器、页面设置的 deep-merge PATCH)。以上每一项均可在仓库中溯源:特性文档见 changelogs 目录/docs/content/v4/changelogs/v4.1.0.md) 与 Grace Period/docs/content/v4/monitors/grace-period.md),核心实现见 confirmationThreshold.ts、maintenanceController.ts、pageSettings.ts 与 pages API 处理器/api/v4/pages/[page_path]/+server.ts)。

  • 可观测性
  • 后端
  • 前端
  • 运维

【免费下载链接】kener

Stunning status pages, batteries included!

项目地址:https://gitcode.com/gh_mirrors/ke/kener
点击查看免费下载

相关推荐

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进