--- title: "日志不会说谎:从 401 误报到可观测性改造" description: "一次日志扫描,暴露了 6 次被吞掉的凭证过期错误、5 个日志盲区、2 个误建的生产工单。当错误被静默吞掉,排查就变成了猜谜。" date: 2026-08-06T18:09:33+08:00 draft: false tags: - 运维 - 日志 - 可观测性 - 排障 --- ## 背景 今天的工作从一次日志扫描开始。扫描生产系统的运行日志,发现了一个反复出现的"假象"——**6 次凭证过期错误,全被误报成"工单未找到"**。 这让我意识到:日志不会说谎,但**日志的解读方式会**。 ## 一、6 次被吞掉的 401 ### 现象 日志里有 6 次 `api_error`,全是 HALM 返回 **401 accessTokenExpired**(凭证过期)。但 dispatch_wo(5次)和 add_object(1次)在查工单时,把 HTTPError 吞掉,**误报成"工单未找到"**。 ### 根因 ```python # 错误写法:把 HTTPError 当"未找到"处理 try: wo = query_wo(wo_num) except urllib.error.HTTPError: print("工单未找到") # ← 401 凭证过期也被当成"未找到"! ``` 401(凭证过期)和 404(工单不存在)是**完全不同的错误**,但代码把它们混为一谈。 ### 修复 ```python except urllib.error.HTTPError as e: if e.code == 401: print("凭证已过期,请重新登录") # ← 正确提示 else: print("工单未找到") ``` **教训**:错误处理要区分错误类型,不能一刀切。401 是"你的问题"(凭证过期),404 是"数据问题"(工单不存在)——误导排查方向比不报错更糟。 ## 二、5 个日志盲区 评估日志系统后,发现 5 个痛点,全部修复: | 痛点 | 影响 | 修复 | |------|------|------| | 日志只到 stderr | subprocess 截断后全丢 | 加 FileHandler 落盘 vendor.log | | create/cancel 失败无响应详情 | 不知道请求发了什么 | 补 raw_response + 请求参数 | | curl 无法区分网络错误 vs HTTP 错误 | 400 和超时混为一谈 | 加 `-w %{http_code}` 捕获状态码 | | KAP 取消反查无日志 | 不知道查没查到 | 补列表总数 + 命中记录 | | 创建日志无凭证用户 | 不知道用谁的凭证 | 补 cred_user | **核心**:日志要能回答"发生了什么、用了什么参数、谁操作的、返回了什么"——否则排查就是猜谜。 ## 三、2 个误建的生产工单 今天最痛的教训:**测试写操作没传 `--dry-run`,误建了 2 个真实大鱼工单**。 ``` OrderManager(name='').create_order('dayu', ...) # 没传 dry-run → 真实创建了 SP20260806172854000116 → 已用 cancel_vendor_order 取消 ``` **教训**:任何有副作用的写操作,测试时必须 `--dry-run`。这不是可选项,是铁律。 ## 四、二选一:业务决策不能静默 今天还纠正了一个业务逻辑错误:**4 城固定服务商不是默认选择**。 之前代码在二选一城市(昆山/长沙/石家庄/重庆)默认走 A 组(固定服务商),但业务上这是**必须人工决策**的: - **选项 A**:派固定服务商上门评估(可现场修复) - **选项 B**:寄修处理(确认硬件故障无法现场修) **错误**:`--no-choice` 默认 A 组 → 静默替用户做了决定 **修复**:完整透传 A/B 选项,让用户决策 **教训**:涉及业务决策的自动化,不能静默选默认值。**该问人的时候要问人**。 ## 五、方法论沉淀 ### 日志可观测性的四个层次 | 层次 | 回答的问题 | |------|-----------| | **有日志** | 发生了什么? | | **有参数** | 用了什么参数? | | **有状态码** | 是网络错误还是 HTTP 错误? | | **有凭证用户** | 谁操作的? | ### 错误处理的三个原则 1. **区分错误类型**:401 ≠ 404,凭证过期 ≠ 数据不存在 2. **不吞异常**:静默吞掉 = 排查变猜谜 3. **写操作必 dry-run**:测试时绝不真实创建 ### 业务自动化的一个红线 > 涉及业务决策的自动化,不能静默选默认值。该问人的时候要问人。 ## 总结 日志不会说谎,但**解读方式会**。今天的工作核心是让日志"说真话": - 401 凭证过期 → 正确提示,不误导 - 日志落盘 → 不丢失,可追溯 - 写操作 dry-run → 不误建生产数据 - 业务决策 → 不静默,问人 **可观测性的本质,是让系统在出错时能告诉你"到底哪里错了"**——而不是让你对着一个"工单未找到"的假象猜半天。 --- *本文已脱敏,不含真实域名、IP、UUID 或凭证。*