首页 > 解决方案 > 重定向性能输出

问题描述

我正在编写一个性能监控脚本来监控应用程序。在此脚本中,调用 perf,然后应用程序等待一段时间,然后终止 perf 进程并收集 perf 信息以及其他非 perf 指标。我通过调用运行 perf 命令:

os.popen('perf stat -d -p ' + pid_executable + ' -o DATA/perf_stat.txt &')

我后来杀死了这个 perf 调用:

os.popen('kill -INT ' + pid_perf)

选项是将-o常规标准输出输出到文件。不幸的是,当kill被调用时,没有收集任何信息。输出如下:

# started on Tue Oct  5 22:28:43 2021


 Performance counter stats for process id '8056':

     <not counted>      task-clock                                                  
     <not counted>      context-switches                                            
     <not counted>      cpu-migrations                                              
     <not counted>      page-faults                                                 
     <not counted>      cycles                                                      
     <not counted>      instructions                                                
     <not counted>      branches                                                    
     <not counted>      branch-misses                                               
     <not counted>      L1-dcache-loads                                             
     <not counted>      L1-dcache-load-misses                                       
     <not counted>      LLC-loads                                                   
     <not counted>      LLC-load-misses                                             

       0.382097310 seconds time elapsed

Some events weren't counted. Try disabling the NMI watchdog:
    echo 0 > /proc/sys/kernel/nmi_watchdog
    perf stat ...
    echo 1 > /proc/sys/kernel/nmi_watchdog

我的性能版本是: perf version 3.10.0-957.12.1.el7.x86_64.debug

我曾尝试使用环境变量来保存输出并使用管道、 和 进行重定向tee>但这产生了类似的结果。我无权访问sudo,并且正常--timeout选项不可用。在 Python 脚本之外正常调用时,Perf 也可以工作。

信息被写入文件,只是没有被收集。我如何收集这些信息以便正确收集?

标签: pythonperf

解决方案


看看上一篇文章中的这个答案。本质上,最好的处理方式是“Pythonic”方式,而不是要求popen处理。所以在你的情况下,你想做这样的事情:

from subprocess import PIPE, Popen

command = f"perf stat -d -p {pid_executable}"
with Popen(command, stdout=PIPE, stderr=None, shell=True) as process:
    output = process.communicate()[0].decode("utf-8")
    with open("perf_stat.txt", "w") as f:
        f.write(output)

TBH 我在没有测试的情况下写了这个,但它应该按照它写的方式工作


推荐阅读