• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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