iT邦幫忙

2

[SRE×AI #06] 一次 Incident 調查的完整旅程:從 Log 到報告的 AI 協作實戰

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20260223/20181291IhyFSPd3um.png

調查花了 20 分鐘,寫報告又花了 1 小時。最痛的不是查問題,是把查到的東西整理成報告。


以下這份 RCA 報告,是我用 AI 產出的。

背景:Device Service 的註冊 API 每天冒出 3-6 筆 500 錯誤,持續一週以上。

你先看報告。看完再說它怎麼來的。


AI 產出的 RCA 報告


📋 Quick Summary

這段回答:一眼看完,發生了什麼事?

項目 內容
服務 Device Service — POST /device-service/v1/devices
問題 註冊 API 持續出現零星 500 錯誤
根因 Stored Procedure 的 Upsert 邏輯用錯欄位,導致 DB 寫入衝突
影響 每日 3-6 筆 500 錯誤(錯誤率 0.0001%),僅影響自動化批次系統
狀態 🟡 監控中,已確認根因,待 RD 修復

⏱️ Timeline — 發生了什麼事

這段回答:事情的經過,從頭到尾。

時間 事件
持續 7 天以上 Device Service 每天穩定出現 3-6 筆 500 錯誤(非突發,是常態)
Day 1 11:50 Grafana Dashboard 觀察到 500 spike(2 筆)
Day 1 14:53 SRE 啟動調查
↳ OpenSearch Access Log:確認每日 3-6 筆 500,錯誤率 0.0001%
↳ OpenSearch App Log:發現 DB duplicate key error
↳ 錯誤訊息:Cannot insert duplicate key row with unique index 'UK_hardware_id_valid'
Day 1 15:30 原始碼調查:確認 Stored Procedure Device_Upsert 的 IF EXISTS 使用錯誤欄位
↳ 根因確認:SP 用 record_id(流水號)判斷,應該用 hardware_id(設備唯一碼)

🔍 Root Cause — 為什麼發生

這段回答:問題的根本原因是什麼?

一句話:Stored Procedure Device_UpsertIF EXISTS 使用 record_id(每次請求都會產生新的流水號)判斷設備是否存在,而非使用 hardware_id(設備唯一碼),導致 Upsert 邏輯永遠走 INSERT 路徑。

因果鏈

https://ithelp.ithome.com.tw/upload/images/20260223/201812915wpBWYBH7q.png

sequenceDiagram
    participant Client as Client(自動化腳本)
    participant Go as Device Service(Go)
    participant SP as SP: Device_Upsert
    participant DB as Database

    Client->>Go: POST /devices(hardware_id: ABC-123)
    Go->>Go: 產生新的 record_id(流水號)
    Go->>SP: EXEC Device_Upsert @record_id=NEW, @hardware_id=ABC-123
    SP->>DB: IF EXISTS(WHERE record_id = NEW)
    DB-->>SP: 找不到(record_id 每次都是新的)
    SP->>DB: INSERT INTO device (...)
    DB-->>SP: ❌ UK_hardware_id_valid 違規(hardware_id 已存在)
    SP-->>Go: duplicate key error
    Go-->>Client: 500 Internal Server Error

簡單說:

  • record_id:流水號,每次請求都是新的
  • hardware_id:設備指紋,同一台設備永遠相同

SP 用 record_id 判斷 → 永遠找不到 → 永遠 INSERT → 撞到 unique constraint。

程式碼證據

-- ❌ 問題:用 record_id(每次都是新的流水號)判斷
IF EXISTS (
    SELECT 1 FROM [dbo].[device]
    WHERE [record_id] = @record_id    -- ← 應該用 hardware_id
    AND [is_valid] = 1
)
BEGIN
    UPDATE ...   -- 永遠走不到這裡
END
ELSE
BEGIN
    INSERT INTO [dbo].[device] (...)   -- 💥 撞到 unique constraint
    VALUES (...)
END

Table Schema

-- 主鍵是 record_id
CONSTRAINT [PK_device] PRIMARY KEY CLUSTERED (record_id ASC)

-- 但 Unique Index 是 hardware_id + is_valid
CREATE UNIQUE NONCLUSTERED INDEX UK_hardware_id_valid
    ON dbo.device (hardware_id, is_valid)

PK 和 Unique Index 用的是不同欄位。IF EXISTS 查 PK,但 constraint 卡的是另一個。


💥 Impact & Response — 影響多大、怎麼處理

這段回答:嚴不嚴重?目前怎麼應對?

指標 數值
每日錯誤數 3-6 筆(錯誤率 0.0001%)
持續時間 7 天以上(常態性,非突發)
受影響對象 自動化批次系統(非終端用戶,不影響設備功能)
目前狀態 🟡 監控中,待 RD 安排修復

建議修復方案

方案 A:修正 IF EXISTS 判斷欄位(推薦)

-- ✅ 改用 hardware_id 判斷
IF EXISTS (
    SELECT 1 FROM [dbo].[device] WITH(UPDLOCK, ROWLOCK)
    WHERE [hardware_id] = @hardware_id
    AND [is_valid] = 1
)
BEGIN
    UPDATE ...   -- 設備已存在 → 更新
END
ELSE
BEGIN
    INSERT INTO [dbo].[device] (...)   -- 新設備 → 新增
    VALUES (...)
END

方案 B:改用 MERGE(原子操作)

用 SQL MERGE 語法一步完成 Upsert,避免 IF EXISTS 的競爭條件。

方案 C:應用層處理

在 Go 層捕捉 duplicate key error,改回傳 409 Conflict 而非 500,改善錯誤語義。


✅ Action Items & Lessons Learned — 下一步 + 學到什麼

這段回答:接下來要做什麼?這次學到什麼?

Action Items

# Action Item Owner Priority
1 修正 SP Device_Upsert 的 IF EXISTS,改用 hardware_id 判斷(方案 A 或 B) RD Team Medium
2 檢查其他 SP 是否有類似的欄位誤用問題 RD Team Low
3 考慮應用層對 duplicate key error 回傳 409 而非 500 RD Team Low

Lessons Learned

  1. Upsert 判斷要用業務唯一鍵,不是 DB 主鍵 — 判斷「存不存在」,用業務邏輯的欄位
  2. 低頻錯誤也值得追 — 0.0001% 很容易忽略,但它是 100% 可重現的邏輯 bug,不會自己好
  3. Code review 加一條 — Upsert 的判斷欄位,是否和 unique constraint 一致?

(報告結束)


這份報告怎麼來的

調查過程:

  1. OpenSearch 查 log — 發現 DB duplicate key error
  2. Confluence 搜歷史 — 確認 API 設計意圖是 Upsert
  3. AI 分析 SP 邏輯 — 找出 IF EXISTS 用錯欄位

三個步驟,同一個對話,20 分鐘。

調查完,一句話:「根據剛才的調查,幫我產出一份 RCA 報告。」

2 分鐘後,你剛才看到的報告就出來了。

AI 已經有完整的調查上下文。不用重新解釋,直接整理成結構化報告。

產出後我花 5-10 分鐘 review — 確認事實、因果鏈、措辭。

從零寫:1-2 小時。Review + 微調:5-10 分鐘。


RCA 報告心法

工具再好,報告的品質最終取決於你的思維。

三個原則。

1. 不是找戰犯,是找系統性改善

「SP 用錯欄位」— 很容易寫成「開發者用錯了」。

但 Action items 該指向流程改善,不是指向個人。

AI 在這點有天然優勢:它不帶情緒,只描述事實和因果。

2. 讓不在場的人也能看懂

報告的讀者可能是老闆、其他團隊、三個月後的新人。

AI 產出的報告天然帶有「解釋性」— 它不會假設讀者知道所有背景。

這反而是人寫報告容易忽略的。我們太熟自己的系統,會不自覺跳過解釋。

3. 報告是給未來的團隊看的

三個月後類似問題又出現。你搜 Confluence,找到這份報告。

因果鏈、程式碼、修復方案,全部都在。不用重新調查。

這也呼應了 #04 — Confluence MCP 搜到的歷史,就是之前有人認真寫的報告。


結語

工具篇(#03-#05)教你怎麼查。

這篇教你怎麼把查到的東西,變成一份報告。

整個流程的時間對比:

階段 Before After
搜歷史 10 min 1 min
查監控 10-15 min 2-3 min
查 Log 20-30 min 5 min
分析根因 30-60 min 5-10 min
建 Ticket 30 min 2 min
寫報告 60-120 min 5-10 min
總計 ~3-4 hr ~25 min

上一篇缺了「寫報告」這一行。

現在補上了。

從調查到報告,完整了。

下一篇,我們要聊一個你可能已經發現的問題:

同樣的工具,問 AI 的方式不同,結果差很多。

怎麼問對問題?怎麼讓 AI 真正理解你的維運需求?

下一篇聊 Prompt 工程。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言