当前位置: 首页 > 科技观察

OpenHarmonyHiTrace在IPC通信中的应用(L2)

时间:2023-03-14 18:33:17 科技观察

了解更多开源请访问:51CTO开源基础软件社区https://ost.51cto.comHiTrace简介主要针对跨设备/跨进程/跨线程的业务流程,通过同一个traceid贯穿整个业务流程,将流程处理过程中的调用关系和各种输出信息进行关联展示,帮助用户分析,定位问题和系统调优。本文介绍了基于openharmony3.1代码的HiTrace的使用和数据传输以及HiTrace在IPC进程通信中的应用。介绍HiTrace在IPC通信中的应用。HiTrace在IPC通信中的应用实例。IPC中HiTrace的数据流向介绍。本用例开发板(3516开发板:HiSpark_AI_Hi3516D_One_Light_VER.B开发板测试)HiTrace在IPC通信中的应用介绍IPC通信的框架代码:客户端发送接收数据其中tranceId已经发送到服务端并发送接收数据了的跟踪日志代码。服务端收到回复数据的地方已经有了获取传入的tranceId和收发数据的跟踪日志代码。我们只需要在要跟踪的代码块之前添加HiTrace::Begin,在代码块之后添加HiTrace::End。获取跟踪日志:hilog|grepHiTraceC查看数据收发日志。源码开发在类定义头文件或类实现源文件中,包括hitrace头文件:#include"hitrace/trace.h"在业务类实现源文件(start/endtrace)中使用:usingnamespaceOHOS::HiviewDFX;HiTraceIdtraceId=HiTrace::Begin("MyServiceFlow",HITRACE_FLAG_DEFAULT);......HiTrace::End(traceId);Trace日志(IPC框架中已经实现,无需实现):HiTraceIdid=HiTrace::GetId();//Begin和End之间的id有效,其他阶段的id无效。如果id无效,则不会输出Tracepoint日志。HiTrace::Tracepoint(HITRACE_TP_CS,id,"客户端发送信息内容");//高潮|grepHiTraceCcapturetracelog编译设置,在BUILD.gn中添加子系统SDK依赖:external_deps=["hiviewdfx:libhitrace"]IPC通信build\subsystem_config.json中的HiTrace应用实例子系统配置:"myapp":{"path":"myapptest","name":"myapp"}产品配置productdefine\common\products\Hi3516DV300.json:"myapp:myappservice_test":{}代码代码目录结构myapptest放在代码根目录下,见附件代码。ServiceIDAddServiceID有一个统一的头文件。foundation\distributedschedule\samgr\interfaces\innerkits\samgr_proxy\include\system_ability_definition.h。MY_APP_SERVICE_ID=9000,...{MY_APP_SERVICE_ID,"MyAppService"},编译编译并将编译结果文件发送给开发板,修改权限参考Openharmony实现的一个IPC客户端和服务器,代码基于此文档添加了代码修改。测试终端1:抓取日志。高潮|grepHiTraceC图中白色部分是一个完整的client-server交互过程,每次begin和end之间的tranceid相同,每次完整交互spanid相同。CS:客户端发送数据,CR:客户端接收数据,SR:服务器接收数据,SS:服务器发送数据。终端2:启动服务。sa_main/system/profile/myappservice_sa.xml终端3:启动客户端。/data/test/myappclientHiTrace在IPC中的数据流引入入口函数文件:foundation\communication\ipc\ipc\native\src\mock\include\dbinder_base_invoker.h。IPC客户端收发数据入口:intDBinderBaseInvoker::SendRequest(int32_thandle,uint32_tcode,MessageParcel&data,MessageParcel&reply,MessageOption&option){uint64_tseqNumber=0;诠释;uint32_t标志=(uint32_t)option.GetFlags();intuserWaitTime=option.GetWaitTime();MessageParcel&newData=const_cast(数据);size_toldWritePosition=newData.GetWritePosition();//#######1.获取tranceIdHiTraceIdtraceId=HiTrace::GetId();//如果启用trace,则设置客户端发送trace点//#######2.客户端数据发送trace记录,并将tranceid打包到发送数据中。HiTraceIdchildId=HitraceInvoker::TraceClientSend(handle,code,newData,flags,traceId);std::shared_ptrsession=WriteTransaction(BC_TRANSACTION,flags,handle,0,code,data,seqNumber,0);if(session==nullptr){newData.RewindWrite(oldWritePosition);DBINDER_BASE_LOGE("seqNumber不能为零,handle=%d",handle);#ifndefBUILD_PUBLIC_VERSIONReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR,DbinderErrorCode::ERROR_TYPE,DbinderErrorCode::RPC_DRIVER,DbinderErrorCode::ERROR_CODE,DbinderErrorCode::TRANSACT);DATAendif返回RPC_BASE_INVOKER_WRITE_TRANS_ERR;}if(flags&TF_ONE_WAY){ret=SendOrWaitForCompletion(userWaitTime,seqNumber,session,nullptr);}else{ret=SendOrWaitForCompletion(userWaitTime,seqNumber,session,&reply);}//#######3.客户端数据接收跟踪记录。HitraceInvoker::TraceClientReceieve(句柄、代码、标志、traceId、childId);//恢复Parcel数据newData.RewindWrite(oldWritePosition);returnret;}服务端采集数据入口:templatevoidDbinderBaseInvoker::OnTransaction(std::shared_ptrprocessInfo){if(processInfo==nullptr){DBINDER_BASE_LOGE("processInfoiserror!");返回;}uint32_tlistenFd=processInfo->listenFd;char*package=processInfo->buffer.get();if(package==nullptr||listenFd==0){DBINDER_BASE_LOGE("packageisnullorlistenFdinvalid!");返回;}dbinder_transaction_data*tr=reinterpret_cast(package);if(tr->sizeOfSelfcmd==BC_TRANSACTION){//#######服务端数据处理函数ProcessTransaction(tr,lis10Fd);}elseif(tr->cmd==BC_REPLY){ProcessReply(tr,listenFd);}return;}templatevoidDBinderBaseInvoker::ProcessTransaction(dbinder_transaction_data*tr,uint32_tlistenFd){interror;MessageParcel数据,回复;IPCProcessSkeleton*current=IPCProcessSkeleton::GetCurrent();if(current==nullptr){DBINDER_BASE_LOGE("currentipcprocessskeletonisnullptr");返回;}autoallocator=newDbinderSendAllocator();if(!data.SetAllocator(allocator)){DBINDER_BASE_LOGE("SetAllocatorfailed");删除分配器;返回;}data.ParseFrom(reinterpret_cast(tr->buffer),tr->buffer_size);如果(!(tr->flags&MessageOption::TF_STATUS_CODE)&&tr->offsets_size>0){data.InjectOffsets(reinterpret_cast(reinterpret_cast(tr->buffer)+tr->offsets),tr->offsets_size/sizeof(binder_size_t));}uint32_t&newflags=const_cast(tr->flags);//#######1.服务端接收数据,解析tranceid,记录接收到的数据跟踪信息,供intisServerTraced=HitraceInvoker::TraceServerReceieve(tr->cookie,tr->code,data,newflags);constpid_toldPid=GetCallerPid();constautooldUid=static_cast(GetCallerUid());conststd::stringoldDeviceId=GetCallerDeviceID();uint32_toldStatus=GetStatus();if(CheckAndSetCallerInfo(listenFd,tr->cookie)!=ERR_NONE){DBINDER_BASE_LOGE("setuserinfoerror,maybecookieisNOTbelongtocurrentcaller");返回;}SetStatus(IRemoteInvoker::ACTIVE_INVOKER);constuint32_tflags=tr->flags;uint64_tsenderSeqNumber=tr->seqNumber;if(tr->cookie==0){//也许cookie为零,丢弃这个包return;}auto*stub=current->QueryStubByIndex(tr->cookie);if(stub==nullptr){DBINDER_BASE_LOGE("stubIndex无效");返回;}if(!IRemoteObjectTranslate(reinterpret_cast(tr->buffer),tr->buffer_size,data,listenFd,nullptr)){DBINDER_BASE_LOGE("翻译对象失败");返回;}auto*stubObject=reinterpret_cast(stub);MessageOption选项;选项.SetFlags(标志);error=stubObject->SendRequest(tr->code,data,reply,option);if(error!=ERR_NONE){DBINDER_BASE_LOGE("stub无效,没有OnReceive或Request");//不能返回;}if(data.GetRawData()!=nullptr){DBINDER_BASE_LOGE("删除流程骨架中的原始数据");当前->DetachRawData(listenFd);}//#######2.服务器数据回复记录连接发送数据的Trace信息HitraceInvoker::TraceServerSend(tr->cookie,tr->code,isServerTraced,newflags);if(!(flags&MessageOption::TF_ASYNC)){SetClientFd(listenFd);SetSeqNum(senderSeqNumber);SendReply(回复,0,错误);SetClientFd(0);设置序号(0);}SetCallerPid(oldPid);SetCallerUid(oldUid);SetCallerDeviceID(oldDeviceId);笔记。了解IPC框架,需要结合OpenharmonyIPCCommunication(L2)进行代码分析和学习。官网文档。了解更多开源信息,请访问:51CTO开源基础软件社区https://ost.51cto.com。