• 周六. 7 月 13th, 2024

    xhprof安装了graphviz还报错failedto execute cmd “dot-Tpng”

    root

    9 月 7, 2020 #xhprof

    使用XHProf我们肯定需要查看它强大的图形统计结果分析图,而xhprof是用dot进行绘图的,在xhprof程序安装包中xhprof_lib/utils/callgraph_utils.php文件中可看到方法function xhprof_generate_image_by_dot()中有接头这个CMD命令。
    Dot是什么?dot是一个适合程序员使用的绘图工具。让你可以用几行代码就能绘制出一些流程图出来。
    dot本身是Graphviz工具包中的一个工具。Graphviz是大名鼎鼎的贝尔实验室的几位牛人开发的一个画图工具,它提供了“所想即所得”的理念,通过dot语言来编写脚本并绘制图形,简单易懂。我们使用一个文本文件通过dot语法描述图形关系,然后用dot生成最终的图形。dot负责布局我们所描述的图形。就算图形对象非常多,关系非常复杂,dot也能将其布局的非常清楚。dot文件语法非常简单,可以像程序一样手动编写,不过很多时候是通过其他程序生成。 如果在使用XHProf的时候我们没有安装dot(即安装Graphviz),则可能会报错如下:
    Error: either we can not find profile data for run_id 58eb5359be406 or the threshold 0.01 is too small or you do not have dot image generation utility installed.
    这时我们就需要安装一下Graphviz工具包:

    yum list 'graphviz*'         #可以看到有很多种语言的包
    yum install -y graphviz      #安装graphviz工具包
    yum install 'graphviz-php*'  #PHP的包。
    

    安装好之后再进行xhprof的图形分析界面,就不会出现这个报错了,但有可能会报这个错误:
    failed to execute cmd ” dot -Tpng”
    我开始以为是没有安装好dot,或者dot没有安装完全。找了些答案。但都没有帮我解决。最后我从xhprof的程序入手自己看,程序如下:

    100 function xhprof_generate_image_by_dot($dot_script, $type) {
    101   $descriptorspec = array(
    102        // stdin is a pipe that the child will read from
    103        0 => array("pipe", "r"),
    104        // stdout is a pipe that the child will write to
    105        1 => array("pipe", "w"),
    106        // stderr is a pipe that the child will write to
    107        2 => array("pipe", "w")
    108        );
    109 
    110   $cmd = " dot -T".$type;
    111 
    112   $process = proc_open($cmd, $descriptorspec, $pipes, "/tmp", array());
    113   if (is_resource($process)) {
    114     fwrite($pipes[0], $dot_script);
    115     fclose($pipes[0]);
    116 
    117     $output = stream_get_contents($pipes[1]);
    118
    119     $err = stream_get_contents($pipes[2]);
    120     if (!empty($err)) {
    121       print "failed to execute cmd: \"$cmd\". stderr: `$err'\n";
    122       exit;
    123     }
    124 
    125     fclose($pipes[2]);
    126     fclose($pipes[1]);
    127     proc_close($process);
    128     return $output;
    129   }
    130   print "failed to execute cmd \"$cmd\"";
    131   exit();
    132 }
    

    此报错是在130行报错,非121行报错,121行报错会报出标准错误。可见是这个proc_open方法执行不成功。于是我便想到php配置文件中的禁用函数:找到php的配置文件:把disable_functions中的proc_open方法去除,重启php解决问题。

    root

    发表回复