
🎙️ 05. 从零搭建 New API 监控看板:一个 SQLite 非时序数据的自救实录
📅 录制日期:2026-04-16
🎙️ 主播:晨玙 & 蛋壳
📝 时长:约 15 分钟阅读
🏷️ 标签:#Grafana #监控 #SQLite #NewAPI #踩坑
🎬 开场
晨玙:「今天想把 New API 的监控看板接进 Grafana,本来以为就是写几个 PromQL 的事。」
蛋壳:「嗯,Prometheus + Grafana 确实是监控标配。New API 的数据源是啥?」
晨玙:「它业务数据全存在 SQLite 里。但我想搞个看板,看看模型调用次数、Token 消耗、失败率这些。」
蛋壳:「哦豁,SQLite… 这就有意思了。你打算怎么搞?」
💬 第一幕:SQLite 不是时序数据库
晨玙:「我先写了个 Python exporter,从 one-api.db 读数据,暴露成 /metrics。但有个问题——Grafana 里选’最近 24 小时’,数据好像不太对。」
蛋壳:「啊,这是核心问题。SQLite 不是时序数据库,它没有 counter/gauge 的概念。你选时间范围,它根本不知道’最近’是什么意思。」
晨玙:「对,它只存了原始时间戳。那我咋搞?总不能每次手动改 SQL 吧。」
蛋壳:「可以在 exporter 里预计算固定窗口。每次 Prometheus 来 scrape,现场跑 SQL 按时间段分桶,暴露成不同的 gauge 指标。比如 newapi_24h_requests_total、newapi_7d_tokens_total 这种。」
晨玙:「牺牲灵活性换正确性?行吧,总比看不了强。」
💬 第二幕:62 种模型里只有 5 个是活的
晨玙:「看板跑起来了,但蹦出 62 种模型,90% 是我几个月前试过就再也没用过的。Top 10 表格被垃圾淹没,完全没法看。」
蛋壳:「历史包袱太重了。你暴露的是全量历史聚合?」
晨玙:「对。加了固定窗口之后好了点,但’all’窗口还是脏。」
蛋壳:「可以给表格加 Top 10 限制,只展示活跃的。all 作为兜底选项,想看总量的时候再切过去。」
晨玙:「行,我试试。运营视角需要看累计,排障视角需要看活跃——这里确实要权衡。」
🤔 晨玙的思考:「其实监控看板也得分场景。运营想看’总共烧了多少钱’,排障想看’现在哪个模型在报错’。一个面板很难同时满足。」
💬 第三幕:channel_name 全是 NULL
晨玙:「还有个坑。logs 表里有 channel_name 字段,但查出来永远是 NULL。我以为是 SQL 写错了,连查三遍。」
蛋壳:「结果发现呢?」
晨玙:「New API 写日志时这个字段就是空的,它只写了 channel_id。」
蛋壳:「啊这… 那只能 JOIN channels 表了?」
晨玙:「对,LEFT JOIN。但 SQL 复杂了一倍,而且渠道表改名的话历史日志的渠道名也跟着变,有点烦。」
💡 转折点:「从’字段有问题’到’原来设计如此’,花了 20 分钟。以后看到 NULL 先检查源头,别急着怀疑自己。」
💬 第四幕:流式调用被当成了全部调用
晨玙:「看板上’模型调用次数’一直偏低,我查了半天才发现——我硬编码了 type="2",只统计了流式调用。」
蛋壳:「普通调用全被漏了?那失败率的分母也变小了吧。」
晨玙:「对,数据失真。但这个问题藏了很久,因为平时基本都是流式调用,乍一看数据是对的。」
蛋壳:「典型的幸存者偏差。修复简单吗?」
晨玙:「简单,去掉 type 过滤就行。但排查过程很烦,我差点怀疑人生。」
💬 第五幕:表格展示比图表难做一百倍
晨玙:「可视化部分也是坑。bargauge 单条数据时标签被截断;barchart 横坐标显示成时间戳(2026),而不是模型名。」
蛋壳:「Grafana 的图表组件确实有很多边界 case。你怎么解决的?」
晨玙:「统一改成 table。但表格也有坑——数值列的阈值背景色会传染到文本列,整个表格花花绿绿像彩虹。」
蛋壳:「哈哈哈哈这个画面感。」
晨玙:「最后给文本列单独加 field override,固定颜色取消背景色,只让数值列保留阈值染色。折腾半天才像样。」
💬 第六幕:浏览器装不上,截图告吹
晨玙:「对了,我还想让 AI 自动截图放博客里。结果试了 N 种方法都没成。」
蛋壳:「遇到什么问题了?」
晨玙:「apt-get install chromium 被 SIGKILL;Playwright 下载成功但缺系统库;Grafana Image Renderer 插件签名验证失败… 环境限制太多了。」
蛋壳:「这… 确实有点超出预期。截图的事可能得换个思路。」
晨玙:「算了,先放占位符,截图我自己补。有时候接受现实比硬刚更务实。」
💡 转折点:「从’我一定要搞定自动化’到’接受现实,换个方式交付’。不是所有东西都能自动化,知道边界也是能力。」
🧵 复盘:我们是怎么想明白的
一开始我们以为 [Prometheus + Grafana 监控任何数据源都很简单]…
聊着聊着发现 [非时序数据库硬套时序监控有很多边界问题:时间切片、历史数据噪音、维度字段缺失]…
最后得出的结论是 [预计算固定窗口的 gauge 方案,虽然牺牲了灵活性,但在工程上是最务实的选择]…
如果用一句话总结:「监控看板的本质是’让人看懂’,不是’技术炫技’。当数据源不配合时,妥协和 trade-off 本身就是设计的一部分。」
🎯 尾声
晨玙:「这次搞下来最大的收获不是 Grafana 玩得有多溜,是深刻体会了非时序数据硬套时序监控有多别扭。」
蛋壳:「下次遇到类似的业务数据库监控,你会怎么做?」
晨玙:「三个问题先想清楚:数据源能不能原生支持时间范围切片?历史垃圾数据会不会淹没当前的 Top N?维度字段是不是真的可信?」
蛋壳:「solid。那截图的事…」
晨玙:「再说吧,先把这篇发了。有些坑,踩过了才知道深浅。」
本文由 蛋壳 基于真实对话整理,经 晨玙 确认发布。