如何智能识别系统性能抓取对应perfetto trace然后方便分析trace-有源码的简单方案

背景:

正常我们抓取perfetto或者systrace都是采用的手动抓取方式,但是手动抓取方式一般适用于一些必现的场景,但是经常一些性能问题都不是必现的。很可能是偶现的问题。所以针对这种偶现的性能问题我们应该如何做呢?
很多同学会想到是否可以考虑自动化监测的呢?本文就来带大家简单实现一个自动化监测系统性能,当性能低下时候可以实现对系统进行perfetto的抓取trace,方便分析问题。

方案简单设计:

上面背景中聊的性能低下,这里只是个文字描述,具体应该怎么来代表和判断当前系统就是性能低下呢?
这里其实可以有很多个指标维度:
1、cpu使用率过高,可以代表当前cpu负载太大,当前系统可能存在卡顿
2、当前帧率低,或者检测卡顿主线程卡顿等
…等其他指标

这里为了简单起见,我们就简单认为cpu使用率为性能低下的参考指标,也就是cpu使用率太高就代表当前系统性能低,要触发对应的perfetto来抓对应trace
设计如下图:

在这里插入图片描述

实战代码

#!/bin/bash

# 配置参数
THRESHOLD=40
CHECK_INTERVAL=5
TRACE_DURATION=10
TRACE_CONFIG="trace_config.pb"
TRACE_OUTPUT="trace.perfetto-trace"
ADB="adb"
LOG_FILE="cpu_monitor.log"

# 确保adb设备已连接
function check_adb() {
  if ! $ADB get-state 1>/dev/null 2>&1; then
    echo "错误:未找到已连接的Android设备" | tee -a "$LOG_FILE"
    exit 1
  fi
}

# 获取当前CPU使用率(整个系统)
function get_cpu_usage() {
  # 使用临时变量存储adb输出
  local cpu_data1=$(adb shell "cat /proc/stat | grep '^cpu '")
  read -r cpu user nice system idle iowait irq softirq steal guest <<< "$cpu_data1"

  # 计算首次总时间和空闲时间
  total1=$((user + nice + system + idle + iowait + irq + softirq + steal))
  idle1=$idle

  sleep 1

  # 第二次读取
  local cpu_data2=$(adb shell "cat /proc/stat | grep '^cpu '")
  read -r cpu user nice system idle iowait irq softirq steal guest <<< "$cpu_data2"

  total2=$((user + nice + system + idle + iowait + irq + softirq + steal))
  idle2=$idle

  total_diff=$((total2 - total1))
  idle_diff=$((idle2 - idle1))

  if [[ $total_diff -ne 0 ]]; then
    usage=$((100 - (idle_diff * 100) / total_diff))
    echo $usage
  else
    echo 0
  fi
}

# 执行perfetto跟踪
function start_tracing() {
  local timestamp=$(date +%Y%m%d_%H%M%S)
  local output_file="${TRACE_OUTPUT%.*}_${timestamp}.${TRACE_OUTPUT##*.}"

  echo "$(date) - CPU使用率超过阈值,开始抓取跟踪数据..." | tee -a "$LOG_FILE"
  
  # 将配置文件推送到设备
  $ADB push "$TRACE_CONFIG" /data/local/tmp/trace_config.pb || {
    echo "错误:推送配置文件失败" | tee -a "$LOG_FILE"
    return 1
  }

  # 启动perfetto跟踪(后台执行)
  $ADB shell "nohup perfetto -c /data/local/tmp/trace_config.pb -o /data/misc/perfetto-traces/$output_file --txt"

  # 等待跟踪启动
  sleep 2

  # 检查是否启动成功
  if $ADB shell "ps -A | grep -q perfetto"; then
    echo "$(date) - 跟踪已启动,持续${TRACE_DURATION}秒..." | tee -a "$LOG_FILE"
    sleep $TRACE_DURATION
    
    # 停止跟踪(通过发送SIGINT)
    $ADB shell "pkill -SIGINT perfetto"
    
    # 等待文件写入
    sleep 3
    
    # 拉取跟踪文件
    $ADB pull "/data/misc/perfetto-traces/$output_file" . && \
    echo "$(date) - 跟踪文件已保存:$output_file" | tee -a "$LOG_FILE"
  else
    echo "错误:perfetto启动失败" | tee -a "$LOG_FILE"
    return 1
  fi
}

# 主监控循环
function main() {
  check_adb
  echo "$(date) - 启动CPU监控,阈值:${THRESHOLD}%,检测间隔:${CHECK_INTERVAL}秒" | tee -a "$LOG_FILE"
  
  while true; do
    cpu_usage=$(get_cpu_usage)
    echo "$(date) - 当前CPU使用率:${cpu_usage}%" | tee -a "$LOG_FILE"
    
    if [[ $cpu_usage -ge $THRESHOLD ]]; then
      start_tracing
      # 触发后暂停检测防止重复触发
      echo "$(date) - 触发跟踪后暂停检测60秒..." | tee -a "$LOG_FILE"
      sleep 60
    else
      sleep $CHECK_INTERVAL
    fi
  done
}

# 执行主函数
main

上面的代码保存到 cpu_monitor.sh中
验证方法:

  1. 授予执行权限
    chmod +x cpu_monitor.sh

  2. 使用bash明确执行(重要)
    bash cpu_monitor.sh

当然要抓取perfetto可以准备好一个trace_config.pb在当前sh脚本目录,这个前面文章有说过
https://mp.weixin.qq.com/s/ruac6wUPvJSoXJ10ElfFJQ
在这里插入图片描述

执行结果如下:
在这里插入图片描述
我们设定了40%阈值,超过就会马上触发perfetto进行抓取trace,打开trace可以看看:
在这里插入图片描述
更多framework实战干货,请关注下面“千里马学框架”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值