从临时日志迁移到结构化事件和 SQL
自由格式的日志对于本地调试很有用,但重复出现的操作和产品问题需要稳定的字段、明确的单位和可审查的定义。迁移不需要替换每个现有的日志或可观测性工具。从一个生产工作流程开始,在现有日志旁边发出一个有界完成事件,并在更改仪表板或告警之前证明其 SQL 回答了预期的问题。 结构化日志管理指南 解释了更大的操作模型。
本指南使用 API 请求作为示例,但相同的顺序适用于作业、Webhook、AI 运行、计费工作流和应用程序级数据库操作。
1. 选择一个决策,而不是整个日志流
从一个已经消耗工程时间的问题开始:
- 哪些 API 路由具有有意义的 5xx 速率?
- 哪些限速请求在重试后会恢复?
- 哪些工作类型正在增加排队年龄?
- 哪个提示版本产生的可接受结果较少?
- 哪个数据库操作指纹在一个请求中重复?
写下答案将支持的决定、所有者、报告窗口以及解释费率所需的最小数量。这可以防止事件成为应用程序内存中每个可用值的副本。
当诊断日志仍然有用时,保留堆栈跟踪或本地上下文的诊断日志。结构化事件是所选问题的持久分析契约。
2. 盘点当前意义
在更改仪器之前,保存现有的搜索或仪表板定义并检查几个实际结果。记录:
- 哪些消息或属性标识工作流程。
- 如何区分成功、重试、取消、终端失败。
- 哪个时间戳标志着工作的开始或完成。
- 重试是否创建额外记录。
- 哪些字段包含机密、个人数据、原始有效负载或无限文本。
- 哪些排除和最小量规则仅存在于操作员的记忆中。
该清单是语义基线,而不是旧结果正确的承诺。如果现有的搜索将尝试与逻辑请求混合在一起,请记录该限制,而不是默默地复制它。
3. 定义一个有界完成事件
更喜欢一个事件而不是一个已完成的工作单元。使用明确的数字、布尔值、单位和受控类别。仅当需要关联时才使用路由模板而不是原始 URL、使用分类错误而不是不受限制的异常文本以及内部标识符。
{
"event_name": "api_request_completed",
"request_id": "req_7d91",
"route_template": "/api/projects/:id/sync",
"method": "POST",
"status_code": 503,
"outcome": "dependency_failed",
"latency_ms": 842,
"attempt_number": 2,
"release": "2026.07.2",
"environment": "production",
"schema_version": 1
}
请勿发送授权标头、cookie、请求正文、连接字符串、原始提示、webhook 负载、付款详细信息或不受限制的客户内容。部署前查看字段允许列表。请参见 脱敏敏感数据 和 高基数字段。
4. 在现有日志旁边发出
运行有时间限制的双写周期。该应用程序继续生成您的团队所依赖的诊断记录,同时还发出新事件。在中央边界添加工具(中间件、作业包装器、Webhook 调度程序或数据库客户端包装器),以便成功和失败路径使用相同的时钟和字段名称。
仪器不得将成功的应用程序变成失败的应用程序。将分析交付视为单独的、有限制的操作,具有明确的超时和适合您的系统的重试行为。在强制实施之前,请验证缺失的配置是否在每个已部署的环境中安全回退。
在双重写入期间,监视事件摄取新鲜度、必填字段完整性、模式版本和重复标识符。 事件摄取新鲜度、必填字段空率 和 重复的事件 ID 配方提供可重复使用的检查。
5.将问题翻译成复习过的SQL
从事件契约开始,而不是音译文本搜索表达式。对于 API 错误,保留计数和分母:
SELECT
route_template,
COUNT(*) AS requests,
SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS errors,
100.0 * SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0) AS error_rate_pct
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
AND environment = 'production'
GROUP BY route_template
HAVING COUNT(*) >= 20
ORDER BY error_rate_pct DESC;
查看时间边界、状态定义、重试粒度、后期事件处理和最小量。测试至少一项成功、预期失败、重试、重复、空和延迟事件。如果查询在操作上变得很重要,请在其旁边存储确定性固定装置和预期结果。
SQL配方库 包括类型化模式、只读 DataFusion SQL、合成输出、可视化、边缘案例、仪表板计划和告警指导。 浏览器 SQL 游乐场 在本地运行支持的装置,而无需将示例行发送到 Telemetry。
6. 比较语义,而不仅仅是总数
在同一个关闭的 UTC 窗口中运行旧的和新的答案。研究差异而不是针对任意精确匹配:
- 较低的新计数可能意味着重试被正确折叠。
- 较高的计数可能会暴露消息模式搜索忽略的失败。
- 不同的路由排名可能是由于稳定的路由模板替换了原始 URL 而导致的。
- 最近的小不匹配可能是由延迟事件或不完整的时间段引起的。
- 历史数据可能不包含新合约引入的字段。
为每个差异创建简短的调节记录:原因、可接受的行为、所有者以及事件或查询是否需要更改。在新的 SQL 重现旧错误之前,请勿对其进行调整。
7、分阶段推广
一次移动一个消费者:
- 使用新的 SQL 制作探索性报告。
- 保存审阅的查询及其所有者和定义。
- 构建一个仪表板,除了费率之外还保留交易量并使用完整的存储桶。
- 在非寻呼或影子模式下运行任何建议的告警。
- 添加持续时间规则、最小音量和响应链接。
- 仅当新消费者在商定的验证窗口中存活下来后,才让旧消费者退出。
仪表板切换是可逆的。删除旧数据、删除诊断日志或禁用已建立的告警可能不会。将这些作为单独的决定,并进行自己的保留和回滚审查。
8. 保留明确的回滚路径
割接前,记录:
- 之前的搜索、仪表板和告警标识符。
- 介绍该事件的版本。
- 事件和架构版本。
- 新的已保存查询标识符。
- 将消费者返回到先前定义的标准。
- 双重写入和额外验证可以结束的日期。
如果新事件丢失必填字段、变得延迟或改变含义,请恢复受影响的消费者,同时继续诊断生产者。回滚不应要求在同一事件期间删除新的仪器。
此迁移不涵盖哪些内容
此工作流并不声称要替换本机主机指标、数据库服务器统计信息、分布式跟踪或不受限制的诊断日志。例如,Telemetry 的数据库模式分析应用程序发出的数据库遥测,例如安全查询指纹、池等待、事务结果、锁定观察、复制信号和迁移结果。他们不是 pg_stat_* 收藏家。
使用每个信号来回答它可以回答的问题,并仅在操作价值证明数据和基数成本合理的情况下将系统与稳定的标识符连接起来。
实际的首次迁移
对于API业务,从API 请求吞吐量、API 按路线的错误率和API 429 恢复开始。他们共享一个小型事件合约,同时回答不同粒度的流量、可靠性和重试问题。对于数据库支持的工作流程,仅在请求和查询指纹可以安全关联后添加 N+1查询检测。
一旦一个工作流程稳定,请重复使用迁移清单以进行下一个决策,而不是毫无疑问地扩展原始事件。