FR-133 · 需求討論稿 · 2026-10-09(v2 · D1~D8 全部定案)
Bugsink 打進安裝包,裝機全自動設好,後端與前端錯誤都收得到
產品要進客戶 UAT(使用者驗收測試),客戶環境不受我們控制。出錯時要在客戶自己的機器上就看得到:錯在程式哪一行(堆疊)、當下變數值、誰踩的、哪一筆請求。決策者選定 Bugsink(單一容器、與 Sentry SDK 相容的錯誤追蹤站)隨產品出貨,裝機時自動建好帳號、專案與連線字串,裝機人員不必開任何畫面、不必輸入任何東西。本稿盤點現況四個缺口、記錄已定案的八項決策與連線面,並拆成六棒。
整案一句話:每套 Guidant AI 都自帶一個錯誤追蹤站,裝好就能用;後端與前端的程式錯誤自動送進去,業務性的「使用者打錯」不送。
給非工程讀者的背景:程式出錯時,工程師要知道錯在哪一行、當時變數是什麼值、是誰、在做什麼。錯誤追蹤站(Error tracking,像一個專收錯誤報告的信箱網站)會把同一種錯誤歸成一條、附上這些資訊。後端已經會「寄信」,缺的是每個客戶機器上要有一個收信的站,以及「哪些該寄、哪些不該寄」的篩選。
六棒,A 與 B0 先跑、可平行
A(過濾開關)與 B0(Bugsink 實測)互不相干,可同時開工。B 等 B0 的實測結果;C、D 等 B;E 收尾文件等全部。
| 棒 | 做什麼 | 產出 | 完成怎麼判定(決策者檢查法) |
|---|---|---|---|
| A 過濾開關 | 業務錯誤(打錯密碼、查無資料這類 4xx)預設不送站台;logger.error 那一行 log 預設不另開一條,只當附帶紀錄 |
兩個環境變數、jedi-log 1.3.4、後端釘新版 | DEV 開著站台,故意打錯密碼登入三次 → 站台一條都不出現;再故意打一支會 500 的 API → 站台只出現一條,不是三條 |
| B0 可行性實跑 | 在 DEV 起 Bugsink 2.6.1,實測「用指令建專案 → 讀出連線字串 → 後端送得進去 → 用 API 讀得回來」整條,另外必測三件:站台能不能掛在 443 的子路徑、前端錯誤經後端轉送進不進得去、主機名從哪讀與改了會怎樣 | 一段可直接搬進 install.sh 的 shell 片段+實測紀錄(含子路徑通或不通的結論) | 打開實測紀錄,清單九項每項都有實際輸出貼在上面;照片段在空白機器重跑一次,站台上看得到後端送進來的錯誤 |
| B 進出貨包 | 安裝包多帶一顆 Bugsink;首次安裝自動建管理員、專案、連線字串;升級時缺了才補;維運指令加清理與改密碼 | compose、bundle、install.sh、guidantai 子命令 | 拿新包在乾淨機器裝好 → 瀏覽器開 https://<主機>/bugsink/(B0 子路徑測不通時改 https://<主機>:8443)用管理員登入,看得到 guidant-ai 專案 → 在產品故意打一支會 500 的 API → 一分鐘內站台出現該筆,點進去有堆疊 |
| C 前端錯誤接回 | 前端的程式錯誤經後端一支「登入後才能打」的轉送端點送進同一個站,帶版號與 commit,能跟後端那一筆串起來 | FE 接線、後端轉送端點、登入後端點多帶 DSN 一欄 | 登入產品後在瀏覽器故意觸發一個前端錯誤 → 站台出現該筆,版本欄有版號+commit、有 request_id;登出狀態下打轉送端點回 401 |
| D 診斷包改用 Bugsink API | 診斷包撈錯誤事件改打 Bugsink 自己的 API | diag_event_fetcher.py 改寫 |
在客戶機器跑一次診斷包匯出 → 解開包,錯誤事件那一份有內容,與站台上看到的一致 |
| E 文件 | 設定範本、部署文件、客戶手冊、release note | 四份文件 | 客戶手冊裡找得到「站台怎麼進、密碼在哪、事件保留多久、改設定後要用 start 不是 restart」四件事 |
依賴:A、B0 平行 → B → C、D 平行 → E。
後端錯誤追蹤的接線已存在,v1.26.0 起 sentry-sdk(送錯誤報告的程式庫)隨包內建:
| 落點 | 現況 |
|---|---|
主專案 core/plugins/api_log.py:234 |
init_error_tracking() 讀環境變數 SENTRY_DSN(DSN=連線字串,告訴程式錯誤要送去哪個站、哪個專案),交給 jedi-log 套件 |
jedi-log 1.3.3 jedi_api_log/error_tracking/__init__.py |
真正初始化 SDK 的地方 |
| 三個後端容器 | api/socketio/worker 都經 create_app 走同一條,一次接好三個都生效 |
遮罩 masking.py |
送出前先過濾:憑證欄位遮掉、四支敏感 headers 整支拿掉、堆疊裡的區域變數也掃 |
| 節流 | 每分鐘 60 筆(ERROR_TRACKING_RATE_LIMIT) |
遮罩與節流都在「送出前」(before_send)做,跟收的站是哪一套無關——換成 Bugsink 不必重做。
🔴 缺口一:一次登入失敗,站台上變三條
打錯一次密碼,站台會出現三條不同的 issue(issue=站台上歸成一類的錯誤):
login_domain_service.py:143 的 logger.error——SDK 的 logging 整合會把 error 等級的 log 當成獨立事件UnauthorizedError 這個例外本身handler.py:62 錯誤處理器再 logger.error 一次不只登入:jedi_common/handler/exception.py 的 ClientError 家族八種(BadRequest/Unauthorized/Forbidden/NotFound/MethodNotAllowed/Conflict/PreconditionFailed/TooManyRequests)全部會進站台。UAT 時使用者的正常操作失誤會淹掉真正的程式錯誤,還會吃光每分鐘 60 筆的節流額度——真的 500 反而送不進去。
🔴 缺口二:前端錯誤回報已整個拆掉
2026-10-05 資安項 U3-⑤(CM-2495,FE 7e136266、BE 4b3a04334)拆掉了前端的 @sentry/vue。原因:連線字串由免登入端點 /client-config 供給,另有免登入的 /error-tunnel 轉送器,兩者被判為任何人不用登入就能打的攻擊面。守衛測試 test/security/code/test_version_module_no_error_tracking_endpoints.py 擋這兩支復活。
所以前端接回時不能走原路,見 D4。FR-071 設計稿(design.md 第 247、341、650 行附近)有「前端 release 帶版號+commit、用 trace 標頭串前後端」的做法可沿用。
缺口三:診斷包撈事件的 API 對不上
infra/support/diag_event_fetcher.py 是對著 GlitchTip 的 Sentry 式 API(/api/0/organizations/<org>/issues/)寫的。Bugsink 的讀取 API 不是這個形狀(見下節),要改寫。
缺口四:改了設定用 restart 不會生效
POC(189)實例:在 guidant.env 加了 SENTRY_DSN 後跑 guidantai restart,不生效。原因是 restart 底層是 docker compose restart,只重啟容器、不重讀設定檔;要用 guidantai start(up -d,會重建容器)。FR-132-STATE.md 第 19 行與 release note v1.26.0 §2b 的寫法要修正。
| 面向 | 事實 |
|---|---|
| 版本與大小 | image bugsink/bugsink:2.6.1(2026-09-25),amd64 壓縮約 78 MB,多架構 |
| 組成 | 單一容器,自帶背景處理程式(monofy 同時跑網站 gunicorn 與背景 snappea),不需要 Redis |
| 執行身分 | 基底 python:3.12-slim,uid 14237,資料目錄 /data |
| 資料庫 | DATABASE_URL=postgresql://...,Postgres ≥ 14 |
| 佇列 | snappea 的工作佇列是 SQLite,寫死在 /tmp——容器重啟會丟掉還沒處理完的事件 |
| 必填設定 | SECRET_KEY(≥ 50 字)、BASE_URL(決定 DSN 長相,不可有結尾斜線) |
| 反向代理 | 要送 Host/X-Forwarded-Proto/X-Real-IP 三個 header,設 BEHIND_HTTPS_PROXY=True;上傳上限 client_max_body_size ≥ 20M |
| 管理員 | CREATE_SUPERUSER=email:password,只在資料庫裡還沒有任何使用者時建 |
| 專案與 token | 沒有建專案的指令或環境變數(官方 issue #240 開著無回應);API token 官方只能從畫面建 |
| DSN 組成 | build_dsn(BASE_URL, project.id, sentry_key.hex);sentry_key 是建專案時產的隨機 UUID,可從資料庫讀出 |
| 註冊 | USER_REGISTRATION=CB_NOBODY 關閉自行註冊;SINGLE_USER=True 為單人模式 |
| 保留 | 每專案預設 1 萬筆(smart retention,依重要性挑留);MAX_EVENT_AGE_DAYS 需另排程跑 bugsink-manage vacuum |
| 速率限制 | 預設 5 分鐘 1000 筆 |
| 讀取 API | /api/canonical/0/:issues/?project=、events/?issue=、events/{id}/stacktrace/;Bearer token;2.6.0 起 token 帶權限(issues:read/events:read)。Sentry 相容的只有「收事件」那一面 |
| 收事件 | /api/<project_id>/envelope/,相容 sentry-sdk 2.x;跨網域(CORS)只知 1.3.0 起有支援,細節查不到 |
| 告警 | 觸發:新 issue/舊錯誤復發/取消靜音;管道:Email(SMTP 變數)、Slack/Teams/Telegram/自訂 webhook;ALERTS_WEBHOOK_DENY_NON_GLOBAL 預設擋內網 webhook |
| 升級 | 容器啟動時自動跑資料庫遷移,換 tag 即可;健康檢查 /health/ready,image 內建 HEALTHCHECK 寫死 8000 埠 |
| 授權 | PolyForm Shield 1.0.0:可商用散布,不得拿去做與 Bugsink 競爭的產品 |
以下全部已拍板,本段為記錄,本案沒有待決策項。
共同原則:客戶防火牆常只開 443,所以客戶需要連的東西一律走 443,不要求客戶多開 port。
| # | 決策 | 內容 | 理由 |
|---|---|---|---|
| D1 | 自動建專案的做法 | 用 bugsink-manage shell 跑 Django ORM(Bugsink 內部的資料存取層)建 team/project/API token;DSN 用 SQL 從資料庫讀出,寫進 guidant.env 的 SENTRY_DSN |
官方沒有建專案的指令。跟著 Bugsink 自己的資料模型走,比直接寫 SQL 插資料穩,版本升級時欄位異動由它自己吸收 |
| D2 | 站台位址 | 優先掛在 443 的子路徑 https://<客戶主機>/bugsink/(nginx 轉給容器);備案才對外開 8443(BASE_URL=https://<客戶主機>:8443),兩者都沿用 stack 既有 HTTPS 憑證。Bugsink 的 BASE_URL 會推導 FORCE_SCRIPT_NAME(Django 用來支援子路徑的設定),代表有子路徑支援但未實證——B0 必測,測通就不開 8443,測不通才退 8443 並在手冊寫明要客戶開 port |
客戶不必多開 port;8443 留作退路,不讓子路徑的不確定性卡住整案 |
| D3 | 授權 | PolyForm Shield 可接受,不過法務 | 本產品是合規管理系統,不是錯誤追蹤產品,不構成競爭 |
| D4 | 前端錯誤怎麼送 | 一律走後端轉送,不做瀏覽器直送。FE @sentry/vue 設 tunnel(SDK 的轉送選項)指向後端一支登入後才能打的端點,後端原樣轉給 Bugsink 容器(docker 內網直連)。DSN 由登入後既有端點的回應多帶一欄取得。不復活免登入的 /error-tunnel//client-config,守衛測試照擋 |
轉送只依賴 443 與登入狀態,不必驗跨網域(CORS)。代價是登入前的前端錯誤收不到,決策者接受 |
| D5 | 管理員帳密 | 帳號固定 admin@guidantai.com;密碼所有客戶同一組,build 時烙進安裝包(CI 的遮罩變數 → 包內一個權限 600 的檔),install.sh 讀它建管理員,並另存一份到 guidant.env 同目錄的檔案。裝機人員不輸入任何東西 |
裝機人員不具備操作能力;原廠維護時要能直接登入。決策者明確排除「每台隨機產生」與「install.conf 自帶」兩案 |
| D6 | 資料庫落點 | stack 內 guidant-db 另開 bugsink 庫與獨立帳號,不用 SQLite |
不多起一顆 Postgres;獨立庫與帳號在權限上與產品資料互不相通;官方不建議 SQLite 放在 volume |
| D7 | 事件保留 | 沿用預設每專案 1 萬筆(挑重要的留),不設天數上限;guidantai bugsink-vacuum 子命令手動清 |
UAT 期間錯誤的價值在「是不是一直發生」,砍天數反而看不出趨勢;筆數上限已把磁碟用量封頂 |
| D8 | 告警 | 第一版不做,靠人登入看站台;Email/webhook 列為下一版 | 第一版目標是「裝得起來、收得到」;告警牽涉客戶 SMTP 有沒有設、寄給誰,且客戶內網多半連不到 Slack/Teams |
| 過濾 | 送不送的開關 | 做成環境變數,預設只收程式錯誤、可開回全收(細節見拆分表棒 A) | 解掉缺口一;保留全收是為了某些客戶要查「為什麼一直 403」時能臨時打開 |
D5 的已知風險(如實記錄,決策已定)
同一組密碼烙在每一份安裝包裡。任何一台客戶機器的安裝目錄外洩,所有客戶的錯誤追蹤站都能用這組登入——站上有堆疊與變數值(已遮罩,但不是零業務資料)。緩解靠兩件事:站台入口只在客戶內網可達、維運指令提供改密碼子命令(棒 B),客戶或原廠可在單台上改掉。
明確不做:原廠集中收錯誤(本案是每台客戶機器自架,用不到)、讓客戶自訂 DSN 的畫面、站台設定畫面。
誰連誰、走哪條路。客戶需要放行的只有 443。
| 誰 | 連到哪 | 走哪條路 | 經不經客戶防火牆 |
|---|---|---|---|
| 後端三容器(api/socketio/worker) | Bugsink 收事件端點 | docker 內網直連容器(http://guidant-bugsink:8000),DSN 指向內網位址 |
不經 |
| 客戶瀏覽器(已登入) | 後端轉送端點 → Bugsink | 443 → 後端(驗登入)→ docker 內網 → Bugsink | 只經 443 |
| 客戶瀏覽器(未登入) | — | 轉送端點回 401,錯誤不收 | — |
| 原廠人員看站台 | Bugsink 網頁介面 | 443 子路徑 https://<主機>/bugsink/;備案 8443 |
只經 443(備案時多一個 8443) |
| 診斷包匯出 | Bugsink 讀取 API | docker 內網直連,帶 install.sh 建好的 token | 不經 |
陷阱:DSN 有兩個位址角色
Bugsink 用 BASE_URL 組 DSN,而 BASE_URL 是給瀏覽器看站台用的外部位址(子路徑或 8443)。後端送事件要走內網,不能用這個外部位址繞出去再繞回來。B0 要實測「BASE_URL 設外部位址、後端 DSN 改寫成內網位址」送不送得進去;送不進去就要在後端初始化時另外處理。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
participant I as install.sh
participant DB as guidant-db(Postgres)
participant BS as guidant-bugsink
participant ENV as guidant.env
participant BE as 後端三容器
I->>I: 讀安裝包內烙好的管理員密碼檔
I->>DB: 建 bugsink 庫與帳號(D6)
I->>BS: compose up guidant-bugsink(CREATE_SUPERUSER)
BS->>DB: 自動遷移資料表、建管理員
I->>BS: 等 /health/ready 回應
I->>BS: bugsink-manage shell 建 team/project/API token
I->>DB: SQL 讀出 project.id 與 sentry_key
I->>ENV: 組好 DSN 寫入 SENTRY_DSN
I->>BE: compose up 後端
BE->>BS: 開始送錯誤事件
升級(--upgrade)時照產品既有慣例:設定檔不重寫,缺了才補(範例 install.sh 第 2734 行 ensure_classifier_env())。舊客戶第一次升到含 Bugsink 的版本時,走的就是上圖整條;已經有的不動。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
BR["瀏覽器(已登入)<br/>@sentry/vue tunnel"] -->|"443"| NG["nginx<br/>443 入口"]
OP["原廠人員"] -->|"443 /bugsink/<br/>(備案 8443)"| NG
NG -->|"轉送端點"| API
NG -->|"/bugsink/ 子路徑"| BS
subgraph BEG["後端三容器"]
API["api<br/>(含驗登入的轉送端點)"]
SIO["socketio"]
WK["worker"]
end
API -->|"內網直連<br/>過濾→遮罩→節流"| BS["guidant-bugsink<br/>:8000"]
SIO -->|"內網直連"| BS
WK -->|"內網直連"| BS
BS --> PG[("guidant-db<br/>bugsink 庫")]
DIAG["診斷包匯出"] -->|"canonical API+token"| BS
| 元件 | 座標 | 現況 | 本案動作 |
|---|---|---|---|
| 後端初始化 | core/plugins/api_log.py:234 |
讀 SENTRY_DSN 交 jedi-log |
_extra_before_send 加業務錯誤過濾(棒 A) |
| jedi-log | jedi_api_log/error_tracking/__init__.py(1.3.3) |
LoggingIntegration 用預設,error log 變事件 |
多一個參數餵 event_level,發 1.3.4(棒 A) |
| 例外家族 | jedi_common/handler/exception.py |
ClientError 八種 |
只讀,作為過濾判斷依據 |
| 出貨包 | scripts/build/build_bundle.sh 第 98–117 行 |
postgres/seaweedfs 第三方 image 釘 digest | 照抄多包一顆 bugsink(棒 B) |
| stack | docker/production/docker-compose.yml 第 457 行 |
只開 80/443 | 加 guidant-bugsink 服務;nginx 加 /bugsink/ 子路徑(備案才開 8443)(棒 B) |
| 安裝器 | scripts/installer/install.sh |
產 .env(compose 用)與 guidant.env(後端用);升級缺了才補 |
首次建站、升級補站(棒 B) |
| build 期烙印 | scripts/gen_version_bake.py |
CI 產常數檔、不入版控 | 管理員密碼檔照這個模式(棒 B) |
| 前端 | FE src/main.js |
@sentry/vue 已拆 |
復原,tunnel 指向登入後轉送端點,DSN 從登入後端點取(棒 C) |
| 轉送端點 | 後端新增 | 無 | 登入後才能打,原樣轉給內網 Bugsink;只收自家專案的事件,套節流(棒 C) |
| 守衛測試 | test/security/code/test_version_module_no_error_tracking_endpoints.py |
擋免登入端點復活 | 保留不動,棒 C 必須通過它 |
| 診斷包 | infra/support/diag_event_fetcher.py |
打 GlitchTip 式 API | 改打 canonical API(棒 D) |
| 文件 | FR-132-STATE.md 第 19 行、release note v1.26.0 §2b |
寫 restart |
改 start(棒 B 順手) |
| 棒 | 做什麼 | repo | 依賴 | 完成怎麼判定(決策者檢查法) |
|---|---|---|---|---|
| A 過濾開關 | ① 新增 ERROR_TRACKING_CAPTURE_CLIENT_ERRORS(預設 false:八種 ClientError 不送),在後端 _extra_before_send 從 hint 取例外類別判斷;② 新增 ERROR_TRACKING_LOG_EVENTS(預設 false:logger.error 只當 breadcrumb,即附在事件上的前情紀錄,不另開一條),jedi-log init_error_tracking 多一個參數餵 LoggingIntegration(event_level=...),發 1.3.4;後端釘新版;新增前先 grep 確認沒有同義變數;.env.sample 與 deployment-env.md 同步補一行 |
jedi-log → BE | 無 | 打錯密碼三次站台零條;故意 500 一次站台一條;把兩個變數改成 true 重來,打錯密碼又會出現 |
| B0 Bugsink 實跑 | DEV 起 bugsink:2.6.1+stack 的 Postgres(bugsink 庫+獨立帳號),實測清單九項:① shell 建 team/project/token ② SQL 讀 DSN ③ sentry-sdk 2.71 送進去 ④ canonical API 讀回 issue ⑤ 重啟容器後資料仍在 ⑥ 443 子路徑:BASE_URL=https://<host>/bugsink 下網頁可登入、各頁連結與靜態檔不跑掉 ⑦ 轉送:SDK tunnel 經一支假的登入後端點轉給內網 Bugsink,站台收到事件 ⑧ 內外位址:DSN 改內網位址後後端仍送得進去 ⑨ 主機名:升級模式(設定檔已存在)下 install.sh 從哪讀得到主機名;裝完改主機名後 DSN 與站台各會怎樣。產出可直接進 install.sh 的 shell 片段,並給出子路徑通/不通的結論 |
BE(scripts 草稿) | 無 | 實測紀錄九項皆附實際輸出;第 ⑥ 項明寫「通」或「不通,退 8443」;照片段在空白環境重跑一次能重現 |
| B 進 stack | compose 加 guidant-bugsink(healthcheck、環境變數);nginx 加 /bugsink/ 子路徑(B0 第 ⑥ 項不通才改開 8443);guidant-db 建 bugsink 庫與帳號;bundle 多包一顆釘 digest;install.sh 首次建管理員/專案、寫 DSN;--upgrade 缺了才補;build 期烙印管理員密碼檔;guidantai 子命令(bugsink-vacuum、改密碼);修 FR-132-STATE 與 release note 的 restart→start |
BE | B0 | 新包乾淨機器裝好,https://<主機>/bugsink/(或備案 8443)管理員登入看得到 guidant-ai 專案;故意 500 一分鐘內出現;舊版升級上來同樣成立且產品資料完好 |
| C 前端接回 | @sentry/vue 復原,設 tunnel 指向後端新增的轉送端點(登入後才能打、原樣轉給內網 Bugsink、只收自家專案事件、套節流);DSN 由登入後既有端點回應多帶一欄;release 帶版號+commit;trace 標頭串前後端 |
FE+BE | B | tunnel 經登入後端點轉送,站台收到帶 release 與 request_id 的前端事件;未登入打該端點回 401;守衛測試仍綠 |
| D 診斷包 | diag_event_fetcher.py 改打 canonical API;token 讀 install.sh 建好的那把 |
BE | B0 | 匯出的診斷包內錯誤事件與站台一致;站台關掉時包內註明未取得而非整包失敗 |
| E 文件 | .env.sample、deployment-env.md、客戶手冊(站台入口、密碼存放位置、保留規則、改設定用 start)、release note |
BE | A–D | 手冊四件事都找得到;release note 寫明站台入口(子路徑或 8443) |
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
A["A 過濾開關<br/>jedi-log→BE"] --> E["E 文件"]
B0["B0 Bugsink 實跑"] --> B["B 進出貨包"]
B0 --> D["D 診斷包改 API"]
B --> C["C 前端接回<br/>(登入後轉送)"]
B --> E
C --> E
D --> E
🔴 改了 guidant.env 用 restart 不會生效
guidantai restart 只重啟容器不重讀設定檔。install.sh 寫完 DSN 後必須走 up -d;手冊與 release note 一律寫 guidantai start。這條沒寫清楚,客戶會以為站台壞了。
容器重啟會丟掉還沒處理的事件
snappea 佇列寫死在容器內 /tmp。升級或重啟的那幾秒內進來的事件會遺失。UAT 情境可接受,但手冊要寫,免得被當成漏收。
CREATE_SUPERUSER 只在零使用者時生效
升級或第二次跑安裝器時它不會改密碼。所以「改密碼」必須另做維運子命令(棒 B),不能靠改環境變數重跑。
image 內建健康檢查寫死 8000 埠
容器內監聽埠要維持 8000,對外入口(子路徑或 8443)一律由 nginx 轉。改容器內埠會讓 image 自帶的 HEALTHCHECK 永遠失敗。
主機名變了,站台入口與 DSN 會悄悄失效
BASE_URL 含客戶主機名。客戶裝完後改主機名,站台連結會指錯;若 DSN 也是由它組出來,事件送不進去且後端不報錯。B0 第 ⑨ 項要實測影響範圍;手冊要寫「改主機名後跑哪支指令重產」。
升級模式讀不讀得到主機名,尚未實證
舊客戶第一次升到含 Bugsink 的版本時,install.sh 走「設定檔已存在、缺了才補」,不會再問主機名。要從既有設定的哪一欄讀到它,B0 第 ⑨ 項要查清楚;讀不到就要另訂來源,不能在升級時停下來問裝機人員。
轉送端點不可變成開放轉發器
後端轉送端點登入後就能打,若原樣轉發任何內容,等於讓已登入使用者能往內網 Bugsink 灌任意資料。端點只接受自家專案 DSN 的事件、大小設上限、套節流。
過濾開關關掉後,403 類問題在站台上看不到
預設不收業務錯誤,代表「權限設定錯導致一直 403」這種問題要回頭看存取紀錄或臨時把開關打開。這是刻意取捨,手冊要寫開關怎麼開。