1# Using HiTraceMeter (ArkTS) 2 3<!--Kit: Performance Analysis Kit--> 4<!--Subsystem: HiviewDFX--> 5<!--Owner: @qq_437963121--> 6<!--Designer: @MontSaintMichel--> 7<!--Tester: @gcw_KuLfPSbe--> 8<!--Adviser: @foryourself--> 9 10## Overview 11 12HiTraceMeter provides APIs for system performance tracing. You can call the APIs at key code to track processes and check system and application performance. 13 14 15## Available APIs 16 17The performance tracing APIs are provided by the **HiTraceMeter** module. For details, see [@ohos.hiTraceMeter (Performance Tracing)](../reference/apis-performance-analysis-kit/js-apis-hitracemeter.md). 18 19| API| Description| 20| -------- | -------- | 21| hiTraceMeter.startSyncTrace(level: HiTraceOutputLevel, name: string, customArgs?: string): void | Starts a synchronous time slice trace with the trace output level specified.<br>**Note**: This API is supported since API version 19.| 22| hiTraceMeter.finishSyncTrace(level: HiTraceOutputLevel): void | Stops a synchronous time slice trace with the trace output level specified.<br>The value of **level** must be the same as that of **startSyncTrace**.<br>**Note**: This API is supported since API version 19.| 23| hiTraceMeter.startAsyncTrace(level: HiTraceOutputLevel, name: string, taskId: number, customCategory: string, customArgs?: string): void | Starts an asynchronous time slice trace with the trace output level specified.<br>If multiple tracing tasks with the same name need to be performed at the same time, different task IDs must be specified through **taskId**. If the tracing tasks with the same name are not performed at the same time, the same task ID can be used.<br>**Note**: This API is supported since API version 19.| 24| hiTraceMeter.finishAsyncTrace(level: HiTraceOutputLevel, name: string, taskId: number): void | Stops an asynchronous time slice trace with the trace output level specified.<br>Stops a tracing task. The values of **name** and **taskId** must be the same as those in **startAsyncTrace**.<br>**Note**: This API is supported since API version 19.| 25| hiTraceMeter.traceByValue(level: HiTraceOutputLevel, name: string, count: number): void | Traces an integer with the trace output level specified.<br>**name** indicates the name of an integer variable to trace, and **count** indicates the integer value.<br>**Note**: This API is supported since API version 19.| 26| hiTraceMeter.isTraceEnabled(): boolean | Checks whether application trace capture is enabled.<br>When it is enabled, **true** is returned; when it is disabled or stopped, **false** is returned. In this case, calling the HiTraceMeter API does not take effect.<br>**Note**: This API is supported since API version 19.| 27 28> **NOTE** 29> 30> The vertical bar (|) is used as the separator in [user-mode trace format](hitracemeter-view.md#user-mode-trace-format). Therefore, the string parameters passed by the HiTraceMeter APIs must exclude this character to avoid trace parsing exceptions. 31 32 33### API Types 34 35HiTraceMeter APIs are classified into three types: synchronous timeslice tracing APIs, asynchronous timeslice tracing APIs, and integer tracing APIs. HiTraceMeter APIs are synchronous. The synchronous and asynchronous modes describe the traced services. The synchronous timeslice tracing APIs are used for synchronous services, and the asynchronous timeslice tracing APIs are used for asynchronous services. HiTraceMeter APIs can be used with [HiTraceChain](hitracechain-guidelines-arkts.md) to associate and analyze logging across devices, processes, or threads. 36 37 38### Use Scenarios 39 40- Synchronous timeslice tracing APIs: 41 The **startSyncTrace** and **finishSyncTrace** APIs must be used sequentially for logging during sequential execution. If they are not called in the correct order, the trace file will appear abnormal in visualization tools such as SmartPerf. 42 43- Asynchronous timeslice tracing APIs: 44 The **startAsyncTrace** API is called to start logging before an asynchronous operation is performed, and the **finishAsyncTrace** API is called to end logging after the asynchronous operation is performed. 45 During trace parsing, different asynchronous traces are identified by the **name** and **taskId** parameters. These two APIs must be used in sequence as a pair, with the same **name** and **taskId** passed. 46 Different **name** and **taskId** values must be used for different asynchronous processes. However, the same **name** and **taskId** values can be used if asynchronous processes do not occur at the same time. 47 If the API is called incorrectly, the trace file will appear abnormal in visualization tools such as SmartPerf. 48 49- Integer tracing APIs: 50 The APIs are used to trace integer variables. The **traceByValue** API is called when integer values change. You can view the change in the lane diagram of SmartPerf. The values during the interval between the start of data collection and the first logging cannot be viewed. 51 52 53### Parameter Description 54 55| Name| Type| Mandatory| Description| 56| -------- | -------- | -------- | -------- | 57| level | enum | Yes| Trace output level. Trace data whose levels are lower than the system threshold will not be output.<br>By default, the log version threshold is **INFO**, and the nolog version threshold is **COMMERCIAL**.| 58| name | string | Yes| Name of the task or integer variable to trace.| 59| taskId | number | Yes| Task ID for association. If multiple tasks with the same name are executed concurrently, different task IDs must be set when the **startAsyncTrace** API is called.| 60| count | number | Yes| Value of an integer variable.| 61| customCategory | string | Yes| Custom category name, which is used to collect asynchronous trace data of the same type.<br>If the category is not required, pass in an empty string.| 62| customArgs | string | No| Custom key-value pair. If there are multiple key-value pairs, separate them with commas (,), for example, **key1=value1,key2=value2**.<br>If this parameter is not required, do not pass in it or pass in an empty string.| 63 64> **NOTE** 65> 66> The maximum length of a [user-mode trace](hitracemeter-view.md#user-mode-trace-format) is 512 characters. Excess characters will be truncated. Therefore, it is recommended that the total length of the **name**, **customCategory**, and **customArgs** fields be less than or equal to 420 characters. 67 68 69## How to Develop 70 71The following is an example of an ArkTS application that uses the HiTraceMeter APIs. 72 73 74### Step 1: Creating a Project 75 761. Create a project in DevEco Studio and select **Empty Ability**. The project directory structure is as follows: 77 78 ```text 79 ├── entry 80 │ ├── src 81 │ ├── main 82 │ │ ├── ets 83 │ │ │ ├── entryability 84 │ │ │ │ └── EntryAbility.ets 85 │ │ │ ├── entrybackupability 86 │ │ │ │ └── EntryBackupAbility.ets 87 │ │ │ └── pages 88 │ │ │ └── Index.ets 89 ``` 90 912. In the **entry/src/main/ets/pages/index.ets** file, use the HiTraceMeter API in the processing service of the text click event. The sample code is as follows: 92 93 ```ts 94 import { hiTraceMeter, hilog } from '@kit.PerformanceAnalysisKit'; 95 96 @Entry 97 @Component 98 struct Index { 99 @State message: string = 'Hello World'; 100 101 build() { 102 Row() { 103 Column() { 104 Text(this.message) 105 .fontSize(50) 106 .fontWeight(FontWeight.Bold) 107 .onClick(() => { 108 this.message = (this.message == 'Hello HiTrace') ? 'Hello World' : 'Hello HiTrace'; 109 const COMMERCIAL = hiTraceMeter.HiTraceOutputLevel.COMMERCIAL; 110 111 let traceCount = 0; 112 // Start the first asynchronous tracing task. 113 hiTraceMeter.startAsyncTrace(COMMERCIAL, 'myTestAsyncTrace', 1001, 'categoryTest', 'key=value'); 114 // Start counting the task. 115 traceCount++; 116 hiTraceMeter.traceByValue(COMMERCIAL, 'myTestCountTrace', traceCount); 117 // Keep the service process running. 118 hilog.info(0x0000, 'testTrace', 'myTraceTest running, taskId: 1001'); 119 120 // Start the second asynchronous tracing task with the same name while the first task is still running. The tasks are running concurrently and therefore their taskId must be different. 121 hiTraceMeter.startAsyncTrace(COMMERCIAL, 'myTestAsyncTrace', 1002, 'categoryTest', 'key=value'); 122 // Start counting the task. 123 traceCount++; 124 hiTraceMeter.traceByValue(COMMERCIAL, 'myTestCountTrace', traceCount); 125 // Keep the service process running. 126 hilog.info(0x0000, 'testTrace', 'myTraceTest running, taskId: 1002'); 127 128 // Stop the asynchronous tracing task whose taskId is 1001. 129 hiTraceMeter.finishAsyncTrace(COMMERCIAL, 'myTestAsyncTrace', 1001); 130 // Stop the asynchronous tracing task whose taskId is 1002. 131 hiTraceMeter.finishAsyncTrace(COMMERCIAL, 'myTestAsyncTrace', 1002); 132 133 // Start a synchronous tracing task. 134 hiTraceMeter.startSyncTrace(COMMERCIAL, 'myTestSyncTrace', 'key=value'); 135 // Keep the service process running. 136 hilog.info(0x0000, 'testTrace', 'myTraceTest running, synchronizing trace'); 137 // Stop the synchronous tracing task. 138 hiTraceMeter.finishSyncTrace(COMMERCIAL); 139 140 // If the process of generating the parameters passed by the HiTraceMeter API is complex, you can use isTraceEnabled to determine whether trace capture is enabled. 141 // Avoid performance loss when application trace capture is not enabled. 142 if (hiTraceMeter.isTraceEnabled()) { 143 let customArgs = 'key0=value0'; 144 for(let index = 1; index < 10; index++) { 145 customArgs += `,key${index}=value${index}` 146 } 147 hiTraceMeter.startAsyncTrace(COMMERCIAL, 'myTestAsyncTrace', 1003, 'categoryTest', customArgs); 148 hilog.info(0x0000, 'testTrace', 'myTraceTest running, taskId: 1003'); 149 hiTraceMeter.finishAsyncTrace(COMMERCIAL, 'myTestAsyncTrace', 1003); 150 } else { 151 hilog.info(0x0000, 'testTrace', 'myTraceTest running, trace is not enabled'); 152 } 153 }) 154 } 155 .width('100%') 156 } 157 .height('100%') 158 } 159 } 160 ``` 161 162 163### Step 2: Collecting and Viewing Trace Information 164 1651. Run the following command in DevEco Studio Terminal to enable trace capture: 166 167 ```shell 168 PS D:\xxx\xxx> hdc shell 169 $ hitrace --trace_begin app 170 ``` 171 1722. Click the **Run** button in DevEco Studio to run the project. Then, click "Hello world" to execute the service logic that contains HiTraceMeter logging. Run the following command to capture trace data and filter the trace data using the keyword **myTest** (the name field prefix passed by the logging API is **myTest** in this example). 173 174 ```shell 175 $ hitrace --trace_dump | grep myTest 176 ``` 177 178 The sample trace data is as follows: 179 180 ```text 181 e.myapplication-39945 ( 39945) [010] .... 347921.342267: tracing_mark_write: S|39945|H:myTestAsyncTrace|1001|M62|categoryTest|key=value 182 e.myapplication-39945 ( 39945) [010] .... 347921.342280: tracing_mark_write: C|39945|H:myTestCountTrace|1|M62 183 e.myapplication-39945 ( 39945) [010] .... 347921.342327: tracing_mark_write: S|39945|H:myTestAsyncTrace|1002|M62|categoryTest|key=value 184 e.myapplication-39945 ( 39945) [010] .... 347921.342333: tracing_mark_write: C|39945|H:myTestCountTrace|2|M62 185 e.myapplication-39945 ( 39945) [010] .... 347921.342358: tracing_mark_write: F|39945|H:myTestAsyncTrace|1001|M62 186 e.myapplication-39945 ( 39945) [010] .... 347921.342365: tracing_mark_write: F|39945|H:myTestAsyncTrace|1002|M62 187 e.myapplication-39945 ( 39945) [010] .... 347921.342387: tracing_mark_write: B|39945|H:myTestSyncTrace|M62|key=value 188 e.myapplication-39945 ( 39945) [010] .... 347921.342586: tracing_mark_write: S|39945|H:myTestAsyncTrace|1003|M62|categoryTest|key0=value0,key1=value1,key2=value2,key3=value3,key4=value4,key5=value5,key6=value6,key7=value7,key8=value8,key9=value9 189 e.myapplication-39945 ( 39945) [010] .... 347921.342615: tracing_mark_write: F|39945|H:myTestAsyncTrace|1003|M62 190 ``` 191 192 In the trace data line, **tracing_mark_write** indicates the logging event type. This event is used by the HiTraceMeter API in applications. The data before the logging event type is the thread name, thread ID, process ID, CPU, and logging time (from the startup time to the current time, in seconds). For the data that follows the logging event type, see [User-Mode Trace Format](hitracemeter-view.md#user-mode-trace-format). 193 194 195### Step 3: Stoping Trace Capture 196 197 1981. Run the following command to stop trace capture of the application. 199 200 ```shell 201 $ hitrace --trace_finish 202 ``` 203 2042. Click "Hello World" on the application screen again. The trace capture of the application is disabled, and the **isTraceEnabled** API returns **false**. In the **Log** window of the DevEco Studio, input the keyword **not enabled** for filtering and the following log is displayed. 205 206 ```text 207 myTraceTest running, trace is not enabled 208 ``` 209 210 > **NOTE** 211 > 212 > In the log version, after the **hitrace --trace_finish** command is used to stop capture, the snapshot mode is automatically started and trace capture is enabled. In this case, the **isTraceEnabled** API returns **true**, and the preceding log is not printed. 213