我有以下格式的日志:
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)
现在,我想以图形方式重建状态机,但我对如何解决这个问题有点犹豫。删除过渡应该不是问题,但我不确定如何从它们重建图形表示。
答案1
我不确定我明白你的意思,但你在寻找这样的东西吗?
我用了图形可视化,它采用描述转换的文本输入文件,并自动计算出图形。这是确切的命令:
$ 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"];
}
运行该文件时得到的 PNGdot
如下所示
答案2
我正在开发一个工具来完全满足您的需求——从日志生成有限状态机。该工具称为 Synoptic,您可以在此处找到有关它的更多信息: http://code.google.com/p/synoptic/