perf-moblie 简介

基于sonic-ios-bridgesonic-android-supply中的性能数据采集功能开发,对 Android 或者 iOS 设备的性能数据以图表形式展示。

背景

虽然我在sonic-ios-bridgesonic-android-supply的基础性能模块已开发完有小半年了,但是目前对里面数据进行可视化展示的话,还是需要部署一套 sonic 服务才能实现,目前个人想搞游戏方面的智能 monkey 小工具,配合性能采集。对于这种情况我不关注云控和 UI 自动化功能,部署全套 Sonic 太浪费,只需要引用 Sonic 的两个生态就好,不然全套下来对开发的调试成本太高。经过对常规的单机几个可视化展示方案调研后,决定采用 go-echarts 完成。

go-echarts 底层采用 html/template,动态的生成 echarts 图表,相关详细介绍可看官方:

go-echarts

设计和实现

一开始参考的是go-echarts/statsview里面的思路,后端采用 go 的 channel,定时采集数据,然后将数据转换成 echarts 的数据形式,也就是 echarts 的 option,通过 gin 暴露出端口,通过 go-echarts 里的 JS 注入功能,注入一个定时函数,定时访问这些 gin 接口。

后来发现对于 iOS 会有大坑,由于 iOS 的 com.apple.instruments.server.services.sysmontap 服务采集的数据会有失帧,所以前端访问的时候,会出现整个某些批次的接口访问被阻塞,进而影响到整个页面。所以后面参考了go-echarts-ws 的做法,将 http api 改成 ws 服务,前端建立 ws 连接,并设置接收数据的回调(接收到数据后,动态的更新 option),当后端的性能数据更新后会将数据发送到 ws 里。

核心代码

官方的 base 模板里的 option 操作会影响到后续动态页面的渲染,需要改成类似如下的模板 (把 option 删除就行):

var BaseTpl = `
{{- define "base" }}
<div class="container">
    <div class="item" id="{{ .ChartID }}" style="width:{{ .Initialization.Width }};height:{{ .Initialization.Height }};"></div>
</div>
<script type="text/javascript">
    "use strict";
    let goecharts_{{ .ChartID | safeJS }} = echarts.init(document.getElementById('{{ .ChartID | safeJS }}'), "{{ .Theme }}");
    let action_{{ .ChartID | safeJS }} = {{ .JSONNotEscapedAction | safeJS }};
    goecharts_{{ .ChartID | safeJS }}.dispatchAction(action_{{ .ChartID | safeJS }});
    {{- range .JSFunctions.Fns }}
    {{ . | safeJS }}
    {{- end }}
</script>
{{ end }}
`

perfdata 数据转换,以安卓应用内存为例:

line := getLineTemplate(title) //生成表单
if data.Process.MemInfo != nil {
    eData.XAxis = append(eData.XAxis, time.Unix(data.Process.MemInfo.TimeStamp/1000, 0).Format("2006-01-02 15:04:05")) //设置XAxis
    if eData.Series["pss"] == nil {
        eData.Series["pss"] = []opts.LineData{}
    }
    eData.Series["pss"] = append(eData.Series["pss"], opts.LineData{Value: data.Process.MemInfo.TotalPSS}) // 设置Series,如果有多个,仿照上面的来多个put就行
}
// 动态赋值
for key, value := range eData.Series {
    line = line.SetXAxis(eData.XAxis).AddSeries(key, value)
}
line.Validate() //只有调用了这个方法,后面才能正常的序列化
err = conn.WriteJSON(line.JSON()) // 发送到ws conn
if err != nil {
    panic(err)
}

使用

perf-moblie releases中获取最新版本,以下是简单使用参考,详细可查看 readme

Android

输入指令

perf-moblie android

然后在浏览器中访问默认的 (http://127.0.0.1:8081) ,可以获取到默认的系统 CPU、系统内存、系统网络数据使用情况


iOS

输入指令

perf-moblie ios

然后在浏览器中访问默认的 (http://127.0.0.1:8081) ,可以获取到默认的系统 CPU、系统内存、FPS、系统 GPU 使用情况

Thanks


↙↙↙阅读原文可查看相关链接,并与作者交流