iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
佛心分享-SideProject30

打造 APR Engineer 的生產力平台,從 Flow Tracer 到 SignOff DashBoard 的落地實戰系列 第 11

【Day 11 】 智慧 Log 追蹤與管理:一個一個開 Log 來看也未免太累

  • 分享至 

  • xImage
  •  

前言

昨天把圖畫出來了。節點會變色、會閃、會告訴你誰在 LSF 排隊。還有一個真正花時間的,是看你的工作,到底跑得如何 ?

綠了,只代表你設定要做的工作順利完成了。

日常大概長這樣:EDA 跟驗證工具都會吐一份幾十萬行的 log。JOB 一旦多起來,如果還是在用 gvim log/xxx.log 一個一個開,那是真的會累死

讓顏色告訴你「誰出事了」;讓 log 告訴你「出什麼事」。WinFlow 做的,是讓你不必離開畫面,就能把後者讀完。

先把兩種 log 拆開

很多人會把「程式幹的活」跟「LSF job 幹的活」搞混

WinFlow 把這兩者拆成兩個目錄、兩個分頁:

bsub -o log/{lsf_name}.log     Job 的 stdout(工具自己印的)
     -e log/{lsf_name}.err     Job 的 stderr
Runner 自己記的:
     logs/flow_YYYYMMDD_HHMMSS.log    GUI 這次 session
     logs/flow_runner.log             CLI 模式
分頁 目錄 在說什麼
Runner Log logs/* 誰被 bsub、現在 PEND 還是 RUN、哪一顆 EXIT
Job Log log/* 那顆 job 真正跑出來的 Innovus / Calibre / script 輸出

https://ithelp.ithome.com.tw/upload/images/20260815/20127932YnxS0pBN6T.jpg

Runner Log 管「排程發生了什麼」;Job Log 管「那個程式在做什麼」

注意 lsf_name 不是畫面上的 job 名。Runner 送 LSF 時會再加使用者與時間戳,避免撞名。檔案因此長這樣:

log/lee_Place_20260815_140211.log
log/lee_Place_20260815_140211.err

路徑可改。config.jsonrunner.job_log_dir / runner.session_log_dir 就是這兩間倉庫的位置

Job Log 怎麼抓:先看尾巴,再跟著長

LSF 一收下 job,bsub -o / -e 就把檔案路徑訂死。GUI 收到 job_submitted 之後,會做三件事:

  1. 記住這顆的 lsf_name(檔名就是它)
  2. 自動切到 Job Log 分頁,下拉選單對到這顆
  3. 背景執行緒開始 tail

不會把整份 log 讀進 Tk。EDA 工具的 log 動輒數十 MB,Text widget 吃進去會卡死。實際做法是:

[ 檔案從頭 ........ 還沒載入 ........ | 最後 100 行 | 之後新寫的 ]
                                       ↑
                               job_log_view_lines

job_log_io.py 從檔案尾巴往回讀,一次 8KB,湊滿設定的行數(預設 100)就停。回傳三樣東西:這 100 行、它們從哪個 byte 開始、更前面還有沒有內容。
之後 JobLogTailer 每 0.5 秒(log_tail_interval_sec)只讀「上次看到的 offset 之後新長出來的 bytes」。你人如果已經捲在最底,畫面會跟著往下走;你如果正在上面翻舊帳,它不會把你拽回去。

這就是為什麼畫面上有時會出現一行:

[...] earlier log not loaded — scroll up or search to load more

往上捲、或搜尋時目前這窗找不到,會再用 read_lines_before() 把更前面的 100 行接上來。舊內容插在頂部,你原本看的那一行會盡量留在原位——不然每次「再載一點」都跳到檔案頭,比直接開 gvim 還暈。

呈現:深色、檔名、stdout / stderr 同框

每一行長這樣:

[14:03:11] [STDOUT] [lee_Place_....log]   工具印的字
[14:03:12] [STDERR] [lee_Place_....err]   錯誤流

.log.err 合在同一個視窗,但用顏色分開:stdout 偏綠,stderr 偏紅。前面掛檔名,是因為你之後可能從下拉選單跳去看另一顆,不能讓行看起來像沒標籤的匿名字。

下拉視窗中的預設 log 視窗會看哪一顆剛被 bsub。想回看已經 DONE 的,自己選就好;選完會先載入那份檔的最後 100 行。若那顆還在跑、而且正好是目前 active job,tail 會從檔案結尾接著跟,不會把你剛載入的內容再灌一次。

真的要整份檔、要跳行號、要跟同事對同一份 evidence,工具列有 Open log file。預設叫 gvim(可在runner.log_viewer 改)

背景執行緒不准直接碰 Tk。tail 進來的資料先丟進 queue,主執行緒每 50ms 再畫。這是 Tk 的規矩;破了,畫面會在你最需要看 log 的時候凍結。

Highlight:讓 ERROR 自己站出來

顏色如果只分 stdout / stderr,還是不夠。很多 EDA 工具把失敗寫在 stdout 裡,一行 ERROR 埋在十萬行 INFO 中間。
所以插入每一行時,會再掃一次關鍵字(不分大小寫)。它標的是,不是整行。你還是看得到前後文,只是那個字會自己發光:

關鍵字 標記 看起來
FATAL / CRITICAL sev_fatal 紅字、深紅底、粗體
ERROR / FAILED / EXCEPTION / TRACEBACK sev_error 紅字、暗底、粗體
WARNING / WARN sev_warning 黃字、暗黃底
MISSING / NOT FOUND / TIMEOUT / ABORT / DENIED sev_alert 橘色、提醒用

再加一個按鈕:Issues only。打開之後,只留 stderr,以及命中上面那些關鍵字的行。十萬行變成幾十行。把人眼不該逐行做的過濾,先做掉。

另外我也順手把 LSF 常見的廢話濾掉。像沒有 tty 的 batch job 很愛印:

TERM environment variable not set.

這種也對除錯沒有任何資訊量,is_job_log_noise() 會在進畫面之前丟掉。空行也丟

搜尋:找不到就再往檔案頭挖

工具列有 Search、Find Next、Find Prev。狀態列會顯示 3 / 17。目前命中用亮黃,其他命中用暗橘。Enter 等於找下一筆。

比較少被注意到的是:如果目前載入的這 100 行裡沒有,搜尋會自動載入更舊的內容再找,最多試好幾輪。也就是你不用先把檔案捲完,才知道這個 timing violation 到底在不在。

它不是全文索引。目標是「在 GUI 裡夠用」;如果有要 grep 整份 800MB 的 log,還是 Open log file 會比較好

Runner Log:一顆 job 只佔一行

另一個分頁在解決另一種 log
本來 LSF 輪詢時,應該會一直印:

[12345] Status: PEND
[12345] Status: PEND
[12345] Status: RUN
[12345] Job completed successfully

如果每則都新開一行,就會變得很長,我讓 GUI 認得出這些句型,同一顆 job 永遠只佔一行,內容就地變成:

[14:03:11] [JOB] lee_Place_...  id=12345  PEND

PEND 淺藍、RUN 藍、DONE 綠、EXIT 紅。要的是「現在這顆活著還是死了」,不是「它已經回報 PEND 二十次」。
其他真正的事件 —— 缺 input、bkill、驗證失敗還是一行一行往下長。該吵的還是要吵。

最後再用一張圖把路徑講完

LSF 機器上的 job
        |  stdout / stderr
        v
   log/{lsf_name}.log
   log/{lsf_name}.err
        |
        +-- JobLogTailer(背景,0.5s)
        |      先 tail 100 行,再只讀新 bytes
        v
   Job Log 分頁(深色)
        |-- STDOUT 綠 / STDERR 紅
        |-- ERROR / WARN 關鍵字 highlight
        |-- Issues only
        |-- Search(不夠就再載舊的)
        |-- 往上捲 → 再載 100 行
        +-- Open log file → gvim(整份檔)
Runner 自己的事件
        |
        v
   logs/flow_*.log
        |
        v
   Runner Log 分頁(淺色)
        +-- 同一顆 job 的狀態,疊在同一行

可以調的參數

我都把他們放在 config.json 裡的 runner

欄位 預設 用途
job_log_dir log LSF -o / -e 的目錄
session_log_dir logs Runner 自己的 session
job_log_view_lines 100 一開始載幾行、往上捲一次補幾行
log_tail_interval_sec 0.5 多久去看檔案長了沒
log_viewer gvim Open log file 叫誰

Reset Flow 會把兩個目錄裡的檔清掉,DAG 回到 waiting。它不會幫你 bkill。Log 跟 LSF 行程是兩件事,清畫面不等於殺 job。

小結

這篇沒有新的排程演算法。只是在解決一個問題:

一個個開 log 來看實在是太累了
WinFlow 能做到一些改善:尾巴先看、關鍵字自己亮、廢話先丟掉,需要整份檔的時候,也可以把 gvim 請回來。


上一篇
【Day 10】 Flow 可視化(Visualization):畫出連菜鳥都能一眼看懂的流程圖
下一篇
【DAY 12】 Flow Control 實戰技巧:幾種 APR 最常碰到的控制與狀況處理
系列文
打造 APR Engineer 的生產力平台,從 Flow Tracer 到 SignOff DashBoard 的落地實戰13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言