MySQL DB LogWriter / TraceStore 邊界設計

返回

MySQL DB LogWriter / TraceStore 邊界設計

1. 文件目的

本文件承接 MySQL TaskStore command_executions 實作前確認,整理詳細診斷資料是否應由 DB LogWriter / TraceStore 承接,而不是直接塞入 MySqlTaskStore.Save(record)

本文件只做邊界設計,不新增 table、不執行 DDL、不連真實 DB、不修改 ITaskStore / ILogWriter public method 簽章,也不修改 TaskExecutionRecord / TaskNodeExecutionRecord public constructor 或 property。

2. 目前已完成狀態

項目 狀態 說明
task_executions 已完成 MySqlTaskStore 已可保存任務主檔,並完成真實 DB manual-only 驗證。
node_executions 已完成 MySqlTaskStore 已可保存節點摘要,並完成真實 DB manual-only 驗證。
command_executions 尚未實作 已完成實作前確認,結論是不宜在資料來源未固定前直接塞入 TaskStore。
LogEntry 已存在 已包含 TaskId、NodeId、DeviceId、CommandName、RawRequestSummary、RawResponseSummary、AdapterTimeTakenMs、DataSummary、MetadataSummary、ErrorCode、Message。
ILogWriter 已存在 目前可由 Console / File / Memory writer 接收 LogEntry
WorkflowEngine 已承接 Adapter Data 已把 Adapter result 的 RawRequest / RawResponse / Data / Metadata 轉成 summary 寫入 LogEntry

3. 核心邊界結論

MySqlTaskStore 與 DB diagnostic log 應拆開。

元件 職責 不應負責
MySqlTaskStore 保存任務主檔與節點摘要,例如 task_executionsnode_executions 不保存完整診斷 log、不承擔 Raw payload 清理、不當作一般 log sink。
MySqlLogWriter LogEntry 安全轉成 DB trace row。 不改變 Workflow 結果、不取代 Console / File log、不直接執行 schema apply。
TaskTraceStore 提供依 TaskId、NodeId、DeviceId、時間區間查詢 trace 的讀取介面。 不負責任務狀態轉換、不寫入 Workflow 核心狀態。
task_log_traces 保存任務與設備命令相關診斷摘要。 不替代 task_executions / node_executions / command_executions

4. 為什麼建議走 Log 流

command_executions 若要保存 RawRequest / RawResponse,最完整的資料目前已在 LogEntry 與 Workflow snapshot 流中。

LogEntry -> MySqlLogWriter -> task_log_traces 的優點:

  1. 不需要為了診斷欄位修改 TaskExecutionRecord / TaskNodeExecutionRecord public model。
  2. 不會讓 MySqlTaskStore.Save(record) 同時承擔任務保存與大量 log sink。
  3. 可以獨立做 payload 遮蔽、長度限制、保留天數與查詢索引。
  4. DB log 寫入失敗時,可獨立處理,不必改變 Workflow 任務成功或失敗判斷。
  5. 未來若一個 node 執行多個 Adapter command,Log 流比 TaskStore node summary 更適合承接多筆診斷事件。

5. 建議資料流

WorkflowEngine
  -> LogEntry
  -> ILogWriter
      -> ConsoleLogWriter
      -> FileLogWriter
      -> MemoryLogWriter
      -> MySqlLogWriter
            -> task_log_traces

TaskTraceStore
  -> query task_log_traces by TaskId / NodeId / DeviceId / time range

第一版建議 MySqlLogWriter 是可選 writer,不得取代既有 Console / File / Memory writer。

6. 建議 table 定位:task_log_traces

task_log_traces 應定位為「診斷 trace table」,不是任務主檔,也不是命令執行表。

6.1 欄位草案

以下只是設計草案,尚未確認前不得建立 table。

欄位 型別 必填 來源 說明
trace_id varchar(64) 寫入端產生 Trace 主鍵,避免依賴 DB 自動編號造成測試不易比對。
task_id varchar(64) LogEntry.TaskId 任務識別碼。
node_id varchar(64) LogEntry.NodeId Workflow 節點識別碼。
node_name varchar(128) LogEntry.NodeName Workflow 節點名稱。
device_id varchar(64) LogEntry.DeviceId 設備識別碼。
command_name varchar(128) LogEntry.CommandName Adapter 命令名稱。
level varchar(32) LogEntry 或 writer mapping Log level,第一版可先以 Info / Warning / Error 表示。
status varchar(32) LogEntry.Status 任務、節點或命令狀態。
retry_count int LogEntry.RetryCount 節點 retry count。
time_taken_ms int LogEntry.TimeTakenMs 節點或事件耗時。
adapter_time_taken_ms int LogEntry.AdapterTimeTakenMs Adapter 命令耗時。
error_code varchar(64) LogEntry.ErrorCode 錯誤代碼。
message varchar(255) LogEntry.Message 訊息摘要。
data_summary text LogEntry.DataSummary Adapter Data 摘要。
raw_request_summary text LogEntry.RawRequestSummary 已遮蔽與截斷後的 request 摘要。
raw_response_summary text LogEntry.RawResponseSummary 已遮蔽與截斷後的 response 摘要。
metadata_summary text LogEntry.MetadataSummary Metadata 摘要。
host_name varchar(128) Host context 執行主機名稱。
operator_id varchar(64) Host context 操作者或服務帳號。
app_version varchar(64) Host context 程式版本。
created_at datetime 寫入當下 Trace 建立時間。

6.2 建議索引

Index Columns 用途
idx_task_log_traces_task_id task_id 查詢指定任務完整 trace。
idx_task_log_traces_node_id node_id 查詢特定節點 trace。
idx_task_log_traces_device device_id 查詢設備相關 trace。
idx_task_log_traces_command command_name 查詢命令相關 trace。
idx_task_log_traces_status status 查詢失敗或特定狀態 trace。
idx_task_log_traces_error_code error_code 查詢特定錯誤。
idx_task_log_traces_created_at created_at 依時間排序與清理。

7. MySqlLogWriter 寫入策略

第一版建議:

  1. MySqlLogWriter 只接收已產生的 LogEntry,不主動改 Workflow 狀態。
  2. 寫入前必須經過 payload sanitizer,避免保存 password、token、connection string 或完整敏感 payload。
  3. RawRequestSummary / RawResponseSummary 只保存摘要,不保存未遮蔽完整原文。
  4. 單筆寫入失敗時,不應讓 Workflow 任務結果由成功變失敗;但必須讓 host 或 fallback log 知道 DB log 寫入失敗。
  5. 第一版不做批次寫入、不做背景佇列、不做 retry worker,避免擴大到背景服務範圍。
  6. 第一版不自動建表,也不在 ConsoleHost 啟動時 apply schema。

8. TaskTraceStore 查詢策略

TaskTraceStore 建議作為讀取介面,不與 ITaskStore 混在一起。

建議第一版查詢能力:

查詢 用途
FindByTaskId(taskId) 查詢單一任務完整 trace。
FindByNodeId(taskId, nodeId) 查詢指定任務節點 trace。
FindByDeviceId(deviceId, from, to) 查詢設備在時間區間內的 trace。
ListRecentErrors(limit) 查詢最近錯誤 trace。

以上查詢介面若要實作,會新增 public contract,必須另做實作前確認。

9. 與 command_executions 的關係

task_log_tracescommand_executions 不應互相取代。

Table 建議定位
command_executions 給報表或任務明細查詢使用的命令執行表,欄位較固定。
task_log_traces 給除錯與診斷使用的 log / trace 表,資料量較大,欄位偏診斷。

目前建議先做 task_log_traces 邊界設計,是因為 RawRequest / RawResponse 較接近診斷資料,不宜為了它先修改 TaskStore model。

若後續需要 command_executions,可以從 LogEntryWorkflowNodeExecutionSnapshot 派生,但必須先做資料來源決策表。

10. Payload 安全規則

DB trace 不能直接保存未處理的 raw payload。

第一版 sanitizer 至少應處理:

規則 說明
長度限制 request / response summary 建議限制在固定字數,例如 2,000 或 4,000 字內。
敏感字遮蔽 password、token、secret、connection string、authorization 需遮蔽。
二進位摘要 若 payload 是 byte array,只保存 hex 摘要與長度,不保存完整大 payload。
Null 安全 沒有 raw data 時保存 null,不硬塞空字串。
錯誤可讀性 遮蔽後仍需保留足夠資訊判斷命令、裝置與錯誤原因。

11. 測試策略

11.1 自動測試

測試 目的
LogEntry to trace row mapper 測試 確認欄位來源正確,Raw summary 不遺失。
payload sanitizer 測試 確認敏感資訊被遮蔽,長字串會截斷。
SQL generator 測試 確認 task_log_traces schema class 可產生 MySQL 5.6.2 DDL preview。
fake gateway writer 測試 確認 MySqlLogWriter 寫入正確 SQL 與參數,不連真實 DB。
writer failure 測試 確認 DB log 寫入失敗不會改變 Workflow result。

11.2 manual-only 真實 DB 驗證

若後續完成實作,真實 DB 驗證需另列節點,且只能在使用者明確確認後執行:

  1. 確認測試 DB 與 table 已準備完成。
  2. 明確開啟 manual-only gate。
  3. 寫入成功、失敗、含 Raw summary、含 ErrorCode 的 trace rows。
  4. 依 TaskId 查回 trace。
  5. 驗證 index 與 comment。
  6. 驗證敏感資訊未被保存。
  7. cleanup 僅清除本次測試前綴資料。

12. 必須停下確認的事項

以下任一項出現時,Codex 必須停下,不得自動執行:

  1. 新增或修改 public contract,例如 ILogWriterITaskStoreTaskTraceStore 介面。
  2. 修改 TaskExecutionRecord / TaskNodeExecutionRecord public constructor 或 property。
  3. 建立 task_log_traces table 或執行任何 DDL / ALTER。
  4. 對真實 DB 執行未確認的 INSERTUPDATEDELETE
  5. 把真實 DB 測試加入一般 CI。
  6. 保存 password、Token、完整 connection string 或未遮蔽 RawRequest / RawResponse。
  7. 導入背景佇列、ServiceHost、WebApi 或正式 DB 自動 apply 流程。
  8. 新增或更換 MySQL 套件。
  9. 讓 DB log 寫入失敗直接改變 Workflow 任務成功 / 失敗結果。

13. 建議結論

建議採用「TaskStore 保存任務與節點,DB LogWriter 保存診斷 trace」的切分。

目前不要把 command_executions 或詳細 Raw 診斷資料直接塞進 MySqlTaskStore.Save(record);較安全的下一步是做「DB LogWriter / TraceStore 實作前確認」,先固定:

  1. task_log_traces schema class。
  2. LogEntry to trace row mapper。
  3. payload sanitizer 規則。
  4. fake gateway 測試策略。
  5. DB log 寫入失敗時的 fallback 行為。

確認後再進入第一版實作,仍維持不自動連真實 DB、不自動建表、不修改現有 TaskStore public contract。