# HiTrace开发指导 ## 概述 HiTrace主要是对于跨设备/跨进程/跨线程的业务流程,通过相同的traceid在整个业务流程中传递,将流程处理过程中的调用关系、各种输出信息关联和展现出来,帮助使用者分析、定位问题和系统调优。 ## 应用场景 HiTrace在产品中应用场景如下,包括: - 端侧业务流程信息(日志、事件等)关联、上报 - 云侧对上报信息的关联展示和分析,辅助问题定位 - IDE对业务流程详细信息、耗时分布进行调试,辅助系统调优 **图 1** HiTrace应用场景 ![](figure/HiTrace应用场景.png "HiTrace应用场景") ### 业务使用示例 **图 2** 业务调用流程图(跨设备、跨进程同步调用) ![](figure/业务调用流程图(跨设备-跨进程同步调用).png "业务调用流程图(跨设备-跨进程同步调用)") 1. 调试时展示业务流程中的调用关系,进行关键路径分析、功能依赖分析,确定各调用点耗时、调用频率,提前发现性能瓶颈点。 **图 3** 业务调用流程序列图 ![](figure/业务调用流程序列图.png "业务调用流程序列图") **图 4** 业务调用流程性能耗时分布 ![](figure/业务调用流程性能耗时分布.png "业务调用流程性能耗时分布") 2. 在日志和事件等信息中自动附加traceid信息,便于开发人员综合分析和快速实现问题定界定位。 ## 接口说明 HiTrace提供C++、C接口。上层业务主要使用HiTrace跟踪启动、结束接口。 HiTrace实现在C层,主要原理是在一次业务调用流程中,利用通信传递traceid,在业务处理前将traceid设置到当前线程的TLS\(Thread Local Storage\)中,业务处理结束清除当前线程的TLS;这样的话,在业务处理中可以从当前线程的上下文TLS取到traceid,自动附加到日志、事件信息中。 ### 接口形式对比 **表 1** C++、C的函数接口
  

C++

C

函数

函数

HiTrace

HiTraceId Begin(const std::string& name, int flags)

HiTraceIdStruct HiTraceBegin(const char* name, int flags)

  

void End(const HiTraceId& id)

void HiTraceEnd(const HiTraceIdStruct* pId)

  

HiTraceId GetId();

HiTraceIdStruct HiTraceGetId()

  

void SetId(const HiTraceId& id)

void HiTraceSetId(const HiTraceIdStruct* pId)

  

void ClearId()

void HiTraceClearId()

  

HiTraceId CreateSpan()

HiTraceIdStruct HiTraceCreateSpan()

  

void Tracepoint(HiTraceTracepointType type, const HiTraceId& id, const char* fmt, ...)

void HiTraceTracepoint(HiTraceTracepointType type, const HiTraceIdStruct* pId, const char* fmt, ...)

  

void Tracepoint(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceId& id, const char* fmt, ...)

void HiTraceTracepointEx(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceIdStruct* pId, const char* fmt, ...)

HiTraceId

HiTraceId();

void HiTraceInitId(HiTraceIdStruct* pId)

  

HiTraceId(const uint8_t* pIdArray, int len)

HiTraceIdStruct HiTraceBytesToId(const uint8_t* pIdArray, int len)

  

bool IsValid()

int HiTraceIsValid(const HiTraceIdStruct* pId)

  

bool IsFlagEnabled(HiTraceFlag flag)

int HiTraceIsFlagEnabled(const HiTraceIdStruct* pId, HiTraceFlag flag)

  

void EnableFlag(HiTraceFlag flag)

void HiTraceEnableFlag(HiTraceIdStruct* pId, HiTraceFlag flag)

  

int GetFlags()

int HiTraceGetFlags(const HiTraceIdStruct* pId)

  

void SetFlags(int flags)

void HiTraceSetFlags(HiTraceIdStruct* pId, int flags)

  

uint64_t GetChainId()

uint64_t HiTraceGetChainId(const HiTraceIdStruct* pId)

  

void SetChainId(uint64_t chainId)

void HiTraceSetChainId(HiTraceIdStruct* pId, uint64_t chainId)

  

uint64_t GetSpanId()

uint64_t HiTraceGetSpanId(const HiTraceIdStruct* pId)

  

void SetSpanId(uint64_t spanId)

void HiTraceSetSpanId(HiTraceIdStruct* pId, uint64_t spanId)

  

uint64_t GetParentSpanId()

uint64_t HiTraceGetParentSpanId(const HiTraceIdStruct* pId)

  

void SetParentSpanId(uint64_t parentSpanId)

void HiTraceSetParentSpanId(HiTraceIdStruct* pId, uint64_t parentSpanId)

  

int ToBytes(uint8_t* pIdArray, int len)

int HiTraceIdToBytes(const HiTraceIdStruct* pId, uint8_t* pIdArray, int len)

### 接口功能参数 **表 2** C++接口说明函数参数和功能

方法

描述

HiTrace

HiTraceId Begin(const std::string& name, int flags)

功能:启动HiTrace跟踪、生成HiTraceId对象并设置到当前线程TLS中。

输入参数:

  • name:业务流程名称。
  • flags:跟踪指示位,可以组合使用,具体含义为:
    • HITRACE_FLAG_INCLUDE_ASYNC:同时跟踪同步调用和异步调用,缺省只跟踪同步调用。
    • HITRACE_FLAG_DONOT_CREATE_SPAN:不创建子分支,缺省创建子分支。
    • HITRACE_FLAG_TP_INFO:输出tracepoint信息,缺省不输出。
    • HITRACE_FLAG_NO_BE_INFO:不输出起始、结束信息,缺省输出。
    • HITRACE_FLAG_DONOT_ENABLE_LOG:不与日志关联输出,缺省关联。
    • HITRACE_FLAG_FAULT_TRIGGER:故障触发的跟踪,缺省为正常启动的。
    • HITRACE_FLAG_D2D_TP_INFO:输出设备间tracepoint信息,缺省不输出。
    • HITRCE_FLAG_DEFAULT: 缺省标志。
  • 输出参数:无
  • 返回值:启动跟踪超过返回有效HiTraceId对象,否则返回无效对象。

注意:嵌套启动跟踪时,内层启动调用返回无效对象。

  

void End(const HiTraceId& id)

功能:根据Begin返回的HiTraceId停止HiTrace跟踪;清除当前线程TLS中HiTraceId内容。

输入参数:

  • id:HiTraceId对象。

输出参数:无。

返回值:无。

  

HiTraceId GetId();

功能:从当前线程TLS中获取HiTraceId对象。

输入参数:无。

输出参数:无。

返回值:当前线程上下文的HiTraceId对象。

  

void SetId(const HiTraceId& id)

功能:设置HiTraceId对象内容到当前线程TLS中。

输入参数:

  • id:HiTraceId对象。

输出参数:无。

返回值:无。

  

void ClearId()

功能:清除当前线程TLS中的HiTraceId对象。

输入参数:无。

输出参数:无。

返回值:无。

  

HiTraceId CreateSpan()

接口功能:获取当前HiTraceId对象中的分支ID。

输入参数:无。

输出参数:无。

返回值:当前分支ID。

  

void Tracepoint(HiTraceTracepointType type, const HiTraceId& id, const char* fmt, ...)

功能:根据埋点信息类型输出HiTrace埋点信息,包括时间戳、子分支HiTraceId对象信息。

输入参数:

  • type:埋点信息类型,具体为
    • HITRACE_TP_CS:Client Send,同步/异步通信客户端发送信息。
    • HITRACE_TP_SR:Server Receive, 同步/异步通信服务端接收信息。
    • HITRACE_TP_SS:Server Send,同步通信服务端发送响应信息。
    • HITRACE_TP_CR:Client Receive,同步通信客户端接收响应信息。
    • HITRACE_TP_GENERAL:普通输出信息。
  • id:当前子分支id。
  • fmt:格式化变参描述字符串。
  • args:变参。

输出参数:无。

返回值:无。

  

void Tracepoint(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceId& id, const char* fmt, ...)

功能:根据通信模式、埋点信息类型输出HiTrace埋点信息,包括时间戳、子分支HiTraceId对象信息。

输入参数:

  • mode:通信模式,具体为
    • HITRACE_CM_DEFAULT:未指定通信模式。
    • HITRACE_CM_THREAD:线程间通信。
    • HITRACE_CM_PROCESS:进程间通信。
    • HITRACE_CM_DEVICE:设备间通信。
  • type:埋点信息类型,具体为
    • HITRACE_TP_CS:Client Send,同步/异步通信客户端发送信息。
    • HITRACE_TP_SR:Server Receive, 同步/异步通信服务端接收信息。
    • HITRACE_TP_SS:Server Send,同步通信服务端发送响应信息。
    • HITRACE_TP_CR:Client Receive,同步通信客户端接收响应信息。
    • HITRACE_TP_GENERAL:普通输出信息。
  • id:当前子分支id。
  • fmt:格式化变参描述字符串。
  • args:变参。

输出参数:无。

返回值:无。

HiTraceId

HiTraceId();

功能:缺省构造函数,生成无效HiTraceId对象。

输入参数:无。

输出参数:无。

返回值:无。

  

HiTraceId(const uint8_t* pIdArray, int len)

功能:构造函数,根据字节数组创建跟踪HiTraceId对象。

输入参数:
  • pIdArray:字节数组指针。
  • len:字节数组长度。

输出参数:无。

返回值:无。

  

bool IsValid()

功能:HiTraceId对象是否有效。

输入参数:无。

输出参数:无。

返回值:true 有效;false 无效。

  

bool IsFlagEnabled(HiTraceFlag flag)

功能:HiTraceId对象的某标志是否置位。

输入参数:

  • flag:跟踪指示位,具体含义见Begin函数中的定义。

输出参数:无。

返回值:true 该标志置位;false 该标志未置位。

  

void EnableFlag(HiTraceFlag flag)短短

功能:设置某跟踪标志位到HiTraceId对象中。

输入参数:

  • flag:跟踪指示位,具体含义见Begin函数中的定义。

输出参数:无。

返回值:无。

  

int GetFlags()

功能:获取HiTraceId对象中设置的标志位。

输入参数:无。

输出参数:无。

返回值:跟踪指示位组合,具体含义见Begin函数中的定义。

  

void SetFlags(int flags)

功能:设置跟踪标志位到HiTraceId对象中。

输入参数:

  • flags:跟踪指示位组合,具体含义见Begin函数中的定义。

输出参数:无。

返回值:无。

  

uint64_t GetChainId()

功能:获取跟踪链ID。

输入参数:无。

输出参数:无。

返回值:跟踪链ID。

  

void SetChainId(uint64_t chainId)

功能:设置跟踪链ID到HiTraceId对象中。

输入参数:

  • chainId:跟踪链ID。

输出参数:无。

返回值:无。

  

uint64_t GetSpanId()

接口功能:获取当前HiTraceId对象中的分支ID。

输入参数:无。

输出参数:无。

返回值:当前分支ID。

  

void SetSpanId(uint64_t spanId)

功能:设置分支ID到HiTraceId对象中。

输入参数:

  • spanId:分支ID。

输出参数:无。

返回值:无。

  

uint64_t GetParentSpanId()

功能:获取当前HiTraceId对象中的父分支ID。

输入参数:无。

输出参数:无。

返回值:父分支ID。

  

void SetParentSpanId(uint64_t parentSpanId)

功能:设置父分支ID到HiTraceId对象中。

输入参数:

  • parentSpanId:父分支ID。

输出参数:无。

返回值:无。

  

int ToBytes(uint8_t* pIdArray, int len)

功能:将HiTraceId对象转换为字节数组,便于缓存或者通信传递。

输入参数:

  • pIdArray:字节数组指针,数组长度至少为HITRACE_ID_LEN。
  • len: 字节数组长度

输出参数:

  • pIdArray:字节数组指针,对象有效时存储转换后的对象数据。

返回值:0 转换失败; >0 有效对象转换数组长度。

## 通信调用处理 业务使用时跨设备/跨进程/跨线程的调用是通过通信机制实现的,HiTrace需要通信机制传递traceid。 OpenHarmony系统内置部分通信机制(如ZIDL)已经支持传递traceid。 下面描述了同步通信调用传递traceid的处理过程,异步通信调用处理类似。 对于不支持的扩展通信机制可以参照该方式实现。 **图 5** 同步通信处理 ![](figure/同步通信处理.png "同步通信处理") 处理流程: 1. client侧业务模块调用begin\(\)接口启动调用链跟踪。 2. client侧业务模块发起同步调用transact,到client侧通信组件。 3. client侧通信组件: 1. 从当前线程TLS中获取traceid。 2. 生成子调用分支(child traceid)。 3. 将child traceid写入同步调用通信数据(transaction data)中。 4. 进行CS埋点(Client Send)。 5. 将通信数据发送到server侧通信组件。 4. server侧通信组件收到通信数据: 1. 从数据消息包中取出traceid。 2. 将traceid设置到当前线程TLS中。 3. 进行SR埋点(Server Receive)。 4. 然后进行同步调用回调(onTransact)到server侧业务模块。 5. server侧业务模块进行服务处理,处理完毕发送处理结果(transact reply)到通信组件。 6. server侧通信组件: 1. 进行SS埋点(Server Send)。 2. 将响应数据发送到client侧通信组件。 3. 清除当前线程TLS中的traceid信息。 7. client侧通信组件收到响应数据: 1. 进行CR埋点(Client Receive)。 2. 发送同步调用响应(transact reply)到client侧业务模块。 8. client侧业务模块进行同步调用响应处理。 9. client侧业务模块在流程结束时调用end\(\)接口停止调用链跟踪。 ## 开发实例 ### C++接口实例 1. 源代码开发 在类定义头文件或者类实现源文件中,包含hitrace头文件: ``` #include "hitrace/trace.h" ``` 在业务类实现源文件中使用(启动/结束跟踪): ``` using namespace OHOS::HiviewDFX; HiTraceId traceId = HiTrace::Begin("MyServiceFlow", HITRACE_FLAG_DEFAULT); ...... HiTrace::End(traceId); ``` 2. 编译设置,在BUILD.gn里增加子系统SDK依赖: ``` external_deps = [ "hiviewdfx:libhitrace" ] ``` ### C接口实例 1. 源代码开发 在源文件中,包含hitrace头文件: ``` #include "hitrace/trace.h" ``` 在业务类实现源文件中使用(启动/结束跟踪): ``` HiTraceIdStruct traceId = HiTraceBegin("MyServiceFlow", HITRACE_FLAG_DEFAULT); ...... HiTraceEnd(traceId); ``` 2. 编译设置,在BUILD.gn里增加子系统SDK依赖: ``` external_deps = [ "hiviewdfx:libhitrace" ] ```