1# HiSysEvent打点 2 3## 概述 4 5### 功能简介 6 7HiSysEvent打点提供了事件打点功能,开发者可以通过在关键路径打点来记录系统在运行过程中的重要信息。同时,HiSysEvent打点也提供了以事件领域为单位的HiSysEvent打点屏蔽机制,方便开发者评估及调试HiSysEvent打点操作的影响。 8 9### 运作机制 10 11在进行HiSysEvent事件打点之前,需要先完成HiSysEvent打点配置,具体配置方法请参考[HiSysEvent打点配置指导](subsys-dfx-hisysevent-logging-config.md)。 12 13## 开发指导 14 15### 场景介绍 16 17事件打点的主要工作是将打点数据进行落盘。 18 19### 接口说明 20 21#### C++接口说明 22 23C++事件打点开发能力如下:HiSysEvent类,具体API详见接口目录(/base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent/include/)。 24 25> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** 26> 27> 从OpenHarmony-3.2-Beta3版本开始,为避免打点风暴事件引发性能问题,对HiSysEvent打点进行了管控。表1中的HiSysEvent::Write打点接口被表2中的HiSysEventWrite宏接口取代。HiSysEvent::Write接口已废弃,请使用HiSysEventWrite宏接口完成HiSysEvent事件打点。 28 29**表1** 事件打点接口(已废弃) 30 31| 接口名 | 描述 | 32| ------------------------------------------------------------ | --------------------- | 33| template<typename... Types> <br>static int Write(const std::string &domain, const std::string &eventName, EventType type, Types... keyValues) | 将打点事件数据进行落盘。 | 34 35**表2** 事件打点宏接口 36 37| 接口名 | 描述 | 38| ------------------------------------------------------------ | --------------------- | 39| HiSysEventWrite(domain, eventName, type, ...) | 将打点事件数据进行落盘。 | 40 41 **表3** EventType事件类型枚举 42 43| 事件类型 | 描述 | 44| --------- | ----------- | 45| FAULT | 故障类型事件。 | 46| STATISTIC | 统计类型事件。 | 47| SECURITY | 安全类型事件。 | 48| BEHAVIOR | 行为类型事件。 | 49 50#### C接口说明 51 52C事件打点开发能力如下:具体API详见接口目录(/base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent/include/)。 53 54**表4** 事件打点接口 55 56| 接口名 | 描述 | 57| ------------------------------------------------------------ | ------------------------ | 58| int OH_HiSysEvent_Write(const char\* domain, const char\* name, HiSysEventEventType type, HiSysEventParam params[], size_t size); | 将打点事件数据进行落盘。 | 59 60**表5** HiSysEventEventType事件类型枚举 61 62| 事件类型 | 描述 | 63| -------------------- | -------------- | 64| HISYSEVENT_FAULT | 故障类型事件。 | 65| HISYSEVENT_STATISTIC | 统计类型事件。 | 66| HISYSEVENT_SECURITY | 安全类型事件。 | 67| HISYSEVENT_BEHAVIOR | 行为类型事件。 | 68 69**表6** HiSysEventParam事件参数结构体 70 71| 属性名称 | 属性类型 | 描述 | 72| --------- | -------------------- | ---------------------------------- | 73| name | char name[] | 事件参数名称。 | 74| t | HiSysEventParamType | 事件参数类型。 | 75| v | HiSysEventParamValue | 事件参数值。 | 76| arraySize | size_t | 事件参数值为数组类型时的数组长度。 | 77 78**表7** HiSysEventParamType事件参数类型枚举 79 80| 参数类型 | 描述 | 81| ----------------------- | -------------------------- | 82| HISYSEVENT_INVALID | 无效类型事件参数。 | 83| HISYSEVENT_BOOL | bool类型事件参数。 | 84| HISYSEVENT_INT8 | int8_t类型事件参数。 | 85| HISYSEVENT_UINT8 | uint8_t类型事件参数。 | 86| HISYSEVENT_INT16 | int16_t类型事件参数。 | 87| HISYSEVENT_UINT16 | uint16_t类型事件参数。 | 88| HISYSEVENT_INT32 | int32_t类型事件参数。 | 89| HISYSEVENT_UINT32 | uint32_t类型事件参数。 | 90| HISYSEVENT_INT64 | int64_t类型事件参数。 | 91| HISYSEVENT_UINT64 | uint64_t类型事件参数。 | 92| HISYSEVENT_FLOAT | float类型事件参数。 | 93| HISYSEVENT_DOUBLE | double类型事件参数。 | 94| HISYSEVENT_STRING | char*类型事件参数。 | 95| HISYSEVENT_BOOL_ARRAY | bool数组类型事件参数。 | 96| HISYSEVENT_INT8_ARRAY | int8_t数组类型事件参数。 | 97| HISYSEVENT_UINT8_ARRAY | uint8_t数组类型事件参数。 | 98| HISYSEVENT_INT16_ARRAY | int16_t数组类型事件参数。 | 99| HISYSEVENT_UINT16_ARRAY | uint16_t数组类型事件参数。 | 100| HISYSEVENT_INT32_ARRAY | int32_t数组类型事件参数。 | 101| HISYSEVENT_UINT32_ARRAY | uint32_t数组类型事件参数。 | 102| HISYSEVENT_INT64_ARRAY | int64_t数组类型事件参数。 | 103| HISYSEVENT_UINT64_ARRAY | uint64_t数组类型事件参数。 | 104| HISYSEVENT_FLOAT_ARRAY | float数组类型事件参数。 | 105| HISYSEVENT_DOUBLE_ARRAY | double数组类型事件参数。 | 106| HISYSEVENT_STRING_ARRAY | char*数组类型事件参数。 | 107 108**表8** HiSysEventParamValue事件参数值联合体 109 110| 属性名称 | 属性类型 | 描述 | 111| -------- | -------- | ------------------------ | 112| b | bool | bool类型事件参数值。 | 113| i8 | int8_t | int8_t类型事件参数值。 | 114| ui8 | uint8_t | uint8_t类型事件参数值。 | 115| i16 | int16_t | int16_t类型事件参数值。 | 116| ui16 | uint16_t | uint16_t类型事件参数值。 | 117| i32 | int32_t | int32_t类型事件参数值。 | 118| ui32 | uint32_t | uint32_t类型事件参数值。 | 119| i64 | int64_t | int64_t类型事件参数值。 | 120| ui64 | uint64_t | uint64_t类型事件参数值。 | 121| f | float | float类型事件参数值。 | 122| d | double | double类型事件参数值。 | 123| s | char* | char*类型事件参数值。 | 124| array | void* | 数组类型事件参数值。 | 125 126#### kernel接口说明 127 128kernel事件打点开发能力如下:具体API详见接口文件(/kernel/linux/linux-5.10/include/dfx/hiview_hisysevent.h)。 129 130**表9** 事件打点接口 131 132| 接口名 | 描述 | 133| ------------------------------------------------------------ | ----------------------------------- | 134| struct hiview_hisysevent *hisysevent_create(const char *domain, const char *name, enum hisysevent_type type); | 创建一个事件对象。 | 135| void hisysevent_destroy(struct hiview_hisysevent *event); | 销毁一个事件对象。 | 136| int hisysevent_put_integer(struct hiview_hisysevent *event, const char *key, long long value); | 将整数类型的事件参数添加到事件对象。 | 137| int hisysevent_put_string(struct hiview_hisysevent *event, const char *key, const char *value); | 将字符串类型的事件参数添加到事件对象。 | 138| int hisysevent_write(struct hiview_hisysevent *event); | 将事件对象数据进行落盘。 | 139 140**表10** hisysevent_type事件类型枚举 141 142| 事件类型 | 描述 | 143| --------- | ----------- | 144| FAULT | 故障类型事件。 | 145| STATISTIC | 统计类型事件。 | 146| SECURITY | 安全类型事件。 | 147| BEHAVIOR | 行为类型事件。 | 148 149### 开发步骤 150 151#### C++打点开发步骤 152 153在需要打点的地方直接调用打点接口,并传入相应事件参数。 154 155 ```c++ 156 HiSysEventWrite(HiSysEvent::Domain::AAFWK, "START_APP", HiSysEvent::EventType::BEHAVIOR, "APP_NAME", "com.ohos.demo"); 157 ``` 158 159#### C打点开发步骤 160 1611. 如果需要在打点时传入自定义事件参数,先要根据事件参数类型创建对应的事件参数对象,再将其放入到事件参数数组中。 162 163 ```c 164 // 创建一个int32_t类型的事件参数 165 HiSysEventParam param1 = { 166 .name = "KEY_INT32", 167 .t = HISYSEVENT_INT32, 168 .v = { .i32 = 1 }, 169 .arraySize = 0, 170 }; 171 172 // 创建一个int32_t数组类型的事件参数 173 int32_t int32Arr[] = { 1, 2, 3 }; 174 HiSysEventParam param2 = { 175 .name = "KEY_INT32_ARR", 176 .t = HISYSEVENT_INT32_ARRAY, 177 .v = { .array = int32Arr }, 178 .arraySize = sizeof(int32Arr) / sizeof(int32Arr[0]), 179 }; 180 181 // 将事件参数对象放入创建的事件参数数组中 182 HiSysEventParam params[] = { param1, param2 }; 183 ``` 184 1852. 在需要打点的地方调用打点接口,并传入相应事件参数。 186 187 ```c 188 OH_HiSysEvent_Write("TEST_DOMAIN", "TEST_NAME", HISYSEVENT_BEHAVIOR, params, sizeof(params) / sizeof(params[0])); 189 ``` 190 191#### kernel打点开发步骤 192 1931. 根据事件领域、事件名称、事件类型参数,创建一个基础的事件对象。 194 195 ```c 196 struct hiview_hisysevent *event = hisysevent_create("KERNEL", "BOOT", BEHAVIOR); 197 ``` 198 1992. 将自定义的事件参数,传入到事件对象里。 200 201 ```c 202 // 添加整数类型参数 203 hisysevent_put_integer(event, "BOOT_TIME", 100); 204 205 // 添加字符串类型参数 206 hisysevent_put_string(event, "MSG", "This is a test message"); 207 ``` 208 2093. 在事件对象构建完成后,将事件进行上报。 210 211 ```c 212 hisysevent_write(event); 213 ``` 214 2154. 事件上报完成后,需要手动将对象销毁。 216 217 ```c 218 hisysevent_destroy(&event); 219 ``` 220 221#### 事件领域屏蔽的步骤 222 2231. 在相应的文件中定义名称为“DOMAIN_MASKS”,内容形如“DOMAIN_NAME_1|DOMAIN_NAME_2|...|DOMAIN_NAME_n”。共有三种屏蔽场景: 224 225- 只屏蔽当前源码文件中的相应事件领域的HiSysEvent打点,在该cpp文件引入hisysevent.h头文件之前定义宏DOMAIN_MASKS即可。 226 ```c++ 227 #define DOMAIN_MASKS "DOMAIN_NAME_1|DOMAIN_NAME_2|...|DOMAIN_NAME_n" 228 #include "hisysevent.h" 229 ``` 230 231- 屏蔽整个模块相应事件领域的HiSysEvent打点,在模块的BUILD.gn文件中定义宏DOMAIN_MASKS即可。 232 ```gn 233 config("module_a"){ 234 cflags_cc += ["-DDOMAIN_MASKS=\"DOMAIN_NAME_1|DOMAIN_NAME_2|...|DOMAIN_NAME_n\""] 235 } 236 ``` 237 238- 全局屏蔽相应事件领域的HiSysEvent打点,则在/build/config/compiler/BUILD.gn中定义宏DOMAIN_MASKS即可。 239 ```gn 240 cflags_cc += ["-DDOMAIN_MASKS=\"DOMAIN_NAME_1|DOMAIN_NAME_2|...|DOMAIN_NAME_n\""] 241 ``` 242 2432. 通过HiSysEventWrite宏完成HiSysEvent打点操作: 244 ```c++ 245 constexpr char DOMAIN[] = "DOMAIN_NAME_1"; 246 const std::string eventName = "EVENT_NAME1"; 247 OHOS:HiviewDFX::HiSysEvent::EventType eventType = OHOS:HiviewDFX::HiSysEvent::EventType::FAULT; 248 HiSysEventWrite(domain, eventName, eventType); //因为DOMAIN_NAME_1事件领域已经在DOMAIN_MASKS中定义,所以该HiSysEvent打点不会执行。 249 ``` 250 251### 开发实例 252 253#### C++打点开发实例 254 255假设业务模块需要在应用启动时进行打点来记录应用启动事件,且需要记录应用的包名信息,完整使用示例如下所示: 256 2571. 首先,需要在业务模块的在BUILD.gn里增加HiSysEvent部件依赖。 258 259 ```c++ 260 external_deps = [ "hisysevent_native:libhisysevent" ] 261 ``` 262 2632. 在业务模块的应用启动函数StartAbility()中,调用打点接口并传入对应事件参数。 264 265 ```c++ 266 #include "hisysevent.h" 267 268 int StartAbility() 269 { 270 ... // 其他业务逻辑 271 int ret = HiSysEventWrite(HiSysEvent::Domain::AAFWK, "START_APP", HiSysEvent::EventType::BEHAVIOR, "APP_NAME", "com.ohos.demo"); 272 ... // 其他业务逻辑 273 } 274 ``` 275 276#### C打点开发实例 277 278假设业务模块需要在应用启动时进行打点来记录应用启动事件,且需要记录应用的包名信息,完整使用示例如下所示: 279 2801. 首先,需要在业务模块的在BUILD.gn里增加HiSysEvent部件依赖。 281 282 ```c++ 283 external_deps = [ "hisysevent_native:libhisysevent" ] 284 ``` 285 2862. 在业务模块的应用启动函数StartAbility()中,调用打点接口并传入对应事件参数。 287 288 ```c 289 #include "hisysevent_c.h" 290 291 int StartAbility() 292 { 293 ... // 其他业务逻辑 294 char packageName[] = "com.ohos.demo"; 295 HiSysEventParam param = { 296 .name = "APP_NAME", 297 .t = HISYSEVENT_STRING, 298 .v = { .s = packageName }, 299 .arraySize = 0, 300 }; 301 HiSysEventParam params[] = { param }; 302 int ret = OH_HiSysEvent_Write("AAFWK", "START_APP", HISYSEVENT_BEHAVIOR, params, sizeof(params) / sizeof(params[0])); 303 ... // 其他业务逻辑 304 } 305 ``` 306 307#### kernel打点开发实例 308 309假设内核业务模块需要在设备启动时进行打点来记录设备启动事件,完整使用示例如下所示: 310 3111. 在设备启动函数device_boot()中,构建一个启动事件对象,然后将事件进行上报,最后销毁事件对象。 312 313 ```c 314 #include <dfx/hiview_hisysevent.h> 315 316 #include <linux/errno.h> 317 #include <linux/printk.h> 318 319 int device_boot() 320 { 321 ... // 其他业务逻辑 322 struct hiview_hisysevent *event = NULL; 323 int ret = 0; 324 325 event = hisysevent_create("KERNEL", "BOOT", BEHAVIOR); 326 if (!event) { 327 pr_err("failed to create event"); 328 return -EINVAL; 329 } 330 ret = hisysevent_put_string(event, "MSG", "This is a test message"); 331 if (ret != 0) { 332 pr_err("failed to put sting to event, ret=%d", ret); 333 goto hisysevent_end; 334 } 335 ret = hisysevent_write(event); 336 337 hisysevent_end: 338 hisysevent_destroy(&event); 339 ... // 其他业务逻辑 340 } 341 ``` 342 343#### 事件领域屏蔽的开发实例 344 345- 假设业务模块中,需要在某个cpp文件中屏蔽名称分别为AAFWK和POWER的事件领域的打点,在该cpp文件引入hisysevent.h头文件之前,定义名称为DOMAIN_MASKS的宏: 346 ```c++ 347 #define DOMAIN_MASKS "AAFWK|POWER" 348 349 #include "hisysevent.h" 350 ... // 其他业务逻辑 351 HiSysEventWrite(OHOS:HiviewDFX::HiSysEvent::Domain::AAFWK, "JS_ERROR", OHOS:HiviewDFX::HiSysEvent::EventType::FAULT, "MODULE", "com.ohos.module"); // 该HiSysEvent打点操作不会执行 352 ... // 其他业务逻辑 353 HiSysEventWrite(OHOS:HiviewDFX::HiSysEvent::Domain::POWER, "POWER_RUNNINGLOCK", OHOS:HiviewDFX::HiSysEvent::EventType::FAULT, "NAME", "com.ohos.module"); // 该HiSysEvent打点操作不会执行 354 ``` 355 356- 假设需要在整个业务模块中屏蔽名称分别为AAFWK和POWER的事件领域的打点,在模块的BUILG.gn文件中定义名称为DOMAIN_MASKS的宏: 357 ```gn 358 config("module_a") { 359 ... // 其他配置项 360 cflags_cc += ["-DDOMAIN_MASKS=\"AAFWK|POWER\""] 361 } 362 ``` 363 364- 假设需要在整个系统中屏蔽名称分别为AAFWK和POWER的事件领域的打点,则直接在/build/config/compiler/BUILD.gn文件中定义名称为DOMAIN_MASKS的宏: 365 ```gn 366 ... // 其他配置项 367 cflags_cc += ["-DDOMAIN_MASKS=\"AAFWK|POWER\""] 368 ``` 369 370# 参考 371 372HiSysEvent模块会将打点数据写入到节点文件中,而打点数据的解析处理会在Hiview模块中统一进行,详细处理过程可参考[Hiview开发指导](subsys-dfx-hiview.md)。 373