设备软件架构与控制模型(八):日志、诊断、审计与升级

设备交付以后,开发者面对的通常不是一个可调试的异常,而是一句话:“昨天夜班偶尔停了一次,重启后好了。”如果软件没有把命令、状态、设备观测和配置版本关联起来,现场只能靠猜;如果升级又缺少兼容检查和回退路径,一次修复还可能制造更大的停机。

本系列最后一篇把可维护性视为架构能力:日志、指标、追踪、报警和审计各自记录不同事实,诊断包把证据安全地带离现场,升级流程则让软件、Recipe、固件和数据结构能够协同演进。

1. 五类信息各司其职

类型回答的问题典型内容
日志(Log)某个时刻发生了什么命令接收、设备响应、异常与上下文
指标(Metric)一段时间内系统怎样变化周期时间、失败数、队列深度、温度趋势
追踪(Trace)一次操作经过了哪些组件UI 命令 → 流程 → 轴/相机 → 数据保存
报警(Alarm)现在需要人采取什么行动联锁未满足、位置未知、关键设备失联
审计(Audit)谁在何时改变了受控对象Recipe 发布、权限变更、维护复位、升级

日志不是审计日志,异常也不自动成为报警。把所有内容写进一个文本文件,会同时损害检索、保留策略和访问控制。

.NET 原生提供 ILoggerSystem.Diagnostics.MetricsActivitySource;OpenTelemetry 可以收集这些信号并导出到不同后端。是否部署集中式平台取决于现场网络和运维条件,但应用内部的事件结构与关联方式应尽早统一。半导体设备侧分级报警与可观测性落地的领域实践见《半导体设备软件(七):日志、报警与可观测性》。

2. 从一次操作的关联 ID 开始

每个外部命令生成或接收一个 CorrelationId,长流程再分配 RunId 和步骤 ID。它们应贯穿日志、状态转换、设备调用和结果数据:

1
2
3
4
5
6
CorrelationId = 01J5Z...
RunId         = RUN-20260817-0042
CommandId     = CMD-018827
Step          = Capture.TopCamera
Device        = Camera.Top
Recipe        = Product-A-Scan@17

关联 ID 用于串起证据,不代表鉴权或幂等。外部传入的值要校验长度和字符范围,日志中也不能无条件信任用户输入。

结构化日志保留字段语义,便于查询和聚合:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using Microsoft.Extensions.Logging;

public static partial class EquipmentLog
{
    [LoggerMessage(
        EventId = 2101,
        Level = LogLevel.Information,
        Message = "Command {CommandId} started on {DeviceId} for run {RunId}")]
    public static partial void CommandStarted(
        ILogger logger,
        string commandId,
        string deviceId,
        string runId);

    [LoggerMessage(
        EventId = 2102,
        Level = LogLevel.Error,
        Message = "Command {CommandId} failed with fault {FaultKind} ({VendorCode})")]
    public static partial void CommandFailed(
        ILogger logger,
        string commandId,
        string faultKind,
        string? vendorCode,
        Exception exception);
}

LoggerMessage 源生成器可以在编译时生成高效日志代码并提供诊断。事件 ID 要稳定,消息模板字段名也应保持一致;否则仪表盘和现场脚本会随着文字修改失效。

3. 日志要能解释状态转换

有用的状态日志至少包含:

  • 旧状态、新状态和触发事件;
  • 命令、运行和设备标识;
  • 守卫条件拒绝的明确原因;
  • 设备返回的原始码和稳定故障分类;
  • Recipe、校准、软件和固件版本;
  • 使用单调计时测得的持续时间。

不要在高频循环中无条件记录每次采样。可以把原始数据送入专门数据管线,把日志保留给状态变化和异常;趋势使用指标,特定故障前后的短窗口再通过环形缓冲保存。日志量控制不能简单丢弃所有 Information,应保证命令开始、状态转换和失败证据能够关联。

墙上时间用于跨系统对齐和审计,持续时间则应使用单调计时来源,例如 StopwatchTimeProvider.GetTimestamp(),避免系统时间校准造成负耗时。

4. 指标关注可行动的趋势

设备软件常见指标包括:

  • 命令和流程的成功数、失败数与耗时分布;
  • 当前命令队列深度、丢弃或等待次数;
  • 设备断连次数和恢复耗时;
  • 报警发生次数、持续时间和重复量;
  • 数据采集速率、处理积压与磁盘剩余空间;
  • 设备温度、压力等健康信号。

标签维度必须受控。把 RunId、序列号或完整错误消息作为指标标签,会产生近乎无限的时间序列;这些高基数字段应该进入日志或追踪。指标适合发现“最近一小时相机断连增加”,日志再回答具体是哪几次。

阈值不要凭经验写成通用常数。先采集基线,再结合设备规格、工艺窗口和响应流程定义报警条件,并记录适用版本。

5. 诊断包保存足够但不过量的证据

现场导出的诊断包可以包含:

  • 软件、操作系统、驱动、固件和硬件标识;
  • 当前状态快照与最近状态转换;
  • 生效的 Recipe/配置/校准版本及摘要;
  • 故障前后受限时间窗口内的日志与关键遥测;
  • 活动报警、原始错误码和通信统计;
  • 存储、内存和线程等运行健康信息;
  • 清单文件、生成时间和文件摘要。

默认不要包含凭据、私钥、访问令牌、完整客户数据和无限量原始图像。导出前执行脱敏,诊断包设置访问权限和保留期限;跨组织传输时按双方的数据规则处理。生成诊断包本身也要有容量上限,避免磁盘已满时再次写入大量数据。

6. 审计记录受控变更

以下动作通常值得审计:

  • 登录、角色和权限变更;
  • Recipe 的创建、审核、发布、激活和停用;
  • 校准与设备常数更新;
  • 报警禁用、阈值和优先级修改;
  • 维护模式、强制输出和故障复位;
  • 软件、驱动和固件升级。

审计事件记录操作者身份、动作、对象、旧值/新值或版本、时间、理由和结果。仅写“修改成功”无法还原变化。审计存储应限制修改和删除,并将时间同步异常本身纳入监控;具体保存期限由行业、合同和组织制度决定,不能从通用架构直接给出一个年限。

7. 升级是一项受控设备变更

一次升级可能同时改变应用、数据库、Recipe Schema、厂商 SDK 和控制器固件。升级包至少应明确:

  • 来源、版本、摘要或数字签名;
  • 支持的操作系统、架构、驱动和固件组合;
  • 配置与数据结构的迁移路径;
  • 升级前检查、预计停机和空间需求;
  • 安装后健康检查与验收步骤;
  • 可回退组件、回退前提和不可逆步骤。

“复制新文件覆盖旧目录”会让旧 DLL、配置和新程序混杂。更稳健的方式是部署到独立版本目录,停止控制入口,备份受控数据,执行迁移,再切换启动目标。切换是否能做到原子性取决于操作系统和部署机制,不能只凭重命名目录就假定整个升级事务原子。

数据库或固件迁移可能不可逆。此时所谓回退不能只恢复旧可执行文件,还必须有向前修复、数据备份恢复或整机维护方案。升级前应阻止新任务,等待当前任务到安全检查点,并记录设备实际状态。

8. 用健康检查决定是否接管设备

进程启动成功不等于升级成功。自动验证至少包括:

  1. 读取应用版本和部署清单;
  2. 加载并验证配置;
  3. 检查数据结构版本;
  4. 建立设备会话并核对身份/固件;
  5. 验证关键联锁和只读状态;
  6. 在允许条件下执行受控自检;
  7. 确认日志、数据和磁盘路径可写;
  8. 最后才允许进入 Ready

验证失败时,系统应保持不可生产状态并输出可诊断原因,而不是为了“服务已启动”强行忽略。对无人值守设备,还要验证 Windows Service、看门狗或外部监管器的重启策略不会形成无限崩溃循环。

9. 可维护性从设计阶段开始

日志字段、故障分类、配置摘要、命令 ID 和版本清单都依赖前几篇建立的边界。若 UI 直接调用 SDK、流程没有唯一 RunId、Recipe 可以运行中被修改,再先进的日志平台也只能收集互相矛盾的信息。

可以用一次“离线故障演练”检验体系:不给开发者远程调试权限,只提供诊断包、操作时间和现象描述,看能否还原使用的版本、命令路径、设备状态、首个根因和恢复动作。无法回答的问题,就是下一轮需要补充的可观测性需求。

总结

日志记录离散事实,指标显示趋势,追踪串起一次操作,报警要求人采取行动,审计保护受控变更。诊断包把这些证据以安全、有限的方式带离现场;升级则是一条包含兼容检查、迁移、验证和回退边界的设备变更流程。

至此,系列从职责边界出发,依次建立 HAL、生命周期、状态机与队列、Recipe、故障恢复、测试和可维护性闭环。它们共同指向同一个原则:上位机架构的核心不是界面有多少功能,而是每个命令、状态、参数、故障和资源都有清晰且可验证的所有者。

参考资料

Licensed under CC BY-NC-SA 4.0