2021-04-08

1. bootchart 简介


bootchart 是一个用于 linux 启动过程性能分析的开源工具软件,在系统启动过程中自动收集 CPU 占用率、磁盘吞吐率、进程等信息,并以图形方式显示分析结果,可用作指导优化系统启动过程。

bootchart 让用户可以很直观的查看系统启动的过程和各个过程耗费的时间,以便让用户能够分析启动过程,从而进行优化以提高启动时间。

它由 bootchartd 服务和 bootchart-render 两部分组成,后者主要负责生成启动流程的分析结果图。

bootchart官网

2. bootchart 在 android8.1 中的应用


Android 系统源码中有 bootchart 的实现,路径在 system/core/init/bootchart.cpp 中, bootchart 通过内嵌在 init 进程中实现,在后台执行测量。不过 bootchart 的测量时段是 init 进程启动之后,不包含 uboot 和 kernel 的启动时间。

3. bootchart 在 android 平台的使用步骤


在 android 源码路径 system/core/init/README.md 中包含了对 bootchart 的使用说明。

3.1. 编译 bootchart


在 Android 5.1 之前 bootchart 是没有编译进系统的,需要使用下面的宏手动打开编译,在 Android 6.0 以上系统默认已经编译了 bootchart,可以 adb shell 命令进入文件系统,可以看到 data 下面已经有 bootchart 的目录了。

rk3288:/data/bootchart # ls


3.2 打开 bootchart 收集开机数据

1. adb shell 'touch /data/bootchart/enabled'
   首先使能 bootchart,bootchart 操作的前提是存在 enable 标记,所以
   在你不需要收集数据的时候别忘了删除这个标记。

2. - sudo apt-get install pybootchartgui
   - $ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh
   grab-bootchart.sh 脚本是 Google 封装的一系列操作的合集跟使用下面手动操作的结果是一样的。
   
   * 手动操作
   1. (可选) echo $TIME_OUT > /data/bootchart/start
   添加 bootchart timeout 时间
   2. reboot 重启
   3. 可以看到 bootchart 生成的数据文件和 log 都被保存在 /data/bootchart 路径下
   4. tar -zcf bootchart.tgz *
   5. 使用 adb pull 命令将文件拷贝出来


3.3 在 Linux PC 机上生成 bootchart 图表
PC 机安装 bootchart 工具

sudo apt-get install bootchart
sudo apt-get install pybootchartgui 


生成 bootchar 图表
拷贝 bootchart.tgz 到 PC 中,并执行下面的命令生成图表

bootchart bootchart.tgz


4. bootchart 图形分析小技巧

image
整个图表以时间线为横轴,图标上方为 CPU 和 磁盘的利用情况,下方是各进程的运行状态条,显示各个进程的开始时间与结束时间以及对 CPU、I/O 的利用情况,我们关心的各个进程的运行时间以及 CPU 的使用情况,进而优化系统。

1.可以通过 Laucher 的启动时间判断开机完成完成时间
2.通过进程的时间长短判断是否存在异常,如图表上的 第一个 Zygote 进程启动时间很短,显示存在异常,后又成功心启动了一遍。
3.待补充
————————————————
版权声明:本文为CSDN博主「岁月斑驳7」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_19923217/article/details/81043736

 

 

#######################################################################################################################################################

bootchart工具在Android系统开机测量中的应用

https://blog.csdn.net/harry_helei/article/details/7281356

 bootchart本是一个开源工具,用可视化的方式对GUN/LINUX的开机启动过程进行性能分析,包括资源的使用,如CPU,磁盘等,各进程的执行时间等信息。根据分析结果,确定系统启动的性能瓶颈,制定相应的优化策略。关于bootchart的来历和说明件其官方网站:点击打开链接

      Android系统中已有一份bootchart的c实现,位于system/core/init/bootchart.c中。bootchart对Android开机测量是通过内建在init进程中实现的,在后台执行测量。不过bootchart的测量时段是从bootchart被初始化之后到home screen出来之前,不包括bootloader和kernel的执行时间。

      我的系统是UBuntu10.04,现将整个使用步骤归纳如下:

1)、UBuntu下bootchart工具的安装

2)、bootchart在Android下的编译

3)、bootchart在Android下的执行

4)、bootchart测量结果的图形化过程
下面依次对上述四个步骤进行详细说明。

1、UBuntu下bootchart工具的安装

       需要安装的工具有两个bootchart和pybootchartgui,执行命令如下:
sudo apt-get install bootchart
sudo apt-get install pybootchartgui

2、bootchart在Android下的编译
       Android系统编译时,默认的没有打开bootchart的编译开关,即没有把bootchart编译进系统中。要把bootchart编进系统分为两种情况了:

1)、系统没有被编译过或者执行了make clean命令,可以执行以下命令:       

$ cd mydroid
$ export INIT_BOOTCHART=true
$ make clean
$ make
2)、系统已经编译过,现在只是要添加bootchart进系统中,执行以下命令:‘
$ touch system/core/init/init.c
$ m INIT_BOOTCHART=true
其中touch命令的作用就是将init.c文件的最后修改时间改为当前时间,这样保证init.c文件会被重新make,而bootchart就是在init.c中被调用的,从而保证bootchart会被编进系统中。

3、bootchart在Android下的执行

      1}、将编译生成的带有bootchart工具的Android系统重新烧录到开发板上,并启动系统

      2)、在UBuntu上通过adb connect连接到开发板,然后执行:

       $ adb shell 'echo 120 > /data/bootchart-start'
      3)、执行命令:

       $ adb shell 'mkdir /data/bootchart'
              在开发板上系统的/data/目录下新建目录bootchart/用来存放bootchart的测量结果,后面要利用这些文件生成可视化图片
      4)、重新启动开发板,在开发板的Android系统的/data/bootchart/目录下将看到以下文件:
# ls -l
-rw-rw-rw- root     root          452 2010-01-01 00:00 header
-rw-r--r-- root     root            0 2010-01-01 00:00 kernel_pacct
-rwxr-xr-x root     root      1020195 2010-01-01 00:02 proc_diskstats.log
-rwxr-xr-x root     root      4252966 2010-01-01 00:02 proc_ps.log
-rwxr-xr-x root     root       138215 2010-01-01 00:02 proc_stat.log
到此为止,bootchart执行测量后生成的测量数据已经完成,看上面有3个.log文件,下面需要将这些数据进一步处理成易读、易分析的图片。
4、bootchart测量结果的图形化过程

       1)、到这里要夸奖下android做的比较贴心,已经写好了脚本将bootchart测量生成的数据直接从开发板上打包出来,生成bootchart.tgz。这个打包脚是源码的system/core/init/grab-bootchart.sh文件,和bootchart源码位于同一目录下。脚本的内容如下:

#!/bin/sh
#
# this script is used to retrieve the bootchart log generated
# by init when compiled with INIT_BOOTCHART=true.
#
# for all details, see //device/system/init/README.BOOTCHART
#
TMPDIR=/tmp/android-bootchart
rm -rf $TMPDIR
mkdir -p $TMPDIR

LOGROOT=/data/bootchart
TARBALL=bootchart.tgz

FILES="header proc_stat.log proc_ps.log proc_diskstats.log kernel_pacct"

for f in $FILES; do
    adb pull $LOGROOT/$f $TMPDIR/$f 2>&1 > /dev/null
done
(cd $TMPDIR && tar -czf $TARBALL $FILES)
cp -f $TMPDIR/$TARBALL ./$TARBALL
echo "look at $TARBALL"
从脚本的LOGROOT一项可以看出,步骤3的3)中,新建存放bootchart测量结果的文件目录不可以随便更改的,要保证所建目录与脚本的LOGROOT项保持一致。打包后将在当前目录下,即system/core/init/下生成bootchart.tgz文件。
      2)、在bootchart.tgz所在目录下执行命令:

       $bootchart ./bootchart.tgz
       这样就在system/core/init/目录下生成了bootchart.png,如下图所示

5、问题总结

        在执行第4步的2)时,即执行命令:

    $bootchart ./bootchart.tgz
时,报错啦,如下错误:
parsing './bootchart.tgz'
parsing 'header'
parsing 'proc_stat.log'
parsing 'proc_ps.log'
warning: no parent for pid '2' with ppid '0'
parsing 'proc_diskstats.log'
parsing 'kernel_pacct'
merged 0 logger processes
pruned 61 process, 0 exploders, 2 threads, and 0 runs
False
Traceback (most recent call last):
  File "/usr/bin/bootchart", line 23, in <module>
    sys.exit(main())
  File "/usr/lib/pymodules/python2.7/pybootchartgui/main.py", line 137, in main
    render()
  File "/usr/lib/pymodules/python2.7/pybootchartgui/main.py", line 128, in render
    batch.render(writer, res, options, filename)
  File "/usr/lib/pymodules/python2.7/pybootchartgui/batch.py", line 41, in render
    draw.render(ctx, options, *res)
  File "/usr/lib/pymodules/python2.7/pybootchartgui/draw.py", line 282, in render
    draw_chart(ctx, IO_COLOR, True, chart_rect, [(sample.time, sample.util) for sample in disk_stats], proc_tree)
  File "/usr/lib/pymodules/python2.7/pybootchartgui/draw.py", line 201, in draw_chart
    yscale = float(chart_bounds[3]) / max(y for (x,y) in data)
ZeroDivisionError: float division by zero
临门一脚出了问题,甚为恼火,找了一圈,总算解决了。解决的具体办法见连接: 点击打开链接,在链接网页内找到 draw.py, parsing.py, samples.py三个文件的下载链接并下载,然后替换ubuntu上/usr/share/pyshared/pybootchartgui/ 下对应的文件,并再次执行命令:
bootchart ./bootchart.tgz
即可。如果没有遇到上述问题,那么既可喜也可惜,呵呵!!
————————————————
版权声明:本文为CSDN博主「harry_helei」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/harry_helei/article/details/7281356


#######################################################################################################################################################

bootchart工具在Android系统开机测量中的应用(二)之问题解决

https://blog.csdn.net/harry_helei/article/details/8545032#

 在我的前一篇博客 《bootchart工具在Android系统开机测量中的应用》中,最后有个问题总结部分,都一年多了,最后给出的三个.py文件的下载链接都找不到了。而且之前问题的出现是在python2.7时出现的。后来我重装系统发现,Ubuntu10.04内建的python版本是2.6,估计之前我那个系统中的python被升级过成2.7了。在python2.6下还会有新的问题。这里一并做个总结。
1、直接执行命令:

$sudo apt-get install bootchart    
$sudo apt-get install pybootchartgui  
安装bootchart之后,执行命令:
$bootchart ./bootchart.tgz 
生成bootchart.png时,直接提示错误:
    parsing 'header'  
    parsing 'proc_stat.log'  
    parsing 'proc_ps.log'  
    warning: no parent for pid '2' with ppid '0'  
    parsing 'proc_diskstats.log'  
    parsing 'kernel_pacct'  
    merged 0 logger processes  
    pruned 63 process, 0 exploders, 2 threads, and 0 runs  
    False  
    Traceback (most recent call last):  
      File "/usr/bin/bootchart", line 23, in <module>  
        sys.exit(main())  
      File "/usr/lib/pymodules/python2.6/pybootchartgui/main.py", line  
    137, in main  
        render()  
      File "/usr/lib/pymodules/python2.6/pybootchartgui/main.py", line  
    128, in render  
        batch.render(writer, res, options, filename)  
      File "/usr/lib/pymodules/python2.6/pybootchartgui/batch.py", line  
    41, in render  
        draw.render(ctx, options, *res)  
      File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line  
    282, in render  
        draw_chart(ctx, IO_COLOR, True, chart_rect, [(sample.time,  
    sample.util) for sample in disk_stats], proc_tree)  
      File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line  
    201, in draw_chart  
        yscale = float(chart_bounds[3]) / max(y for (x,y) in data)  
    ZeroDivisionError: float division   
这个跟在python2.7下执行时是一样的。解决办法有两种:

1)、到这个链接去下载draw.py,parsing.py,samples.py三个文件,然后替换ubuntu下/usr/share/pyshared/pybootchartgui/ 目录下对应的文件

2)、考虑到1)中的下载链接保不齐啥时就掉链子了,因此给个彻底的解决,直接修改ubuntu下/usr/share/pyshared/pybootchartgui/目录的draw.py,parsing.py,samples.py三个文件,分别修改如下:

draw.py:
    将200,201行由:  
    xscale = float(chart_bounds[2]) / max(x for (x,y) in data)  
    yscale = float(chart_bounds[3]) / max(y for (x,y) in data)  
    改为:  
    xscale = float(chart_bounds[2]) / max(0.00001, max(x for (x,y) in data))  
    yscale = float(chart_bounds[3]) / max(0.00001, max(y for (x,y) in data))  
parsing.py:
在156行后添加:  
    if interval == 0:  
        interval = 1
修改后如下:  
    sums = [ a - b for a, b in zip(sample1.diskdata, sample2.diskdata) ] 
    if interval == 0:
        interval = 1

samples.py:
在81行后添加:  
    if interval == 0:  
        interval = 1
修改后如下:
    def calc_load(self, userCpu, sysCpu, interval):
        if interval == 0: <br>  
            interval = 1  

2、解决问题1之后,再次执行命令:
$bootchart ./bootchart.tgz   
出现如下错误:
Traceback (most recent call last):
  File "/usr/bin/bootchart", line 23, in <module>
    sys.exit(main())
  File "/usr/lib/pymodules/python2.6/pybootchartgui/main.py", line 137, in main
    render()
  File "/usr/lib/pymodules/python2.6/pybootchartgui/main.py", line 128, in render
    batch.render(writer, res, options, filename)
  File "/usr/lib/pymodules/python2.6/pybootchartgui/batch.py", line 41, in render
    draw.render(ctx, options, *res)
  File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line 299, in render
    draw_process_bar_chart(ctx, proc_tree, times, curr_y + bar_h, w, h)
  File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line 319, in draw_process_bar_chart
    draw_processes_recursively(ctx, root, proc_tree, y, proc_h, chart_rect)
  File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line 357, in draw_processes_recursively
    child_x, child_y = draw_processes_recursively(ctx, child, proc_tree, next_y, proc_h, rect)
  File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line 349, in draw_processes_recursively
    draw_process_activity_colors(ctx, proc, proc_tree, x, y, w, proc_h, rect)
  File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line 376, in draw_process_activity_colors
    state = get_proc_state( sample.state )
  File "/usr/lib/pymodules/python2.6/pybootchartgui/draw.py", line 105, in get_proc_state
    return "RSDTZXW".index(flag) + 1
ValueError: substring not found
解决办法是修改文件:/usr/lib/pymodules/python2.6/pybootchartgui/draw.py,改动如下:
将105行:  
return "RSDTZXW".index(flag) + 1  
改为:  
return "RSDTZXW".find(flag) + 1
至此,再次执行命令:

$bootchart ./bootchart.tgz   
期待已久的bootchart.png就生成啦

参考文章:

http://blog.csdn.net/harry_helei/article/details/7281356

https://groups.google.com/forum/?fromgroups=#!topic/android-kernel/mdGQZzVODMQ

https://bugs.launchpad.net/ubuntu/+source/bootchart/+bug/580560
————————————————
版权声明:本文为CSDN博主「harry_helei」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/harry_helei/article/details/8545032

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值