等待非同步 Log Flush 完成的穩定偵測法
等待非同步 Log Flush 完成的穩定偵測法
面對 async log writer(如 OTEL BatchProcessor),固定 sleep 要嘛太短導致漏讀,要嘛太長浪費時間。正確做法是 poll 直到讀到的筆數連續穩定,代表 flush 已完成。
問題情境
OTEL BatchProcessor 不立即 flush,而是分批寫入:
1 | Agent 執行完畢 |
如果只 sleep 固定時間:
- Sleep 100ms → 只讀到 3 筆,以為完成,漏掉 2 筆
- Sleep 600ms → 總是等太久,即使 100ms 就完成了
穩定偵測邏輯
1 | func waitForLogStable(logPath string, maxWait time.Duration) error { |
時序示意:
1 | t=0ms count=0 → stableRounds=0 |
為何需要連續 3 次(stableRounds >= 2)
只要求 2 次(stableRounds >= 1)可能在 burst-gap 中間提早返回:
1 | t=200ms count=3 → stableRounds=0 |
連續 3 次相同表示已等過至少 2 個 poll interval(400ms),足以覆蓋一般 burst-gap。若 BatchProcessor 間隔更長,可調整 stableRounds 閾值或 time.Sleep 間距。
應用場景
此模式適用於任何非同步 log consumer:
| 場景 | 說明 |
|---|---|
| OTEL BatchSpanProcessor | 本文情境,等待 trace flush |
| Kafka consumer lag | poll 直到 consumer group offset 穩定 |
File tail(tail -f) |
等待寫入程序完成後再解析 |
| DB async replication | 等待 replica 追上 primary |
| 非同步 job queue | poll 直到 queue depth 不再變化 |
本部落格所有文章除特別聲明外,均採用CC BY-NC-SA 4.0 授權協議。轉載請註明來源 Kenny's Blog!




