Command-Line
從日誌中繪製狀態機
我有以下格式的日誌:
03/22/2011 14:45:06;0001;PBS_Server;Svr;PBS_Server;svr_setjobstate: setting job 35707.arien.ics.muni.cz state from EXITING-RETURNSTD to EXITING-STAGEOUT (5-51) 03/22/2011 14:45:06;0001;PBS_Server;Svr;PBS_Server;svr_setjobstate: setting job 35709.arien.ics.muni.cz state from RUNNING-PRERUN to RUNNING-RUNNING (4-42) 03/22/2011 14:45:07;0001;PBS_Server;Svr;PBS_Server;svr_setjobstate: setting job 35708.arien.ics.muni.cz state from RUNNING-RUNNING to EXITING-EXITING (5-50) 03/22/2011 14:45:07;0001;PBS_Server;Svr;PBS_Server;svr_setjobstate: setting job 35708.arien.ics.muni.cz state from EXITING-EXITING to EXITING-RETURNSTD (5-70) 03/22/2011 14:45:07;0001;PBS_Server;Svr;PBS_Server;svr_setjobstate: setting job 35708.arien.ics.muni.cz state from EXITING-RETURNSTD to EXITING-STAGEOUT (5-51) 03/22/2011 14:45:08;0001;PBS_Server;Svr;PBS_Server;svr_setjobstate: setting job 35709.arien.ics.muni.cz state from RUNNING-RUNNING to EXITING-EXITING (5-50)
現在,我想以圖形方式重建狀態機,但我有點猶豫如何解決這個問題。切斷過渡應該不是問題,但我不確定如何從它們重建圖形表示。
我不肯定我知道你的意思,但你在尋找這樣的東西嗎?
我使用了Graphviz,它接受描述轉換的文本輸入文件,並自動計算出圖形。這是確切的命令:
$ sed 's/-/_/g' input | gawk ' BEGIN {print "digraph g {"} END {print "}"} match($0, /from ([^ ]*) to ([^ ]*) \((.*)\)$/, groups) { print groups[1] " -> " groups[2] " [label = \"" groups[3] "\"];" }' > output.dot $ dot -Tpng output.dot > output.png
解釋
sed 's/-/_/g' input
– Dot 不喜歡節點名稱中的連字元,所以我將它們轉換為下劃線
gawk
– 標準awk沒有match
gawk的功能;你可以以任何你喜歡的方式進行字元串操作(例如 perl 是另一個不錯的選擇)
BEGIN {print "digraph g {"}
– 點規格從這條線開始(圖形的名稱,“g”,並不重要)END {print "}"}
–digraph g
在 BEGIN 塊中結束開始match($0, /from ([^ ]*) to ([^ ]*) \((.*)\)$/, groups)
– 一個匹配你的日誌文件格式的正則表達式;它將結果儲存在groups
變數中print groups[1] " -> " groups[2] " [label = \"" groups[3] "\"];"
– 輸出與點兼容的線(例如,A -> B [label = "C"];
將顯示兩個節點 A 和 B,它們之間的過渡標記為 C)
dot -Tpng output.dot > output.png
– 告訴 graphviz 將點文件轉換為 PNG生成的點文件
digraph g { EXITING_RETURNSTD -> EXITING_STAGEOUT [label = "5_51"]; RUNNING_PRERUN -> RUNNING_RUNNING [label = "4_42"]; RUNNING_RUNNING -> EXITING_EXITING [label = "5_50"]; EXITING_EXITING -> EXITING_RETURNSTD [label = "5_70"]; EXITING_RETURNSTD -> EXITING_STAGEOUT [label = "5_51"]; RUNNING_RUNNING -> EXITING_EXITING [label = "5_50"]; }
執行該文件時獲得的PNG在
dot
上面