1# 使用HiCollie监控函数执行时间超长问题(C/C++) 2 3HiCollie模块对外提供函数执行时间超长的检测机制。 4 5## 接口说明 6 7| 接口名 | 描述 | 8| ------------------------------ | --------------------------------- | 9| OH_HiCollie_SetTimer | 注册定时器,用于检测函数或代码块执行是否超过自定义时间。<br/>结合OH_HiCollie_CancelTimer接口配套使用,应在调用耗时的函数之前使用。| 10| OH_HiCollie_CancelTimer | 取消定时器。<br/>结合OH_HiCollie_SetTimer接口配套使用,执行函数或代码块后使用,OH_HiCollie_CancelTimer通过id将该任务取消;<br/>若未在自定义时间内取消,则执行回调函数,在特定自定义超时动作下,生成故障日志。| 11 12- API接口的具体使用说明(参数使用限制、具体取值范围等)请参考[HiCollie](../reference/apis-performance-analysis-kit/_hi_collie.md)。 13- 函数执行时间超长故障日志以syswarning-开头,生成在”设备/data/log/faultlog/faultlogger/”路径下。文件名格式为“syswarning-应用包名-应用UID-秒级时间.log”。 14 15## 开发步骤 16 17下文将展示如何在应用内增加一个按钮,并单击该按钮以调用HiCollie Ndk接口。 18 191. 新建Native C++工程,目录结构如下: 20 21 ```yml 22 entry: 23 src: 24 main: 25 cpp: 26 - types: 27 libentry: 28 - index.d.ts 29 - CMakeLists.txt 30 - napi_init.cpp 31 ets: 32 - entryability: 33 - EntryAbility.ts 34 - pages: 35 - Index.ets 36 ``` 37 382. 编辑"CMakeLists.txt"文件,添加源文件及动态库: 39 40 ```cmake 41 # 依赖动态库libhilog_ndk.z.so(日志输出),libohhicollie.so(HiCollie对外检测接口) 42 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libohhicollie.so) 43 ``` 44 453. 编辑"napi_init.cpp"文件,导入依赖头文件、定义LOG_TAG与测试方法以及注册TestHiCollieTimerNdk为ArkTS接口: 46 47 ```c++ 48 #include "napi/native_api.h" 49 #include "hicollie/hicollie.h" 50 #include "hilog/log.h" 51 52 #include <unistd.h> 53 54 #undef LOG_TAG 55 #define LOG_TAG "testTag" 56 57 //定义回调函数 58 void CallBack(void*) 59 { 60 OH_LOG_INFO(LogType::LOG_APP, "HiCollieTimerNdk callBack"); // 回调函数中打印日志 61 } 62 63 static napi_value TestHiCollieTimerNdk(napi_env env, napi_callback_info info) 64 { 65 int id; 66 HiCollie_SetTimerParam param = {"testTimer", 1, CallBack, nullptr, HiCollie_Flag::HICOLLIE_FLAG_LOG}; // 设置HiCollieTimer 参数(Timer任务名,超时时间,回调函数,回调函数参数,超时发生后行为) 67 HiCollie_ErrorCode errorCode = OH_HiCollie_SetTimer(param, &id); // 注册HiCollieTimer函数执行时长超时检测一次性任务 68 if (errorCode == HICOLLIE_SUCCESS) { // HiCollieTiimer任务注册成功 69 OH_LOG_INFO(LogType::LOG_APP, "HiCollieTimer taskId: %{public}d", id); // 打印任务id 70 sleep(2); // 模拟执行耗时函数,在这里简单的将线程阻塞2s 71 OH_HiCollie_CancelTimer(id); // 根据id取消已注册任务 72 } 73 return 0; 74 } 75 76 EXTERN_C_START 77 static napi_value Init(napi_env env, napi_value exports) 78 { 79 napi_property_descriptor desc[] = { 80 { "testHiCollieTimerNdk", nullptr, TestHiCollieTimerNdk, nullptr, nullptr, nullptr, napi_default, nullptr } // 将TestHiCollieTimerNdk注册为ArkTS接口 81 }; 82 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 83 return exports; 84 } 85 EXTERN_C_END 86 87 static napi_module demoModule = { 88 .nm_version = 1, 89 .nm_flags = 0, 90 .nm_filename = nullptr, 91 .nm_register_func = Init, 92 .nm_modname = "entry", 93 .nm_priv = ((void*)0), 94 .reserved = { 0 }, 95 }; 96 97 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) 98 { 99 napi_module_register(&demoModule); 100 } 101 ``` 102 1034. 编辑"index.d.ts"文件,定义ArkTS接口: 104 105 ```ts 106 export const testHiCollieTimerNdk: () => void; 107 ``` 108 1095. 编辑"Index.ets"文件: 110 111 ```ts 112 import testNapi from 'libentry.so' 113 114 @Entry 115 @Component 116 struct Index { 117 @State message: string = 'Hello World' 118 119 build() { 120 Row() { 121 Column() { 122 Button("testHiCollieTimerNdk") 123 .fontSize(50) 124 .fontWeight(FontWeight.Bold) 125 .onClick(testNapi.testHiCollieTimerNdk); //添加点击事件,触发testHiCollieTimerNdk方法。 126 } 127 .width('100%') 128 } 129 .height('100%') 130 } 131 } 132 ``` 133 1346. 点击IDE界面中的运行按钮,运行应用工程: 135 1367. 在DevEco Studio的底部,切换到“Log->HiLog”窗口,设置日志的过滤条件为“testTag”: 137 138 点击“testHiCollieTimerNdk”按钮执行程序,日志窗口打印任务id: 139 140 ``` 141 .../testTag ... HiCollieTimer taskId: x 142 ``` 143 144 等待2s后,执行回调函数,日志窗口打印: 145 146 ``` 147 .../testTag ... HiCollieTimerNdk CallBack 148 ``` 149 150 获取故障文件信息相关内容可参考[订阅任务执行超时事件(C/C++)](hiappevent-watcher-apphicollie-events-ndk.md) 订阅获取。