Guidant AI v1.17.0 Release Note¶
| 項目 | 內容 |
|---|---|
| 版本 | 1.17.0(功能版號;主軸=系統紀錄能送進客戶自己的 log 平台——落地版客戶接 SIEM/集中 log 管理的第一塊拼圖) |
| 發布日期 | 2026-08-27 |
| 上一版本 | 1.16.0(2026-08-26) |
| 涵蓋區間 | 2026-08-26 ~ 2026-08-27(6d4ea5ee..2b15fbfd) |
| 涵蓋需求 | FR-068 系統 Log 轉發(Syslog RFC 5424 / GELF 1.1 × UDP/TCP、應用 log 與稽核事件兩流獨立開關、熱生效、測試送出、三家對接手冊)+ FR-065 升級路徑修補(--upgrade 拿舊 init image 套 migration 的假成功,CM-1407) |
| 規模 | BE 21 commits(feat 4/fix 7/docs・chore・test 10);FE 2 commits(feat 2);DB migration 2 支 |
| 適用部署 | 188 STG + 189 POC(皆為安裝版 docker stack,走 install.sh --upgrade) |
| 部署性質 | 含 2 支 DB migration(envs=*,由 init image 的 migrate 模式套用)。189 POC 為既有資料升級——只走升級模式、不重建庫。不走正式簽章(維持 --skip-prod-key-check,決策者裁示)。 |
0. 發版前回歸 gate¶
本版未執行 site-regression 自動 Core gate。理由與 v1.16.0 同:落地版 stack 形態的 E2E 套件尚未補齊,且本版變更面極窄——一張新設定頁+一支旁路 handler 鏈,不觸及既有任何業務流程。放行依據為 188 STG 上的實機驗收(設定頁可存、測試送出可達、三容器 healthy)與 189 POC 升級後的資料零損失逐項對照(見 §5)。自動化 gate 待落地版 E2E 套件補齊後於後續版本恢復。
1. 概述¶
v1.16.0 解決的是「客戶裝好之後,檢測能力怎麼覆蓋整個環境」;v1.17.0 解決的是「系統自己產生的紀錄,怎麼進到客戶既有的監控體系」。
落地版客戶(尤其合規客群)幾乎都已經有一套集中 log 平台——rsyslog、Graylog、或 ELK。在此之前,Guidant AI 的紀錄只留在自己的資料庫與容器 log 裡:客戶要看「誰登入了、誰改了什麼」,得另外開我們的畫面;資安團隊想把稽核事件送進 SIEM 做關聯分析,沒有任何介面可用。
本版讓系統管理員在畫面上填一組 host/port,就把紀錄送一份出去。兩條流各自獨立開關:
- 稽核事件流(帶
event_code的紀錄)——合規客群接 SIEM 的核心訴求,誰在什麼時候對什麼做了什麼。 - 應用程式 log 流——服務工程排錯集中化。
轉發是旁路:log server 連不上時,API 延遲無感、本機 log 與 system_logs 照常寫,被丟掉的只有「送出去的那一份」。這是刻意的設計取捨——log 轉發不該有能力拖垮主服務。
2. 重點新功能¶
2.1 FR-068 系統 Log 轉發(本版主軸)¶
一頁設定、兩種協定、兩條流。 系統管理 → 系統設定新增「Log 轉發設定」頁:
| 設定項 | 選項 | 說明 |
|---|---|---|
| 啟用 log 轉發 | 開/關 | 總開關,關閉時完全不對外送出 |
| 協定 | syslog(RFC 5424)/gelf(GELF 1.1) |
syslog 是 rsyslog/Graylog/ELK 三家最大公約數;GELF 給 Graylog 原生結構化欄位保真 |
| 傳輸方式 | udp/tcp |
UDP fire-and-forget;TCP 可確認連線 |
| Log 伺服器位址/連接埠 | — | 啟用時必填,port 1–65535 三層驗證(FE/domain/DB CHECK) |
| 轉發應用程式 log | 勾/不勾 | 流一:無 event_code 的紀錄 |
| 轉發稽核事件 | 勾/不勾 | 流二:帶 event_code 的紀錄([AUDIT:*]) |
熱生效,不必重啟服務。 存檔後處理該請求的進程立即重掛 handler 鏈;其餘 gunicorn worker 由各自的 watcher 執行緒在 30 秒內追上。存檔成功的 toast 會明說「其餘程序最多 N 秒跟上」——不讓使用者以為沒生效而反覆按。
測試送出按鈕。 用已儲存的設定送一筆固定訊息,驗連通性。表單有未存變更時按鈕反灰(否則測到的是舊設定,結論會誤導)。UDP 只驗得到「送出去了」不驗得到「對方收到」,文案如實說明。
主服務零阻塞。 handler 鏈掛在 stdlib 的 QueueHandler/QueueListener 之後,主執行緒只做入佇列;TCP 斷線靜默降級,不做重試風暴。
三家對接手冊。 使用手冊新增〈Log 轉發設定使用指南〉,含 rsyslog(收 UDP 514 的 conf 範例)、Graylog(GELF input 建法)、ELK(Logstash syslog input pipeline)各一段可直接照抄的配置。
3. 重要修補¶
3.1 CM-1407:--upgrade 拿舊 init image 套 migration 的假成功(FR-065,高風險)¶
這是本版最重要的修補,影響所有落地版客戶的升級路徑。
症狀:升級一個帶新 migration 的版本時,install.sh --upgrade 會印出「已套 N 支/待套 0 支」並一路回報成功、退出碼 0,但資料庫其實停在舊結構——新功能的表根本不存在。沒有錯誤訊息、沒有紅字。
根因:compose 的 init 服務寫的是 image: guidant-ai-init:${GUIDANT_VERSION:-latest},而升級第④步(套 migration)讀的 --env-file 指向主機 .env,版號要到第⑤步才寫新值。於是第④步拿舊版 init image 去套新版 migration——舊 image 內烤的 manifest.tsv 沒有新增那幾支,migrate.sh 據此算出「待套 0 支」,然後誠實地回報成功。凡新版帶新 migration,第一次 --upgrade 都會靜默漏套。
修法(三層):
- 套 migration 的兩次 compose 呼叫顯式帶
GUIDANT_VERSION=${NEW_VERSION}(compose 變數優先序是 shell 環境 >--env-file,前綴帶值即可蓋掉,與同一行的GUIDANT_INIT_MODE同一機制,不新增概念)。 - 新增收工斷言
upgrade_verify_migrations_at_head():套完後再跑一次 dry-run,要求輸出含「待套 0 支」才放行——不信任migrate.sh的退出碼。這是 CM-1404「驗烙印不等於驗 schema」同一教訓的第二次落地:回傳 0 的意思只是「它認為該做的都做完了」,而它認為該做什麼,取決於它自己那份 manifest。 - 套 migration 前先
docker image inspect確認新版 init image 在本機。缺了的話 compose 會轉去 registry 拉,封閉網路只會得到一句無關的 pull 失敗,完全不指向「出貨包沒帶這顆 image」。
同類問題盤點:compose 內其餘 ${GUIDANT_*} 皆為連線/路徑類(DATA_DIR/DB_*/REDIS_*/PORT),升級前後不變,讀舊 .env 無害。唯一與版號連動的 ${GUIDANT_VERSION} 出現在 be/fe/init 三處 image tag,其中 be/fe 只在第⑤步(sed 之後)被用到、時序正確;init 是唯一在 sed 之前就被使用的,即本次修正處。無其他步驟受同一根因影響。
3.2 CM-1408:syslog/GELF 送出的內容不合規範¶
分兩次修完,症狀都是「客戶的 log server 收得到但解析不出來」:
- syslog 改合 RFC 5424:關掉 Python
SysLogHandler預設的 NUL 結尾(append_nul),時戳改真 UTC(原本送容器本地牆鐘,收端時序全亂)。 - HOSTNAME/host 欄位改用站台位址:原本送的是容器 ID(每次重啟就變一組亂碼),收端無法把紀錄歸戶到哪套系統。syslog 的 HOSTNAME 與 GELF 的
host兩個欄位分兩次修完(後者是前者漏掉的另一半)。
3.3 CM-1409:log 轉發頁被授權機制誤標「未授權」¶
新頁面預設落入 license 唯讀降級判定,畫面顯示未授權而不可編輯。log 轉發屬基礎設施類功能(與 SMTP/LDAP 同性質),不隨業務模組授權浮動,補進基礎設施豁免清單。
3.4 CM-1410:未上線的「敏感資料遮罩」開關不再曝光¶
設計上(D5)第一版不做內容過濾、僅預留架構掛點,UI 原以 disabled 形式佔位。決策為未上的功能不在 UI 曝光——masking_available 恆 false 時整塊不渲染。SPEC 與使用手冊同步移除該段描述。
4. Breaking Changes¶
無。本版為純新增:一張新表、一組新 API、一個新選單項,不改動任何既有欄位、端點或行為。
5. DB Migration¶
2 支,皆 envs=*(客戶端 migrate 模式會套用):
| 檔 | 內容 |
|---|---|
2026-08-25-fr068-1-log-forwarding-settings.sql |
新表 config.log_forwarding_settings(全域一列,tenant_id NULL=全域、預留租戶層擴充)+ log-forwarding.{read,update} 兩個能力點 |
2026-08-27-fr068-2-log-forwarding-menu-route.sql |
選單登記:ui_routes 掛 group-system-config sort=35 + route_capabilities 綁上述兩能力點 |
出貨基線同步:本版重跑了 gen_schema_sql.sh 與 gen_stamp_sql.sh,scripts/init/ 的 02-schema.sql/99-stamp.sql 已含 FR-068 兩支,marker 為 __init_baseline_v1.17.0__。全新安裝與升級兩條路徑皆已對齊本版。
6. 部署順序¶
落地版 stack(188 STG/189 POC)走標準升級路徑:
四步依序為:① pg_dump 全量備份(失敗即中止,不裸升)→ ② docker load 三顆 image + digest 比對 → ③ 套增量 migration(dry-run 印清單 → 實際套用 → 再 dry-run 斷言「待套 0 支」)→ ④ 改 GUIDANT_VERSION + up -d,等 healthcheck 全綠。
§3.1 的修補在第③步生效:本版是該修補的首次實戰。升級 log 會出現「資料庫已與本版對齊(待套 0 支)」這一行,那是新增的收工斷言在說話——沒有這一行代表用的是舊版 install.sh。
7. 相依套件版本¶
無變動。evidence-agent 維持 0.2.30。
8. 已知 follow-up¶
| 項目 | 說明 |
|---|---|
| 敏感資料遮罩 | 架構掛點已預留(轉發 handler 前的 filter 鏈),內建預設規則組(IPv4/email/token 形狀)與 UI 開關待後續版本。第一版信任邊界在客戶內網,手冊已註明 |
| agent log 轉發 | 本案不做(決策者裁示)。未來另案時,agent 端沿同一設定下發形狀 |
| 租戶層設定 | 資料結構已預留(tenant_id 可空、讀取 helper 單點),目標客群偏落地版(一客戶一套)故第一版只做全域 |
| 正式簽章 | 本版三顆 image 維持 --skip-prod-key-check(決策者裁示)。正式鑰進 image 前需先完成 PUBLIC_KEYS commit(沿用 FR-062 待辦) |
| site-regression gate | 落地版 stack 形態的 E2E 套件補齊後恢復(見 §0) |
9. 相關文件索引¶
| 文件 | 路徑 |
|---|---|
| FR-068 設計定案(D1–D6) | docs/features/FR-068-2608-log-forwarding/design.md |
| 頁面 SPEC | docs/specs/v1.17.0/system-admin/log-forwarding.md |
| 使用手冊 | docs/user-manual/log-forwarding-guide.md(三家對接範例) |
| 升級路徑修補脈絡 | scripts/installer/install.sh(upgrade_apply_migrations 段的行內註解)|scripts/init/README.md(「出包必驗裝機後 schema 到 head」段) |