机器人在现场出问题后,日志通常是唯一的线索。但常见的日志只能回答“出错了”,回答不了当时在做什么、哪一步超时、以及这个错误属于哪次任务。缺少这些信息,复盘就只能停留在猜测。
这篇文章讨论的是把日志当作证据来设计:不是为了记录更多,而是为了在事后能回答几个具体问题。
先写出你要回答的问题
设计字段之前先列出复盘时要回答的问题。常见的几个:这次任务从哪台设备、哪个请求开始;在哪一步超时;超时前最后收到的有效反馈是什么;同一时刻有没有其他错误;这个问题在这台设备上出现过几次。
这些问题决定了字段,而不是反过来。如果先写日志再想用途,很容易得到大量重复的“进入函数”“离开函数”记录,却在关键判断点缺少信息。
身份字段比详细描述更有用
一段日志如果只有时间和文本,跨进程的同一件事就无法关联。加入以下字段能显著提高可检索性:
1 | ts=2026-09-14T09:30:12.481+08:00 |
关键点是 task_id 与 request_id 贯穿所有层。上层任务、设备命令和设备侧反馈都带同一个标识时,事后可以把它们按时间排成一条链,而不需要在文本里猜哪个是相关的。
时间基准要统一并说明来源
不同进程使用不同的时钟来源,会让排列出来的顺序失去意义。至少要明确:时间戳来自哪个时钟、是否与外部时间同步、以及单位。
对于有超时逻辑的系统,记录单调时钟差值比记录墙上时间更可靠,因为墙上时间可能被同步步骤调整。需要跨机器比较时再记录同步后的墙上时间,并标注同步状态。
只记录墙上时间而不记录单调时间,会让那些“时钟跳变导致误判超时”的问题无法被发现。
状态转换比错误字符串更有解释力
只记录“ack 超时”只能说明发生了什么,记录状态转换才能说明系统当时如何理解这件事。上面的示例中 from、to 和 reason 三项组合,既能做统计也能做流程重建。
原因码建议使用可枚举的集合,而不是自由文本。自由文本适合补充细节,不适合聚合分析。一个稳定的原因码集合,能直接支持“这台设备最近两周最常出现哪种停止原因”这类问题。
高频路径上的日志要有限制
机器人程序里有一部分日志出现在高频路径上,例如每次控制周期或每帧处理。在这些位置无差别打印会改变时序,让原本要观察的性能问题被日志本身掩盖。
可行的做法是分层:正常路径只在状态变化时记录,异常路径按原因码记录并做限流,详细跟踪通过可运行时开启的开关控制。限流要在日志里显式说明“已丢弃 N 条”,否则事后无法知道记录是否完整。
和可复现性的关系
日志能让问题可解释,但不一定能让问题可复现。要复现,需要记录输入和环境:当时的配置、软件版本、以及关键输入数据是否被保存。
如果一次超时与某个传感器输入相关,而没有保存当时的输入,那么日志只能说明超时发生,无法重放。此时补充数据录制比增加日志更有效。两者是互补关系:日志说明发生了什么事,录制数据说明为什么会发生。
参考资料
证据边界
本文讨论日志字段设计与记录策略,不包含任何具体系统的日志样例数据。字段集合需要按要回答的问题裁剪;日志能证明系统当时如何判断,不能证明物理世界发生了什么,涉及执行器行为的结论仍需设备侧反馈或独立测量支持。