从日志中绘制状态机

从日志中绘制状态机

我有以下格式的日志:

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 没有matchgawk 有的功能;你可以用任何你喜欢的方式进行字符串操作(例如perl是另一个不错的选择)
    • BEGIN {print "digraph g {"}-- 点规格从这条线开始(图形的名称“g”并不重要)
    • END {print "}"}-- 结束digraph gBEGIN 块中的开始
    • 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/

相关内容