1# 性能打点跟踪开发指导 2 3## 简介 4 5hiTraceMeter为开发者提供系统性能打点接口。开发者通过在自己的业务逻辑中的关键代码位置调用HiTraceMeter接口提供的API接口,能够有效跟踪进程轨迹、查看系统性能。 6 7## 基本概念 8 9- **hiTraceMeter Tag** 10 11 跟踪数据使用类别分类,称作hiTraceMeter Tag或hiTraceMeter Category,一般每个软件子系统对应一个Tag,该Tag在打点API中以类别Tag参数传入。hiTraceMeter命令行工具采集跟踪数据时,只采集给定的Tag类别选项指定的跟踪数据。 12 13## 实现原理 14 15- 应用程序通过hiTraceMeter函数接口进行打点,hiTraceMeter函数将跟踪数据通过内核sysfs文件接口输出到内核的ftrace数据缓冲区。 16- hiTraceMeter命令行工具读取内核ftrace缓冲区中的跟踪数据,将文本格式的跟踪数据保存到设备侧的文件中。 17 18## 约束与限制 19 20- 由于JS程序的异步IO特性,现在hiTraceMeter只提供了异步接口。 21 22## 接口说明 23 24性能打点跟踪接口由hiTraceMeter模块提供,详细API请参考[性能打点跟踪API参考](../reference/apis/js-apis-hitracemeter.md)。 25 26**性能打点跟踪接口功能介绍:** 27 28| 接口名 | 返回值 | 描述 | 29| ---------------------------------------------------------------------------- | --------- | ------------ | 30| hiTraceMeter.startTrace(name: string, taskId: number) | void | 标记一个预跟踪耗时任务的开始。taskId是trace中用来表示关联的ID,如果有多个name相同的任务是并行执行的,则每次调用startTrace的taskId不同。如果具有相同name的任务是串行执行的,则taskId可以相同。 | 31| hiTraceMeter.finishTrace(name: string, taskId: number) | void | name和taskId必须与流程开始的hiTraceMeter.startTrace对应参数值保持一致。 | 32| hiTraceMeter.traceByValue(name: string, value: number) | void | 用来标记一个预跟踪的数值变量,该变量的数值会不断变化。| 33 34## 开发步骤 35 36在应用启动执行页面加载后,开始分布式跟踪,完成业务之后,停止分布式跟踪。 37 381. 新建工程,并在业务中调用hiTraceMeter接口,进行性能打点跟踪。 39 40 - **ArkTS应用工程** 41 42 新建一个ArkTS应用工程,在“Project”窗口点击“entry > src > main > ets > pages > index”,打开工程中的“index.ets”文件,在页面执行加载后,在自己的业务中调用hiTraceMeter的接口,进行性能打点跟踪,以任务名name为HITRACE_TAG_APP为例 示例代码如下: 43 44 ```ts 45 import hitrace from '@ohos.hiTraceMeter'; 46 47 @Entry 48 @Component 49 struct Index { 50 @State message: string = 'Hello World'; 51 52 build() { 53 Row() { 54 Column() { 55 Text(this.message) 56 .fontSize(50) 57 .fontWeight(FontWeight.Bold) 58 .onClick(() => { 59 this.message = 'Hello ArkUI'; 60 61 // 跟踪并行执行的同名任务 62 hitrace.startTrace("HITRACE_TAG_APP", 1001); 63 // 业务流程 64 console.log(`HITRACE_TAG_APP running`); 65 66 // 第二个跟踪任务开始,同时第一个跟踪的同名任务还没结束,出现了并行执行,对应接口的taskId需要不同。 67 hitrace.startTrace("HITRACE_TAG_APP", 1002); 68 // 业务流程 69 console.log(`HITRACE_TAG_APP running`); 70 71 hitrace.finishTrace("HITRACE_TAG_APP", 1001); 72 hitrace.finishTrace("HITRACE_TAG_APP", 1002); 73 74 // 跟踪串行执行的同名任务,taskId可以不同,也可以相同 75 hitrace.startTrace("HITRACE_TAG_APP", 1003); 76 // 业务流程 77 console.log(`HITRACE_TAG_APP running`); 78 //第一个跟踪的任务结束 79 hitrace.finishTrace("HITRACE_TAG_APP", 1003); 80 81 // 第二个跟踪任务开始,同名的待跟踪任务串行执行,且taskId不同 82 hitrace.startTrace("HITRACE_TAG_APP", 1004); 83 // 业务流程 84 console.log(`HITRACE_TAG_APP running`); 85 let traceCount = 3; 86 hitrace.traceByValue("myTestCount", traceCount); 87 hitrace.finishTrace("HITRACE_TAG_APP", 1004); 88 89 // 第三个跟踪任务开始,同名的待跟踪任务串行执行,且taskId与上一个相同 90 hitrace.startTrace("HITRACE_TAG_APP", 1004); 91 // 业务流程 92 console.log(`HITRACE_TAG_APP running`); 93 //第三个跟踪的任务结束 94 hitrace.finishTrace("HITRACE_TAG_APP", 1004); 95 96 }) 97 } 98 .width('100%') 99 } 100 .height('100%') 101 } 102 } 103 ``` 104 105 - **JS应用工程** 106 107 新建一个JS应用工程,在“Project”窗口点击“entry > src > main > js > default > pages > index”,打开工程中的“index.js”文件,在页面执行加载后,在自己的业务中调用hiTraceMeter的接口,进行性能打点跟踪,示例代码如下: 108 109 ```js 110 import hiTraceMeter from '@ohos.hiTraceMeter' 111 112 export default { 113 data: { 114 title: "" 115 }, 116 onInit() { 117 this.title = this.$t('strings.world'); 118 119 // 跟踪并行执行的同名任务 120 hiTraceMeter.startTrace("business", 1); 121 // 业务流程 122 console.log(`business running`); 123 hiTraceMeter.startTrace("business", 2); // 第二个跟踪任务开始,同时第一个跟踪的同名任务还没结束,出现了并行执行,对应接口的taskId需要不同。 124 // 业务流程 125 console.log(`business running`); 126 hiTraceMeter.finishTrace("business", 1); 127 // 业务流程 128 console.log(`business running`); 129 hiTraceMeter.finishTrace("business", 2); 130 131 // 跟踪串行执行的同名任务 132 hiTraceMeter.startTrace("business", 1); 133 // 业务流程 134 console.log(`business running`); 135 hiTraceMeter.finishTrace("business", 1); // 第一个跟踪的任务结束 136 // 业务流程 137 console.log(`business running`); 138 hiTraceMeter.startTrace("business", 1); // 第二个跟踪的同名任务开始,同名的待跟踪任务串行执行。 139 // 业务流程 140 console.log(`business running`); 141 142 let traceCount = 3; 143 hiTraceMeter.traceByValue("myTestCount", traceCount); 144 traceCount = 4; 145 hiTraceMeter.traceByValue("myTestCount", traceCount); 146 hiTraceMeter.finishTrace("business", 1); 147 } 148 } 149 ``` 150 1512. 运行项目,点击应用界面上的运行按钮,在shell中依次执行如下命令: 152 153 ```shell 154 hdc shell 155 hitrace --trace_begin app 156 ``` 157 158 执行抓取trace命令后,先在设备中自己的业务里面调用接口,继续依次执行如下命令: 159 160 ```shell 161 hitrace --trace_dump | grep tracing_mark_write 162 hitrace --trace_finish 163 ``` 164 165 抓取trace成功的数据如下所示 166 167 ``` 168 <...>-3310 (-------) [005] .... 351382.921936: tracing_mark_write: S|3310|H:HITRACE_TAG_APP 1001 169 <...>-3310 (-------) [005] .... 351382.922138: tracing_mark_write: S|3310|H:HITRACE_TAG_APP 1002 170 <...>-3310 (-------) [005] .... 351382.922165: tracing_mark_write: F|3310|H:HITRACE_TAG_APP 1001 171 <...>-3310 (-------) [005] .... 351382.922175: tracing_mark_write: F|3310|H:HITRACE_TAG_APP 1002 172 <...>-3310 (-------) [005] .... 351382.922182: tracing_mark_write: S|3310|H:HITRACE_TAG_APP 1003 173 <...>-3310 (-------) [005] .... 351382.922203: tracing_mark_write: F|3310|H:HITRACE_TAG_APP 1003 174 <...>-3310 (-------) [005] .... 351382.922210: tracing_mark_write: S|3310|H:HITRACE_TAG_APP 1004 175 <...>-3310 (-------) [005] .... 351382.922233: tracing_mark_write: C|3310|H:myTestCount 3 176 <...>-3310 (-------) [005] .... 351382.922240: tracing_mark_write: F|3310|H:HITRACE_TAG_APP 1004 177 <...>-3310 (-------) [005] .... 351382.922247: tracing_mark_write: S|3310|H:HITRACE_TAG_APP 1004 178 <...>-3310 (-------) [005] .... 351382.922266: tracing_mark_write: F|3310|H:HITRACE_TAG_APP 1004 179 ``` 180