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