1fb726d48Sopenharmony_ci# TraceStreamer工具说明 2fb726d48Sopenharmony_ciTraceStreamer是一个trace数据解析程序,可以将一个trace文本文件或者基于proto序列化的二进制文件转换成为sqlite数据库的形式。 TraceStreamer使用C++实现,支持在ohos, linux, mac等系统上使用,具有良好的跨平台特性。 3fb726d48Sopenharmony_ci 4fb726d48Sopenharmony_ci## 关于TraceStreamer的使用说明 5fb726d48Sopenharmony_ciTraceStreamer工具可以2种方式使用: 6fb726d48Sopenharmony_ci1. 可以将系统离线trace文件解析并转为db,此工具支持基于文本的trace和基于proto的trace。 7fb726d48Sopenharmony_ci2. TraceStreamer工具还可以WebAssembly的方式在浏览器中运行,需提供相关接口给js文件。 8fb726d48Sopenharmony_ci 9fb726d48Sopenharmony_ci### 导出db模式 10fb726d48Sopenharmony_ci在导出db模式下,通过下面的指令: 11fb726d48Sopenharmony_ci``` 12fb726d48Sopenharmony_ci./trace_streamer trace文件路径名 -e 导出db路径名.db 13fb726d48Sopenharmony_ci``` 14fb726d48Sopenharmony_ci可以将trace文件转为db文件。 15fb726d48Sopenharmony_ci本应用支持在ohos, linux, mac使用。 16fb726d48Sopenharmony_ci在数据导出之后,会在本地目录下生成一个trace_streamer.log文件,在导出db的目录下生成一个数据库文件同名,.db.ohos.ts后缀的文件。 17fb726d48Sopenharmony_ci文件内容如下: 18fb726d48Sopenharmony_ci``` 19fb726d48Sopenharmony_ci当前时间戳:执行结果(数字) 20fb726d48Sopenharmony_ci应用运行时间 21fb726d48Sopenharmony_ci``` 22fb726d48Sopenharmony_ci执行结果解释如下: 23fb726d48Sopenharmony_ci``` 24fb726d48Sopenharmony_ci0 代表执行成功 1 表示输入文件不匹配, 2 表示解析错误, 3其他错误。 25fb726d48Sopenharmony_ci``` 26fb726d48Sopenharmony_ci#### __关于db文件的说明__ 27fb726d48Sopenharmony_ci可以使用sqliteexport或DB Browser for SQLite工具加载生成的db,通过查看stat表,可以浏览当前数据一共有多少类数据,各类数据都收到多少条,数据是否正常等情况。在meta表会记录数据库导出时的一些系统信息,比如导入和导出的文件全路径,解析时间等信息。 28fb726d48Sopenharmony_cimeta表可以选择不导出(有些情况下会暴露系统敏感信息),在导出时添加 -nm选项即可。 29fb726d48Sopenharmony_ci更多db文件的介绍,可以参考[doc/des_tables.md](./doc/des_tables.md)。 30fb726d48Sopenharmony_ci 31fb726d48Sopenharmony_ci### 内置浏览器模式 32fb726d48Sopenharmony_ciTraceStreamer可以WebAssembly方式在浏览器中运行,相关接口在wasm模式下生成的trace_streamer_builtin.js文件中,js可以使用的接口如下使用如下接口访问trace_streamer: 33fb726d48Sopenharmony_ci``` 34fb726d48Sopenharmony_ciextern "C" { 35fb726d48Sopenharmony_ci/* 初始化wasm,在JS中注册回调函数,并返回一段可复用的内存空间,由JS调用 36fb726d48Sopenharmony_ci * 37fb726d48Sopenharmony_ci * @ replyFunction: 回调函数,返回json格式的数据。 38fb726d48Sopenharmony_ci * @ reqBufferSize: js在wasm中申请的内存大小。 39fb726d48Sopenharmony_ci * @ replyTLVFunction: 回调函数,返回proto格式的sql查询结果。 40fb726d48Sopenharmony_ci * @ ffrtConvertedReply: 回调函数,返回ffrt转换后生成的新trace文件。 41fb726d48Sopenharmony_ci * return: 返回一段内存地址给JS 42fb726d48Sopenharmony_ci*/ 43fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE uint8_t *Initialize(uint32_t reqBufferSize, 44fb726d48Sopenharmony_ci ReplyFunction replyFunction, 45fb726d48Sopenharmony_ci TLVReplyFunction replyTLVFunction, 46fb726d48Sopenharmony_ci ReplyFunction ffrtConvertedReply) 47fb726d48Sopenharmony_ci 48fb726d48Sopenharmony_ciextern "C" { 49fb726d48Sopenharmony_ci/* 初始化wasm,在JS中注册大文件切割或按时间切割文件的回调函数,并返回一段可复用的内存空间,由JS调用 50fb726d48Sopenharmony_ci * 51fb726d48Sopenharmony_ci * @ splitFileFunction: 回调函数, 返回大文件切割,或者按时间切割后生成的数据。 52fb726d48Sopenharmony_ci * @ reqBufferSize: js在wasm中申请的内存大小。 53fb726d48Sopenharmony_ci * return: 返回一段内存地址给JS 54fb726d48Sopenharmony_ci*/ 55fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE uint8_t *InitializeSplitFile(SplitFileFunction splitFileFunction, uint32_t reqBufferSize) 56fb726d48Sopenharmony_ci 57fb726d48Sopenharmony_ci/* 通知wasm,按时间切割文件的时间信息已发送,并且通知时间信息大小为dataLen字节 58fb726d48Sopenharmony_ci * 59fb726d48Sopenharmony_ci * @ dataLen 切割文件的时间信息长度。 时间数据保存在InitializeSplitFile接口申请的内存中。数据格式:"startTS;endTS;"。 60fb726d48Sopenharmony_ci * return: bool类型。解析切割时间信息成功返回true,否则返回false。 61fb726d48Sopenharmony_ci*/ 62fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerSplitFileEx(int dataLen) 63fb726d48Sopenharmony_ci 64fb726d48Sopenharmony_ci/* 通知wasm,按时间切割的文件信息已发送,并且通知发送的文件信息大小为dataLen字节 65fb726d48Sopenharmony_ci * 66fb726d48Sopenharmony_ci * @ dataLen 已经发送的被切割的文件数据长度,数据内容保存在InitializeSplitFile接口申请的内存中。 67fb726d48Sopenharmony_ci * @ isFinish bool类型, 被切割的文件数据发送完成为true, 否则为false。 68fb726d48Sopenharmony_ci * return: 切割成功返回0,否则返回-1。 69fb726d48Sopenharmony_ci*/ 70fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerReciveFileEx(int32_t dataLen, int32_t isFinish) 71fb726d48Sopenharmony_ci 72fb726d48Sopenharmony_ci/* JS在wasm中申请一段内存,用于传输config配置信息。如: ffrt convert开关,animation开关,taskpool开关等 73fb726d48Sopenharmony_ci * 74fb726d48Sopenharmony_ci * @ reqBufferSize JS准备申请的内存大小。 75fb726d48Sopenharmony_ci * return: 返回一段内存地址给JS。 76fb726d48Sopenharmony_ci*/ 77fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE uint8_t *InitializeParseConfig(uint32_t reqBufferSize) 78fb726d48Sopenharmony_ci 79fb726d48Sopenharmony_ci/* JS通知wasm已经发送了config信息,并通知发送的数据大小。 wasm解析config信息。 80fb726d48Sopenharmony_ci * 81fb726d48Sopenharmony_ci * @ dataLen JS发送config信息大小, 数据内容保存在InitializeParseConfig接口申请的内存中。 82fb726d48Sopenharmony_ci * return: wasm解析config信息成功返回0,否则返回-1。 83fb726d48Sopenharmony_ci*/ 84fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerParserConfigEx(int dataLen) 85fb726d48Sopenharmony_ci 86fb726d48Sopenharmony_ci/* JS通知wasm已经发送大文件切割的时间信息,并通知发送的数据大小。 wasm解析大文件切割的时间信息。 87fb726d48Sopenharmony_ci * 88fb726d48Sopenharmony_ci * @ dataLen JS发送大文件切割时间信息长度。时间信息格式为proto数据的1024头,保存在InitializeSplitFile接口申请的内存中。 89fb726d48Sopenharmony_ci * return: wasm解析大文件切割时间信息成功返回0,否则返回-1。 90fb726d48Sopenharmony_ci*/ 91fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerGetLongTraceTimeSnapEx(int dataLen) 92fb726d48Sopenharmony_ci 93fb726d48Sopenharmony_ci/* JS通知wasm已经发送大文件切割的文件数据,并通知发送的数据大小。 94fb726d48Sopenharmony_ci * 95fb726d48Sopenharmony_ci * @ dataLen JS发送大文件切割文件数据大小。 96fb726d48Sopenharmony_ci * @ isFinish JS发送数据是否结束。 97fb726d48Sopenharmony_ci * @ pageNum 准备按照第pageNum个文件的时间范围,切割大文件。 98fb726d48Sopenharmony_ci * return: wasm解析大文件切割时间信息成功返回0,否则返回-1。 99fb726d48Sopenharmony_ci*/ 100fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerLongTraceSplitFileEx(int dataLen, int32_t isFinish, uint32_t pageNum) 101fb726d48Sopenharmony_ci 102fb726d48Sopenharmony_ci/* 导入so重新符号化业务,JS通知wasm申请内存保存导入so的文件名称,并设置导入so重新符号化的回调函数。 103fb726d48Sopenharmony_ci * 104fb726d48Sopenharmony_ci * @ parseELFCallback 回调函数 105fb726d48Sopenharmony_ci * @ reqBufferSize 申请的文件大小 106fb726d48Sopenharmony_ci * return: 返回一段内存给JS。 107fb726d48Sopenharmony_ci*/ 108fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE uint8_t *InitFileName(ParseELFFunction parseELFCallback, uint32_t reqBufferSize) 109fb726d48Sopenharmony_ci 110fb726d48Sopenharmony_ci/* 更新起始结束时间,由JS调用 111fb726d48Sopenharmony_ci * 112fb726d48Sopenharmony_ci * @ len: 起始和结束时间组成的字符串长度 113fb726d48Sopenharmony_ci * return: 成功返回0。 114fb726d48Sopenharmony_ci*/ 115fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int UpdateTraceTime(int len) 116fb726d48Sopenharmony_ci 117fb726d48Sopenharmony_ci/* 设置TraceStreamer和第三方wasm通信的回调函数,并返回一段内存,由JS调用 118fb726d48Sopenharmony_ci * 119fb726d48Sopenharmony_ci * @ sendDataCallBack:与第三方wasm通信的回调函数 120fb726d48Sopenharmony_ci* @ reqBufferSize: 返回的内存长度 121fb726d48Sopenharmony_ci* return: 成功返回0 122fb726d48Sopenharmony_ci*/ 123fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE uint8_t* TraceStreamerSetThirdPartyDataDealer(SendDataCallBack sendDataCallBack, uint32_t reqBufferSize) 124fb726d48Sopenharmony_ci 125fb726d48Sopenharmony_ci/* 设置TraceStreamer可以打印的日志级别,由JS调用 126fb726d48Sopenharmony_ci * 127fb726d48Sopenharmony_ci * @ level: 允许打印日志的最低级别。 128fb726d48Sopenharmony_ci*/ 129fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE void TraceStreamerSetLogLevel(uint32_t level) 130fb726d48Sopenharmony_ci 131fb726d48Sopenharmony_ci/* TraceStreamer的数据解析接口,由JS调用 132fb726d48Sopenharmony_ci * 133fb726d48Sopenharmony_ci* @ dataLen: 需要解析的数据源长度 134fb726d48Sopenharmony_ci* return: 成功返回0,失败返回-1 135fb726d48Sopenharmony_ci*/ 136fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerParseDataEx(int dataLen, bool isFinish) 137fb726d48Sopenharmony_ci 138fb726d48Sopenharmony_ci/* 导入so重新符号化业务的下载so文件接口,由JS调用 139fb726d48Sopenharmony_ci * 140fb726d48Sopenharmony_ci * @ totalLen: 传输的文件总长度。 141fb726d48Sopenharmony_ci * @ fileNameLen: 传输的文件名长度。 142fb726d48Sopenharmony_ci * @ dataLen: 当前调用传输的文件数据长度。 143fb726d48Sopenharmony_ci * @ finish: 当前文件是否传输结束。 144fb726d48Sopenharmony_ci * return: wasm下载并保存该文件成功返回0,失败返回-1 145fb726d48Sopenharmony_ci*/ 146fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int32_t TraceStreamerDownloadELFEx(int32_t totalLen, 147fb726d48Sopenharmony_ci int32_t fileNameLen, 148fb726d48Sopenharmony_ci int32_t dataLen, 149fb726d48Sopenharmony_ci int32_t finish) 150fb726d48Sopenharmony_ci 151fb726d48Sopenharmony_ci/* TraceStreamer停止解析数据,由JS调用 152fb726d48Sopenharmony_ci * 153fb726d48Sopenharmony_ci* return: 成功返回0,失败返回-1 154fb726d48Sopenharmony_ci*/ 155fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerParseDataOver() 156fb726d48Sopenharmony_ci 157fb726d48Sopenharmony_ci/* 数据库操作接口,由JS调用,返回json格式的sql查询结果。 158fb726d48Sopenharmony_ci * 159fb726d48Sopenharmony_ci* @ sqlLen: 需要执行的操作类sql语句长度 160fb726d48Sopenharmony_ci* return: 成功返回0,失败返回-1 161fb726d48Sopenharmony_ci*/ 162fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerSqlOperateEx(int sqlLen) 163fb726d48Sopenharmony_ci 164fb726d48Sopenharmony_ci/*清空wasm内存中的内容,由JS调用 165fb726d48Sopenharmony_ci * 166fb726d48Sopenharmony_ci* return: 成功返回0,失败返回-1 167fb726d48Sopenharmony_ci*/ 168fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerReset() 169fb726d48Sopenharmony_ci 170fb726d48Sopenharmony_ci/*执行查询类sql语句,由JS调用 171fb726d48Sopenharmony_ci * 172fb726d48Sopenharmony_ci* @ sqlLen: 需要执行的查询类sql语句长度 173fb726d48Sopenharmony_ci* return: 成功返回0,失败返回-1 174fb726d48Sopenharmony_ci*/ 175fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerSqlQueryEx(int sqlLen) 176fb726d48Sopenharmony_ci 177fb726d48Sopenharmony_ci/*取消sql查询,由JS调用。 178fb726d48Sopenharmony_ci * 179fb726d48Sopenharmony_ci* return: 成功返回0。 180fb726d48Sopenharmony_ci*/ 181fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerCancel() 182fb726d48Sopenharmony_ci 183fb726d48Sopenharmony_ci/*执行查询类sql语句,由JS调用。返回proto格式的sql查询结果。 184fb726d48Sopenharmony_ci * 185fb726d48Sopenharmony_ci* @ sqlLen: 需要执行的查询类sql语句长度 186fb726d48Sopenharmony_ci* return: 成功返回0,失败返回-1 187fb726d48Sopenharmony_ci*/ 188fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int32_t TraceStreamerSqlQueryToProtoCallback(int32_t sqlLen) 189fb726d48Sopenharmony_ci/*执行metrics数据查询 190fb726d48Sopenharmony_ci * 191fb726d48Sopenharmony_ci* @ sqlLen: 需要执行的查询类sql语句长度 192fb726d48Sopenharmony_ci* return: 成功返回0,失败返回-1 193fb726d48Sopenharmony_ci*/ 194fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int32_t TraceStreamerSqlMetricsQuery(int32_t sqlLen) 195fb726d48Sopenharmony_ci 196fb726d48Sopenharmony_ci/*发送数据给第三方wasm解析,由TraceStreamer调用 197fb726d48Sopenharmony_ci * 198fb726d48Sopenharmony_ci* @ pluginData: 第三方插件的数据源 199fb726d48Sopenharmony_ci* @ len: 数据源长度 200fb726d48Sopenharmony_ci* @ componentName: 第三方插件名称 201fb726d48Sopenharmony_ci* return: 成功返回0 202fb726d48Sopenharmony_ci*/ 203fb726d48Sopenharmony_ciint TraceStreamerPluginOutSendData(const char* pluginData, int len, const std::string componentName) 204fb726d48Sopenharmony_ci 205fb726d48Sopenharmony_ci/*返回解析数据库 206fb726d48Sopenharmony_ci * 207fb726d48Sopenharmony_ci * @ fun: 回调函数,负责返回解析生成的数据库。 208fb726d48Sopenharmony_ci * return: 成功返回0 209fb726d48Sopenharmony_ci*/ 210fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int32_t WasmExportDatabase(ExportDBCallback fun) 211fb726d48Sopenharmony_ci 212fb726d48Sopenharmony_ci/* 初始化配置接口,由JS调用 213fb726d48Sopenharmony_ci * 214fb726d48Sopenharmony_ci* @ dataLen: 配置字符串的长度 215fb726d48Sopenharmony_ci* return: 成功返回0 216fb726d48Sopenharmony_ci*/ 217fb726d48Sopenharmony_ciEMSCRIPTEN_KEEPALIVE int TraceStreamerInitThirdPartyConfig(int dataLen) 218fb726d48Sopenharmony_ci 219fb726d48Sopenharmony_ci} // extern "C" 220fb726d48Sopenharmony_ci``` 221fb726d48Sopenharmony_ci 222fb726d48Sopenharmony_ci### 可以执行如下命令查看应用帮助 223fb726d48Sopenharmony_ci```./trace_streamer --help``` 224fb726d48Sopenharmony_ci 225fb726d48Sopenharmony_ci### TraceStreamer支持解析的事件列表 226fb726d48Sopenharmony_ci通过```./trace_streamer -i``` 227fb726d48Sopenharmony_ci查看支持的事件列表。 228fb726d48Sopenharmony_ci支持的事件列表参见[SupportEventList.md](./doc/des_support_event.md)。 229fb726d48Sopenharmony_ci## TraceStreamer重要概念介绍 230fb726d48Sopenharmony_ci### 进程和线程标识符 231fb726d48Sopenharmony_ci``` 232fb726d48Sopenharmony_ci在通用操作系统中,进程号(pid/tgid)和线程号(tid)可能会被重复用于标识不同的进程或者线程。所以在trace数据源中,进程号(pid)和线程号(tid)也可能被重用。 233fb726d48Sopenharmony_ciTraceStreamer在解析数据过程中,使用ipid(internal pid)唯一标识进程, itid(internal tid)唯一标识线程。 234fb726d48Sopenharmony_ci``` 235fb726d48Sopenharmony_ci### 计量器 236fb726d48Sopenharmony_ci用来记录系统中各种随时间连续变化的数值。例如: CPU的频率, 内存的使用量, 界面刷新频率。 237fb726d48Sopenharmony_ci#### 举例 238fb726d48Sopenharmony_ciCPU频率: 239fb726d48Sopenharmony_ci 240fb726d48Sopenharmony_ci内存占用: 241fb726d48Sopenharmony_ci 242fb726d48Sopenharmony_ci 243fb726d48Sopenharmony_ci### 过滤器 244fb726d48Sopenharmony_ciTraceStreamer设计过程中使用了流式处理的思想,数据从入口进入以后,就像进入一条河流,从上游流向下游,在河道中央有很多过滤器,每种过滤器会将流过的数据中自己关注的内容吸附捕捉到。最终,每个过滤器都拥有了大量同类型的数据,而且这些数据都是按时间序列排列的。TraceStreamer使用filterid来标识同一种用途的数据,可以方便在UI中绘制。 245fb726d48Sopenharmony_ci 246fb726d48Sopenharmony_ci 247fb726d48Sopenharmony_ci## Stat表设计 248fb726d48Sopenharmony_ci具体内容参见 [des_stat](./doc/des_stat.md)。 249fb726d48Sopenharmony_ci## TraceStreamer开发环境搭建和编译运行指引 250fb726d48Sopenharmony_ci 251fb726d48Sopenharmony_ci本应用使用gn作为构建工具。 252fb726d48Sopenharmony_ci### 开发环境 253fb726d48Sopenharmony_ci可以在ubuntu、mac、windows下执行开发和编译,建议使用vscode开发工具。 254fb726d48Sopenharmony_ci在windows平台上,需使用支持c++17标准的clang编译器。 255fb726d48Sopenharmony_ci# 对外部的依赖 256fb726d48Sopenharmony_ci本应用依赖与sqlite、protobuf(htrace解析部分依赖)、nlohmann_json。 257fb726d48Sopenharmony_ci本应用同时依赖于src/protos/protogen.sh目录下文件来生成相关pb.h,pb.cc文件。 258fb726d48Sopenharmony_ci_____ 259fb726d48Sopenharmony_ci 260fb726d48Sopenharmony_ci### 编译linux和Mac应用 261fb726d48Sopenharmony_ci在目录下有build.sh脚本,在不同的平台上会判断系统版本,编译相应系统的应用。 262fb726d48Sopenharmony_ci``` 263fb726d48Sopenharmony_ci./build.sh linux 264fb726d48Sopenharmony_ci./build.sh macx 265fb726d48Sopenharmony_ci``` 266fb726d48Sopenharmony_ci 267fb726d48Sopenharmony_ci### 编译wasm 268fb726d48Sopenharmony_ci``` 269fb726d48Sopenharmony_ci./build.sh wasm 270fb726d48Sopenharmony_ci``` 271fb726d48Sopenharmony_ci 272fb726d48Sopenharmony_ci### 开始编译 273fb726d48Sopenharmony_ci本工具建议独立编译,通过部署第三方依赖库,emsdk,可编译出支持不同平台的应用。 274fb726d48Sopenharmony_ci具体方法可参考[compile_trace_streamer](./doc/compile_trace_streamer.md)。