lifecycle:被逼停的關機走 BeginFailure;修好 kit/logging 會過期的測試 - #14
Merged
Conversation
newRotator 在建構時就 prune 一次(服務停機久於保留窗時要補刪),而測試是在 它回傳之後才裝上 r.now——那個時鐘來得太晚,那次 prune 用的是真實時鐘。 測試把「保留窗內」那個檔固定寫在 2026-07-31,於是真實時間越過 cutoff(now-14d)的那一天起,建構時的 prune 就把它刪掉了,測試從此 單向轉紅。臨界點是 2026-08-14。 時鐘改成 newRotator 的參數(nil = time.Now),在 prune 之前就位。 順帶讓這支測試真的涵蓋到啟動時那次 prune——它先前完全沒有被測到, 因為斷言前又呼叫了一次 prune,看起來像是那一次的功勞。 反向對照:拿掉保留期的刪除,測試在新的斷言上轉紅。
BeginShutdown 的 announce 一律 info,而採用它的服務都把「是什麼逼停了我」 當成那一行的欄位傳進去。結果是:跑在 log.level: warn 的部署——也就是最需要 這筆紀錄的那些——listener 起不來時,那個 error 不存在於任何一筆 error 紀錄裡, 行程就這麼消失,什麼都沒留下。 新增 BeginFailure(log, reason, err, attrs...): - 觸發的 error 走 **Error**,帶著是什麼掛了; - Done() 之後**不會**說 "stopped cleanly" 而是 "stopped after a failure", 即使每個拆解步驟都成功——收拾得乾淨不等於停得乾淨,而在 warn 底下那行 總結本來會是唯一活下來的一行; - err 傳 nil 代表沒有東西逼停它,等同 BeginShutdown(單一程式路徑的呼叫端 不會意外變吵)。 BeginShutdown 一個位元組都沒動:有秩序的停止維持 info,跑在 warn 的部署 看不到它是刻意的,例行重啟不該每次都喊。成功的步驟也維持 debug。 測試改成斷言**某個層級的部署實際看得到什麼**,而不是斷言呼叫了什麼——這個 差別只在 info 以上才存在,在 debug 底下驗不出來。四支:warn 底下失敗關機 聽得到(且成功步驟不會漏出來)、warn 底下正常關機完全靜默、失敗的 step 即使在正常關機裡也是 error、nil cause 等同 BeginShutdown。把原因行退回 info 可讓第一支轉紅,已實測。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
兩件事,都與「日誌在什麼層級才看得到」有關。
1.
lifecycle.BeginFailureBeginShutdown的 announce 一律info,而採用它的服務把「是什麼逼停了我」當成那一行的欄位傳進去。結果是:跑在
log.level: warn的部署——也就是最需要這筆紀錄的那些——listener 起不來時,那個 error 不存在於任何一筆
error紀錄裡,行程就這麼消失,什麼都沒留下。
新增
BeginFailure(log, reason, err, attrs...):Error,帶著是什麼掛了;Done()之後不會說stopped cleanly,而是stopped after a failure——即使每個拆解步驟都成功。收拾得乾淨不等於停得乾淨,而在
warn底下那行總結本來會是唯一活下來的一行;
err傳nil= 沒有東西逼停它 = 等同BeginShutdown,讓只有一條程式路徑的呼叫端不會意外變吵。
BeginShutdown一個位元組都沒動:有秩序的停止維持info,跑在warn的部署看不到它是刻意的——例行重啟不該每次都喊。成功的拆解步驟也維持
debug。2.
kit/logging的測試從 2026-08-14 起單向轉紅newRotator建構時就prune()一次,而測試是在它回傳之後才裝r.now——那次 prune 用的是真實時鐘。「保留窗內」那個檔固定寫在 2026-07-31,
真實 cutoff(now−14d)越過它的那一天起就被刪掉了。不是 flaky,是單向過期。
把時鐘改成
newRotator的參數(nil=time.Now),在 prune 之前就位。順帶讓那支測試真的涵蓋到啟動時那次 prune——它先前完全沒被測到,
因為斷言前又呼叫了一次
prune(),看起來像是那一次的功勞。驗證
gofmt -l .無輸出、go build ./...、go vet ./...、go test -race ./...全綠;js/的npm test33 passed / 0 failed(本次沒有動到 JS,那裡沒有 lifecycle)。測試斷言的是某個層級的部署實際看得到什麼——建一個
Level: warn的 logger、寫進暫存檔、讀回來比對。這個差別在
debug底下驗不出來,所以任何在預設層級跑的測試都會是綠的。四支:
warn底下失敗關機聽得到(且成功步驟不會漏出來)、warn底下正常關機完全靜默、失敗的 step 即使在正常關機裡也是error、nilcause 等同BeginShutdown。實測反向對照:把原因行退回
info,第一支轉紅;還原後回綠。Generated by Claude Code