• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# HiTraceChain开发指导
2
3## 概述
4
5HiTraceChain主要是对于跨设备/跨进程/跨线程的业务流程,通过相同的traceid在整个业务流程中传递,将流程处理过程中的调用关系、各种输出信息关联和展现出来,帮助使用者分析、定位问题和系统调优。
6
7
8## 应用场景
9
10HiTraceChain在产品中应用场景如下,包括:
11
12- 端侧业务流程信息(日志、事件等)关联、上报
13
14- 云侧对上报信息的关联展示和分析,辅助问题定位
15
16- IDE对业务流程详细信息、耗时分布进行调试,辅助系统调优
17
18    **图1** HiTraceChain应用场景
19    ![zh-cn_image_0000001216312860](figures/zh-cn_image_0000001216312860.png)
20
21
22### 业务使用示例
23
24  **图2** 业务调用流程图(跨设备、跨进程同步调用)
25
26  ![zh-cn_image_0000001216632830](figures/zh-cn_image_0000001216632830.png)
27
281. 调试时展示业务流程中的调用关系,进行关键路径分析、功能依赖分析,确定各调用点耗时、调用频率,提前发现性能瓶颈点。
29
30     **图3** 业务调用流程序列图
31     ![zh-cn_image_0000001216792790](figures/zh-cn_image_0000001216792790.png)
32
33
34     **图4** 业务调用流程性能耗时分布
35     ![zh-cn_image_0000001261272659](figures/zh-cn_image_0000001261272659.png)
36
372. 在日志和事件等信息中自动附加traceid信息,便于开发人员综合分析和快速实现问题定界定位。
38
39
40## 接口说明
41
42HiTraceChain提供C++、C接口。上层业务主要使用HiTraceChain跟踪启动、结束接口。
43
44HiTraceChain实现在C层,主要原理是在一次业务调用流程中,利用通信传递traceid,在业务处理前将traceid设置到当前线程的TLS(Thread Local Storage)中,业务处理结束清除当前线程的TLS;这样的话,在业务处理中可以从当前线程的上下文TLS取到traceid,自动附加到日志、事件信息中。
45
46
47### 接口形式对比
48
49  **表1** C++、C的函数接口
50
51|  | **C++** | **C** |
52| -------- | -------- | -------- |
53| **类** | **函数** | **函数** |
54| HiTraceChain | HiTraceId Begin(const std::string& name, int flags) | HiTraceIdStruct HiTraceChainBegin(const char* name, int flags) |
55|  | void End(const HiTraceId& id) | void HiTraceChainEnd(const HiTraceIdStruct* pId) |
56|  | HiTraceId GetId(); | HiTraceIdStruct HiTraceChainGetId() |
57|  | void SetId(const HiTraceId& id) | void HiTraceChainSetId(const HiTraceIdStruct* pId) |
58|  | void ClearId() | void HiTraceChainClearId() |
59|  | HiTraceId CreateSpan() | HiTraceIdStruct HiTraceChainCreateSpan() |
60|  | void Tracepoint(HiTraceTracepointType type, const HiTraceId& id, const char* fmt, ...) | void HiTraceChainTracepoint(HiTraceTracepointType type, const HiTraceIdStruct* pId, const char* fmt, ...) |
61|  | void Tracepoint(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceId& id, const char* fmt, ...) | void HiTraceChainTracepointEx(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceIdStruct* pId, const char* fmt, ...) |
62| HiTraceId | HiTraceId(); | void HiTraceChainInitId(HiTraceIdStruct* pId) |
63|  | HiTraceId(const uint8_t* pIdArray, int len) | HiTraceIdStruct HiTraceChainBytesToId(const uint8_t* pIdArray, int len) |
64|  | bool IsValid() | int HiTraceChainIsValid(const HiTraceIdStruct* pId) |
65|  | bool IsFlagEnabled(HiTraceFlag flag) | int HiTraceChainIsFlagEnabled(const HiTraceIdStruct* pId, HiTraceFlag flag) |
66|  | void EnableFlag(HiTraceFlag flag) | void HiTraceChainEnableFlag(HiTraceIdStruct* pId, HiTraceFlag flag) |
67|  | int GetFlags() | int HiTraceChainGetFlags(const HiTraceIdStruct* pId) |
68|  | void SetFlags(int flags) | void HiTraceChainSetFlags(HiTraceIdStruct* pId, int flags) |
69|  | uint64_t GetChainId() | uint64_t HiTraceChainGetChainId(const HiTraceIdStruct* pId) |
70|  | void SetChainId(uint64_t chainId) | void HiTraceChainSetChainId(HiTraceIdStruct* pId, uint64_t chainId) |
71|  | uint64_t GetSpanId() | uint64_t HiTraceChainGetSpanId(const HiTraceIdStruct* pId) |
72|  | void SetSpanId(uint64_t spanId) | void HiTraceChainSetSpanId(HiTraceIdStruct* pId, uint64_t spanId) |
73|  | uint64_t GetParentSpanId() | uint64_t HiTraceChainGetParentSpanId(const HiTraceIdStruct* pId) |
74|  | void SetParentSpanId(uint64_t parentSpanId) | void HiTraceChainSetParentSpanId(HiTraceIdStruct* pId, uint64_t parentSpanId) |
75|  | int ToBytes(uint8_t* pIdArray, int len) | int HiTraceChainIdToBytes(const HiTraceIdStruct_ pId, uint8_t* pIdArray, int len) |
76
77
78### 接口功能参数
79
80  **表2** 跟踪标志组合类型枚举
81
82| **名称** | **值** | **说明** |
83| -------- | -------- | -------- |
84| HITRACE_FLAG_DEFAULT           | 0      | 缺省标志。       |
85| HITRACE_FLAG_INCLUDE_ASYNC | 1      | 异步调用标志。启动跟踪时,缺省只跟踪同步调用。设置该标志,同时跟踪同步、异步调用。   |
86| HITRACE_FLAG_DONOT_CREATE_SPAN | 1 << 1 | 无分支标志。启动跟踪时,在同步、异步调用时缺省自动创建分支信息。设置该标志,指示不创建分支。     |
87| HITRACE_FLAG_TP_INFO           | 1 << 2 | 埋点标志。启动跟踪式时,缺省不进行埋点。调试场景下设置该标志,在同步、异步调用的收发侧自动埋点,输出埋点信息和时间戳。收发埋点按照client、server分为client send(CS)、server receive(SR)、server send(SS)、client receive(CR)四类信息。一次同步调用输出CS/SR/SS/CR,一次异步调用输出CS/SR/SS三个埋点信息。       |
88| HITRACE_FLAG_NO_BE_INFO        | 1 << 3 | 无起始结束标志。启动跟踪时,缺省打印启动及结束跟踪信息。设置该标志,指示不打印启动及结束跟踪信息。 |
89| HITRACE_FLAG_DONOT_ENABLE_LOG       | 1 << 4 | 日志关联标志。设置该标志,指示隐藏日志中的跟踪信息。  |
90| HITRACE_FLAG_FAULT_TRIGGER   | 1 << 5 | 故障触发标志。预置标志,暂时没有作用。  |
91| HITRACE_FLAG_D2D_TP_INFO       | 1 << 6 | 设备间埋点标志。TP_INFO的一个子集,设置该标志,只进行设备间的调用埋点。 |
92
93  **表3** 跟踪埋点类型枚举
94
95| **名称** | **值** | **说明** |
96| -------- | -------- | -------- |
97| HITRACE_TP_CS       | 0 | 客户端发送类型,标识client侧的发送埋点。        |
98| HITRACE_TP_CR       | 1 | 客户端接收类型,标识client侧的接收埋点。        |
99| HITRACE_TP_SS       | 2 | 服务端发送类型,标识server侧的发送埋点。        |
100| HITRACE_TP_SR       | 3 | 服务端接收类型,标识server侧的接收埋点。        |
101| HITRACE_TP_GENERAL  | 4 | 一般类型,标识CS、CR、SS、SR四种场景之外的埋点。|
102
103  **表4** 跟踪通信类型枚举
104
105| **名称** | **值** | **说明** |
106| -------- | -------- | -------- |
107| HITRACE_CM_DEFAULT  | 0 | 缺省通信类型    |
108| HITRACE_CM_THREAD   | 1 | 线程间通信类型  |
109| HITRACE_CM_PROCESS  | 2 | 进程间通信类型  |
110| HITRACE_CM_DEVICE   | 3 | 设备间通信类型  |
111
112  **表5** C++接口说明函数参数和功能
113
114| **类** | **方法** | **描述** |
115| -------- | -------- | -------- |
116| HiTraceChain | HiTraceId Begin(const std::string&amp; name, int flags) | 功能:启动HiTraceChain跟踪、生成HiTraceId对象并设置到当前线程TLS中。<br/>输入参数:<br/>- name:业务流程名称。<br/>- flags:跟踪指示位,可以组合使用,具体说明请参考**表2** 跟踪标志组合类型枚举。<br/>- 输出参数:无<br/>- 返回值:启动跟踪超过返回有效HiTraceId对象,否则返回无效对象。<br/>注意:嵌套启动跟踪时,内层启动调用返回无效对象。 |
117|  | void End(const HiTraceId&amp; id) | 功能:根据Begin返回的HiTraceId停止HiTraceChain跟踪;清除当前线程TLS中HiTraceId内容。<br/>输入参数:<br/>- id:HiTraceId对象。<br/>输出参数:无。<br/>返回值:无。 |
118|  | HiTraceId GetId(); | 功能:从当前线程TLS中获取HiTraceId对象。<br/>输入参数:无。<br/>输出参数:无。<br/>返回值:当前线程上下文的HiTraceId对象。 |
119|  | void SetId(const HiTraceId&amp; id) | 功能:设置HiTraceId对象内容到当前线程TLS中。<br/>输入参数:<br/>- id:HiTraceId对象。<br/>输出参数:无。<br/>返回值:无。 |
120|  | void ClearId() | 功能:清除当前线程TLS中的HiTraceId对象。<br/>输入参数:无。<br/>输出参数:无。<br/>返回值:无。 |
121|  | HiTraceId CreateSpan() | 接口功能:获取当前HiTraceId对象中的分支ID。<br/>输入参数:无。<br/>输出参数:无。<br/>返回值:当前分支ID。 |
122|  | void Tracepoint(HiTraceTracepointType type, const HiTraceId&amp; id, const char* fmt, ...) | 功能:根据埋点信息类型输出HiTraceChain埋点信息,包括时间戳、子分支HiTraceId对象信息。<br/>输入参数:<br/>- type:埋点信息类型,具体说明请参考**表3** 跟踪埋点类型枚举。<br/>- id:当前子分支id。<br/>- fmt:格式化变参描述字符串。<br/>- args:变参。<br/>输出参数:无。<br/>返回值:无。 |
123|  | void Tracepoint(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceId&amp; id, const char* fmt, ...) | 功能:根据通信模式、埋点信息类型输出HiTraceChain埋点信息,包括时间戳、子分支HiTraceId对象信息。<br/>输入参数:<br/>- mode:通信模式,具体说明请参考**表4** 跟踪通信类型枚举。<br/>- type:埋点信息类型,具体说明请参考**表3** 跟踪埋点类型枚举。<br/>- id:当前子分支id。<br/>- fmt:格式化变参描述字符串。<br/>- args:变参。<br/>输出参数:无。<br/>返回值:无。 |
124| HiTraceId | HiTraceId(); | 功能:缺省构造函数,生成无效HiTraceId对象。<br/>输入参数:无。<br/>输出参数:无。<br/>返回值:无。 |
125|  | HiTraceId(const uint8_t* pIdArray, int len) | 功能:构造函数,根据字节数组创建跟踪HiTraceId对象。<br/>输入参数:<br/>- pIdArray:字节数组指针。<br/>- len:字节数组长度。<br/>输出参数:无。<br/>返回值:无。 |
126|  | bool IsValid() | 功能:HiTraceId对象是否有效。<br/>输入参数:无。<br/>输出参数:无。<br/>返回值:true 有效;false 无效。 |
127|  | bool IsFlagEnabled(HiTraceFlag flag) | 功能:HiTraceId对象的某标志是否置位。<br/>输入参数:<br/>- flag:跟踪指示位,具体含义见Begin函数中的定义。<br/>输出参数:无。<br/>返回值:true 该标志置位;false 该标志未置位。 |
128|  | void EnableFlag(HiTraceFlag flag) | 功能:设置某跟踪标志位到HiTraceId对象中。<br/>输入参数:<br/>- flag:跟踪指示位,具体含义见Begin函数中的定义。<br/>输出参数:无。<br/>返回值:无。 |
129|  | int GetFlags() | 功能:获取HiTraceId对象中设置的标志位。<br/>输入参数:无。<br/>输出参数:无。<br/>返回值:跟踪指示位组合,具体含义见Begin函数中的定义。 |
130|  | void SetFlags(int flags) | 功能:设置跟踪标志位到HiTraceId对象中。<br/>输入参数:<br/>- flags:跟踪指示位组合,具体含义见Begin函数中的定义。<br/>输出参数:无。<br/>返回值:无。 |
131|  | uint64_t GetChainId() | 功能:获取跟踪链ID。<br/>输入参数:无。<br/>输出参数:无。<br/>返回值:跟踪链ID。 |
132|  | void SetChainId(uint64_t chainId) | 功能:设置跟踪链ID到HiTraceId对象中。<br/>输入参数:<br/>- chainId:跟踪链ID。<br/>输出参数:无。<br/>返回值:无。 |
133|  | uint64_t GetSpanId() | 接口功能:获取当前HiTraceId对象中的分支ID。<br/>输入参数:无。<br/>输出参数:无。<br/>返回值:当前分支ID。 |
134|  | void SetSpanId(uint64_t spanId) | 功能:设置分支ID到HiTraceId对象中。<br/>输入参数:<br/>- spanId:分支ID。<br/>输出参数:无。<br/>返回值:无。 |
135|  | uint64_t GetParentSpanId() | 功能:获取当前HiTraceId对象中的父分支ID。<br/>输入参数:无。<br/>输出参数:无。<br/>返回值:父分支ID。 |
136|  | void SetParentSpanId(uint64_t parentSpanId) | 功能:设置父分支ID到HiTraceId对象中。<br/>输入参数:<br/>- parentSpanId:父分支ID。<br/>输出参数:无。<br/>返回值:无。 |
137|  | int ToBytes(uint8_t* pIdArray, int len) | 功能:将HiTraceId对象转换为字节数组,便于缓存或者通信传递。<br/>输入参数:<br/>- pIdArray:字节数组指针,数组长度至少为HITRACE_ID_LEN。<br/>- len: 字节数组长度<br/>输出参数:<br/>- pIdArray:字节数组指针,对象有效时存储转换后的对象数据。<br/>返回值:0 转换失败; &amp;gt;0 有效对象转换数组长度。 |
138
139
140### 通信调用处理
141
142业务使用时跨设备/跨进程/跨线程的调用是通过通信机制实现的,HiTraceChain需要通信机制传递traceid。
143
144OpenHarmony系统内置部分通信机制(如ZIDL)已经支持传递traceid。
145
146下面描述了同步通信调用传递traceid的处理过程,异步通信调用处理类似。
147
148  对于不支持的扩展通信机制可以参照该方式实现。
149  **图5** 同步通信处理
150  ![zh-cn_image_0000001261032707](figures/zh-cn_image_0000001261032707.png)
151
152处理流程:
153
1541. client侧业务模块调用begin()接口启动调用链跟踪。
155
1562. client侧业务模块发起同步调用transact,到client侧通信组件。
157
1583. client侧通信组件:
159   1. 从当前线程TLS中获取traceid。
160   2. 生成子调用分支(child traceid)。
161   3. 将child traceid写入同步调用通信数据(transaction data)中。
162   4. 进行CS埋点(Client Send)。
163   5. 将通信数据发送到server侧通信组件。
164
1654. server侧通信组件收到通信数据:
166   1. 从数据消息包中取出traceid。
167   2. 将traceid设置到当前线程TLS中。
168   3. 进行SR埋点(Server Receive)。
169   4. 然后进行同步调用回调(onTransact)到server侧业务模块。
170
1715. server侧业务模块进行服务处理,处理完毕发送处理结果(transact reply)到通信组件。
172
1736. server侧通信组件:
174   1. 进行SS埋点(Server Send)。
175   2. 将响应数据发送到client侧通信组件。
176   3. 清除当前线程TLS中的traceid信息。
177
1787. client侧通信组件收到响应数据:
179   1. 进行CR埋点(Client Receive)。
180   2. 发送同步调用响应(transact reply)到client侧业务模块。
181
1828. client侧业务模块进行同步调用响应处理。
183
1849. client侧业务模块在流程结束时调用end()接口停止调用链跟踪。
185
186
187## 开发实例
188
189
190### C++接口实例
191
1921. 源代码开发
193     在类定义头文件或者类实现源文件中,包含hitracechain头文件:
194
195   ```
196   #include "hitrace/tracechain.h"
197   ```
198
199     在业务类实现源文件中使用(启动/结束跟踪):
200
201   ```
202   using namespace OHOS::HiviewDFX;
203   auto traceId = HiTraceChain::Begin("MyServiceFlow", HITRACE_FLAG_DEFAULT);
204   ......
205   HiTraceChain::End(traceId);
206   ```
207
2082. 编译设置,在BUILD.gn里增加子系统SDK依赖:
209
210   ```
211   external_deps = [ "hiviewdfx:libhitracechain" ]
212   ```
213
214
215### C接口实例
216
2171. 源代码开发
218     在源文件中,包含hitracechain头文件:
219
220   ```
221   #include "hitrace/tracechain.h"
222   ```
223
224     在业务类实现源文件中使用(启动/结束跟踪):
225
226   ```
227   HiTraceIdStruct traceId = HiTraceChainBegin("MyServiceFlow", HITRACE_FLAG_DEFAULT);
228   ......
229   HiTraceChainEnd(traceId);
230   ```
231
2322. 编译设置,在BUILD.gn里增加子系统SDK依赖:
233
234   ```
235   external_deps = [ "hiviewdfx:libhitracechain" ]
236   ```
237