1# HiSysEvent订阅 2 3 4## 概述 5 6 7### 功能简介 8 9HiSysEvent提供了跨进程订阅机制,开发者可以通过注册订阅接口实时获取关注的事件,例如电池模块订阅功耗相关的事件,用于分析耗电情况。 10 11 12### 约束与限制 13 14在订阅HiSysEvent事件之前,需要先完成HiSysEvent打点配置,具体配置方法请参考[《HiSysEvent打点配置指导》](../subsystems/subsys-dfx-hisysevent-logging-config.md)。 15 16 17## 开发指导 18 19### 接口说明 20 21#### C++接口说明 22 23C++ HiSysEvent订阅开发能力如下:HiSysEventManager类,具体API详见接口目录(/base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent_manager/include/)。 24 25>  **说明:** 26> 27> ListenerRule订阅规则对象构造函数形参类型RuleType请参考[HiSysEvent查询](subsys-dfx-hisysevent-query.md)中的“表4 RuleType匹配规则类型枚举”说明。 28 29 **表1** HiSysEvent订阅接口 30 31| 接口名称 | 描述 | 32| -------- | -------- | 33| int32_t HiSysEventManager::AddListener(std::shared_ptr<HiSysEventListener> listener,<br/> std::vector<ListenerRule>& rules) | 接口功能:添加对系统事件的订阅,通过设置规则订阅某些特定的事件。<br/>输入参数:<br/>- listener:订阅回调对象。<br/>- rules:事件订阅规则。<br/>返回值:<br/>- 0:订阅添加成功。<br/>- 负值:订阅添加失败。 | 34| int32_t HiSysEventManager::RemoveListener(std::shared_ptr<HiSysEventListener> listener) | 接口功能:移除对系统事件的订阅。<br/>输入参数:<br/>- listener:订阅回调对象。<br/>返回值:<br/>- 0:订阅移除成功。<br/>- 负值:订阅移除失败。 | 35 36 **表2** ListenerRule订阅规则对象 37 38| 接口名称 | 描述 | 39| -------- | -------- | 40| ListenerRule(const std::string& tag,<br/> RuleType ruleType = RuleType::WHOLE_WORD) | 接口功能:订阅规则构造函数,创建事件标签订阅规则对象。<br/>输入参数:<br/>- tag:订阅规则中指定的系统事件标签,字符串类型,最大长度16个字符(含),有效字符包含大小写字母及数字。<br/>- ruleType:订阅规则的规则类型,RuleType枚举类型(参考表3)。 | 41| ListenerRule(const std::string& domain,<br/> const std::string& eventName,<br/> RuleType ruleType = RuleType::WHOLE_WORD) | 接口功能:订阅规则构造函数,创建事件领域与事件名称订阅规则对象。<br/>输入参数:<br/>- domain:订阅规则中指定的系统事件领域,字符串类型,最大长度16个字符(含),有效字符包含大写字母、数字及下划线。<br/>- eventName:订阅规则中指定的系统事件名称,字符串类型,最大长度32个字符(含),有效字符包含大写字母、数字及下划线。<br/>- ruleType:订阅规则的规则类型,RuleType枚举类型(参考表3)。 | 42| ListenerRule(const std::string& domain,<br/> const std::string& eventName,<br/> const std::string& tag,<br/> RuleType ruleType = RuleType::WHOLE_WORD) | 接口功能:订阅规则构造函数,创建事件领域、事件名称,事件标签订阅规则对象。<br/>输入参数:<br/>- domain:订阅规则中指定的系统事件领域,字符串类型,最大长度16个字符(含),有效字符包含大写字母、数字及下划线。<br/>- eventName:订阅规则中指定的系统事件名称,字符串类型,最大长度32个字符(含),有效字符包含大写字母、数字及下划线。<br/>- tag:订阅规则中指定的系统事件标签,字符串类型,最大长度16个字符(含),有效字符包含大小写字母及数字。<br/>- ruleType:订阅规则的规则类型,RuleType枚举类型。 | 43 44 **表3** HiSysEventListener订阅对象 45 46| 接口名称 | 描述 | 47| -------- | -------- | 48| void HiSysEventListener::OnEvent(std::shared_ptr<HiSysEventRecord> sysEvent) | 接口功能:订阅事件的回调接口。<br/>输入参数:<br/>- sysEvent:订阅到的实时系统事件。<br/>返回值:<br/>无。 | 49| void HiSysEventListener::OnServiceDied() | 接口功能:服务异常回调。<br/>输入参数:<br/>无。<br/>返回值:<br/>无。 | 50 51 **表4** HiSysEventRecord系统事件对象 52| 接口名称 | 描述 | 53| -------- | -------- | 54|std::string HiSysEventRecord::AsJson()|接口功能:获取该系统事件的内容。<br/>输入参数:<br/>无。<br/>返回值:<br/>该系统事件的内容。| 55|std::string HiSysEventRecord::GetDomain()|接口功能:获取该系统事件的域名。<br/>输入参数:<br/>无。<br/>返回值:<br/>该系统事件的域名。| 56|std::string HiSysEventRecord::GetEventName()|接口功能:获取该系统事件的名称。<br/>输入参数:<br/>无。<br/>返回值:<br/>该系统事件的名称。| 57|HiSysEvent::EventType HiSysEventRecord::GetEventType()|接口功能:获取该系统事件的类型。<br/>输入参数:<br/>无。<br/>返回值:<br/>该系统事件的类型。| 58|std::string HiSysEventRecord::GetLevel()|接口功能:获取该系统事件的级别。<br/>输入参数:<br/>无。<br/>返回值:<br/>该系统事件的级别。| 59|std::string HiSysEventRecord::GetTag()|接口功能:获取该系统事件的标签。<br/>输入参数:<br/>无。<br/>返回值:<br/>该系统事件的标签。| 60|std::string HiSysEventRecord::GetTimeZone()|接口功能:获取该系统事件的时区。<br/>输入参数:<br/>无。<br/>返回值:<br/>时区内容,格式为“+0800”。| 61|int HiSysEventRecord::GetTraceFlag()|接口功能:获取该系统事件的分布式跟踪标志位。<br/>输入参数:<br/>无。<br/>返回值:<br/>分布式跟踪标志位。| 62|int64_t HiSysEventRecord::GetPid()|接口功能:获取落盘该系统事件的进程ID。<br/>输入参数:<br/>无。<br/>返回值:<br/>进程ID。| 63|int64_t HiSysEventRecord::GetTid()|接口功能:获取落盘该系统事件的线程ID。<br/>输入参数:<br/>无。<br/>返回值:<br/>线程ID。| 64|int64_t HiSysEventRecord::GetUid()|接口功能:获取落盘该系统事件的用户ID。<br/>输入参数:<br/>无。<br/>返回值:<br/>用户ID。| 65|uint64_t HiSysEventRecord::GetPspanId()|接口功能:获取该系统事件的分布式跟踪父分支ID。<br/>输入参数:<br/>无。<br/>返回值:<br/>分布式跟踪父分支ID。| 66|uint64_t HiSysEventRecord::GetSpandId()|接口功能:获取该系统事件的分布式跟踪分支ID。<br/>输入参数:<br/>无。<br/>返回值:<br/>分布式跟踪分支ID。| 67|uint64_t HiSysEventRecord::GetTime()|接口功能:获取该系统事件的时间戳。<br/>输入参数:<br/>无。<br/>返回值:<br/>时间戳。| 68|uint64_t HiSysEventRecord::GetTraceId()|接口功能:获取该系统事件的分布式跟踪链ID。<br/>输入参数:<br/>无。<br/>返回值:<br/>分布式跟踪链ID。| 69|void HiSysEventRecord::GetParamNames(std::vector<std::string>& params)|接口功能:获取该系统事件的所有键名。<br/>输入参数:<br/>- params:键名数组引用。<br/>返回值:<br/>无。| 70|int HiSysEventRecord::GetParamValue(const std::string& param, int64_t& value)|接口功能:将该系统事件键名为param的值解析为int64_t类型的值。<br/>输入参数:<br/>- param:键名。<br/>- value:int64_t类型引用。<br/>返回值:<br/>- 0:解析成功。<br/>- -1:该系统事件初始化失败,无法解析。<br/>- -2:不存在的键名。<br/>- -3:类型不匹配,无法转换成int64_t类型的值。| 71|int HiSysEventRecord::GetParamValue(const std::string& param, uint64_t& value)|接口功能:将该系统事件键名为param的值解析为uint64_t类型的值。<br/>输入参数:<br/>- param:键名。<br/>- value:uint64_t类型引用。<br/>返回值:<br/>- 0:解析成功。<br/>- -1:该系统事件初始化失败,无法解析。<br/>- -2:不存在的键名。<br/>- -3:类型不匹配,无法转换成uint64_t类型的值。| 72|int HiSysEventRecord::GetParamValue(const std::string& param, double& value)|接口功能:将该系统事件键名为param的值解析为double类型的值。<br/>输入参数:<br/>- param:键名。<br/>- value:double类型引用。<br/>返回值:<br/>- 0:解析成功。<br/>- -1:该系统事件初始化失败,无法解析。<br/>- -2:不存在的键名。<br/>- -3:类型不匹配,无法转换成double类型的值。| 73|int HiSysEventRecord::GetParamValue(const std::string& param, std::string& value)|接口功能:将该系统事件键名为param的值解析为string类型的值。<br/>输入参数:<br/>- param:键名。<br/>- value:std::string类型引用。<br/>返回值:<br/>- 0:解析成功。<br/>- -1:该系统事件初始化失败,无法解析。<br/>- -2:不存在的键名。<br/>- -3:类型不匹配,无法转换成std::string类型的值。| 74|int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<int64_t>& value)|接口功能:将该系统事件键名为param的值解析为int64_t类型的数组。<br/>输入参数:<br/>- param:键名。<br/>- value:int64_t类型数组引用。<br/>返回值:<br/>- 0:解析成功。<br/>- -1:该系统事件初始化失败,无法解析。<br/>- -2:不存在的键名。<br/>- -3:类型不匹配,无法转换成int64_t类型的数组。| 75|int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<uint64_t>& value)|接口功能:将该系统事件键名为param的值解析为uint64_t类型的数组。<br/>输入参数:<br/>- param:键名。<br/>- value:uint64_t类型数组引用。<br/>返回值:<br/>- 0:解析成功。<br/>- -1:该系统事件初始化失败,无法解析。<br/>- -2:不存在的键名。<br/>- -3:类型不匹配,无法转换成uint64_t类型的数组。| 76|int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<double>& value)|接口功能:将该系统事件键名为param的值解析为double类型的数组。<br/>输入参数:<br/>- param:键名。<br/>- value:double类型数组引用。<br/>返回值:<br/>- 0:解析成功。<br/>- -1:该系统事件初始化失败,无法解析。<br/>- -2:不存在的键名。<br/>- -3:类型不匹配,无法转换成double类型的数组。| 77|int HiSysEventRecord::GetParamValue(const std::string& param, std::vector<std::string>& value)|接口功能:将该系统事件键名为param的值解析为string类型的数组。<br/>输入参数:<br/>- param:键名。<br/>- value:std::string类型数组引用。<br/>返回值:<br/>- 0:解析成功。<br/>- -1:该系统事件初始化失败,无法解析。<br/>- -2:不存在的键名。<br/>- -3:类型不匹配,无法转换成std::string类型的数组。| 78 79#### C接口说明 80 81C HiSysEvent订阅开发能力如下:具体API详见接口目录(/base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent_manager/include/)。 82 83>  **说明:** 84> 85> HiSysEventWatcher订阅回调结构体OnEvent回调方法形参类型HiSysEventRecord请参考[HiSysEvent查询](subsys-dfx-hisysevent-query.md)中的“表11 HiSysEventRecord事件结构体”及“表12 HiSysEventRecord解析接口”说明。 86 87 **表5** HiSysEvent订阅接口 88 89| 接口名称 | 描述 | 90| ------------------------------------------------------------ | ------------------------------------------------------------ | 91| int OH_HiSysEvent_Add_Watcher(HiSysEventWatcher* watcher,<br/>HiSysEventWatchRule rules[],<br/>size_t ruleSize); | 接口功能:添加对系统事件的订阅,通过设置规则订阅某些特定的事件。<br/>输入参数:<br/>- watcher:订阅回调对象。<br/>- rules:事件订阅规则数组。<br/>- ruleSize:事件订阅规则数组长度。<br/>返回值:<br/>- 0:订阅添加成功。<br/>- 负值:订阅添加失败。 | 92| int OH_HiSysEvent_Remove_Watcher(HiSysEventWatcher* watcher); | 接口功能:移除对系统事件的订阅。<br/>输入参数:<br/>- watcher:订阅回调对象。<br/>返回值:<br/>- 0:订阅移除成功。<br/>- 负值:订阅移除失败。 | 93 94 95 **表6** HiSysEventWatcher订阅回调结构体 96| 属性名称 | 属性类型 | 描述 | 97| ------------- | -------------------------------------------------- | ------------------------------------------------------------ | 98| OnEvent | void (*)(HiSysEventRecord record); | 接口功能:订阅事件的回调接口。<br/>输入参数:<br/>- record:订阅到的实时系统事件。<br/>返回值:<br/>无。 | 99| OnServiceDied | void (*)(); | 接口功能:服务异常回调。<br/>输入参数:<br/>无。<br/>返回值:<br/>无。 | 100 101 **表7** HiSysEventWatchRule订阅规则结构体 102| 属性名称 | 属性类型 | 描述 | 103| ------------- | --------- | ---------------------------------- | 104| domain | char[] | 用来指定订阅的系统事件领域。 | 105| name | char[] | 用来指定订阅的系统事件名称。 | 106| tag | char[] | 用来指定订阅的系统事件标签。 | 107| ruleType | int | 用于指定订阅事件的匹配规则,取值请参考[HiSysEvent查询](subsys-dfx-hisysevent-query.md)中的“表4 RuleType匹配规则类型枚举”。 | 108| eventType | int | 用于指定订阅事件的事件类型,取值请参考[HiSysEvent查询](subsys-dfx-hisysevent-query.md)中的“表3 EventType事件类型枚举”,当取值0,表示订阅所有的事件类型。 | 109 110### 开发步骤 111 112#### C++ HiSysEvent订阅开发步骤 113 1141. 引入对应的头文件。 115 116 ```c++ 117 #include "hisysevent_manager.h" 118 ``` 119 1202. 业务领域实现对应的订阅回调接口。 121 122 ```c++ 123 class TestListener : public OHOS::HiviewDFX::HiSysEventListener { 124 public: 125 void OnEvent(std::shared_ptr<HiSysEventRecord> record) 126 { 127 if (record == nullptr) { 128 return; 129 } 130 std::cout << record->AsJson() << std::endl; 131 } 132 133 void OnServiceDied() 134 { 135 std::cout << std::string("service disconnect, exit") << std::endl; 136 exit(0); 137 } 138 }; 139 ``` 140 1413. 在订阅事件的地方调用订阅接口,并传入相应的订阅回调参数、订阅规则列表,在业务结束,注销此次订阅。 142 143 ```c++ 144 auto testListener = std::make_shared<TestListener>(); 145 // 事件标签规则订阅,规则类型为默认的全词匹配类型 146 ListenerRule tagRule("dfx"); 147 // 事件标签规则订阅,规则类型为正则匹配类型 148 ListenerRule regRule("dfx.*", RuleType::REGULAR); 149 // 事件领域及事件名称规则订阅,规则类型为前缀匹配类型 150 ListenerRule domainNameRule("HIVIEWDFX", "APP_USAGE", RuleType::PREFIX); 151 std::vector<ListenerRule> sysRules; 152 sysRules.push_back(tagRule); 153 sysRules.push_back(regRule); 154 sysRules.push_back(domainNameRule); 155 // 开始系统事件订阅 156 auto ret = HiSysEventManager::AddListener(testListener, sysRules); 157 // 订阅结束,移除订阅回调参数。 158 if (ret == 0) { 159 HiSysEventManager::RemoveListener(testListener); 160 } 161 ``` 162 163#### C HiSysEvent订阅开发步骤 164 1651. 引入对应的头文件。 166 167 ```c++ 168 #include "hisysevent_manager_c.h" 169 ``` 170 1712. 业务领域实现对应的订阅回调接口。 172 173 ```c++ 174 void OnEventTest(HiSysEventRecord record) 175 { 176 printf("OnEventTest: event=%s", record.jsonStr); 177 } 178 179 void OnServiceDiedTest() 180 { 181 printf("OnServiceDied"); 182 } 183 ``` 184 1853. 在订阅事件的地方调用订阅接口,并传入相应的订阅回调参数、订阅规则列表,在业务结束,注销此次订阅。 186 187 ```c++ 188 HiSysEventWatcher watcher; 189 watcher.OnEvent = OnEventTest; 190 watcher.OnServiceDied = OnServiceDiedTest; 191 // 事件标签规则订阅,规则类型为默认的全词匹配类型 192 constexpr char DFX_TAG[] = "dfx"; 193 HiSysEventWatchRule tagRule; 194 (void)strcpy_s(tagRule.tag, strlen(DFX_TAG) + 1, DFX_TAG); 195 tagRule.ruleType = 1; 196 tagRule.eventType = 0; 197 // 事件标签规则订阅,规则类型为正则匹配类型 198 constexpr char DFX_PATTERN_TAG[] = "dfx.*"; 199 HiSysEventWatchRule regRule; 200 (void)strcpy_s(regRule.tag, strlen(DFX_PATTERN_TAG) + 1, DFX_PATTERN_TAG); 201 regRule.ruleType = 3; 202 regRule.eventType = 0; 203 // 事件领域及事件名称规则订阅,规则类型为前缀匹配类型 204 constexpr char DOMAIN[] = "HIVIEWDFX"; 205 constexpr char NAME[] = "APP_USAGE"; 206 HiSysEventWatchRule domainNameRule; 207 (void)strcpy_s(domainNameRule.domain, strlen(DOMAIN) + 1, DOMAIN); 208 (void)strcpy_s(domainNameRule.name, strlen(NAME) + 1, NAME); 209 domainNameRule.ruleType = 2; 210 domainNameRule.eventType = 0; 211 // 开始系统事件订阅 212 HiSysEventWatchRule rules[] = {tagRule, regRule, domainNameRule}; 213 int ret = OH_HiSysEvent_Add_Watcher(&watcher, rules, sizeof(rules) / sizeof(HiSysEventWatchRule)); 214 // 订阅结束,移除订阅回调参数。 215 if (ret == 0) { 216 ret = OH_HiSysEvent_Remove_Watcher(&watcher); 217 } 218 ``` 219 220### 开发实例 221 222#### C++ HiSysEvent订阅开发实例 223 224假设业务模块需要订阅事件领域为HIVIEWDFX、事件名称为PLUGIN_LOAD的所有事件,其完整使用示例如下所示: 225 2261. 在业务模块的在BUILD.gn里增加hisysevent部件的libhisysevent及libhisyseventmanager依赖。 227 228 ```c++ 229 external_deps = [ 230 "hisysevent:libhisysevent", 231 "hisysevent:libhisyseventmanager", 232 ] 233 ``` 234 2352. 在业务模块的TestEventListening()函数中,调用订阅接口去订阅事件,业务结束时移除事件订阅。 236 237 ```c++ 238 #include <iostream> 239 240 #include "hisysevent_manager.h" 241 242 using namespace OHOS::HiviewDFX; 243 244 class TestListener : public HiSysEventQueryCallback { 245 public: 246 void OnEvent(std::shared_ptr<HiSysEventRecord> record) 247 { 248 if (record == nullptr) { 249 return; 250 } 251 std::cout << record->AsJson() << std::endl; 252 } 253 254 void OnServiceDied() 255 { 256 std::cout << std::string("service disconnect, exit") << std::endl; 257 exit(0); 258 } 259 }; 260 261 void TestEventListening() 262 { 263 auto testListener = std::make_shared<TestListener>(); 264 ListenerRule domainNameRule("HIVIEWDFX", "PLUGIN_LOAD", RuleType::WHOLE_WORD); 265 std::vector<ListenerRule> sysRules; 266 sysRules.push_back(domainNameRule); 267 auto ret = HiSysEventManager::AddListener(testListener, sysRules); 268 if (ret == 0) { 269 HiSysEventManager::RemoveListener(testListener); 270 } 271 } 272 ``` 273 274#### C HiSysEvent订阅开发实例 275 276假设业务模块需要订阅事件领域为HIVIEWDFX、事件名称为PLUGIN_LOAD的所有事件,其完整使用示例如下所示: 277 2781. 在业务模块的在BUILD.gn里增加hisysevent部件的libhisysevent及libhisyseventmanager依赖。 279 280 ```c++ 281 external_deps = [ "hisysevent:libhisyseventmanager" ] 282 283 // for strcpy_s 284 deps = [ "//third_party/bounds_checking_function:libsec_shared" ] 285 ``` 286 2872. 在业务模块的TestEventListening()函数中,调用订阅接口去订阅事件,业务结束时移除事件订阅。 288 289 ```c++ 290 #include <securec.h> 291 292 #include "hisysevent_manager_c.h" 293 294 void OnEventTest(HiSysEventRecord record) 295 { 296 printf("OnEventTest: event=%s", record.jsonStr); 297 } 298 299 void OnServiceDiedTest() 300 { 301 printf("OnServiceDied"); 302 } 303 304 void TestEventListening() 305 { 306 HiSysEventWatcher watcher; 307 watcher.OnEvent = OnEventTest; 308 watcher.OnServiceDied = OnServiceDiedTest; 309 constexpr char DOMAIN[] = "HIVIEWDFX"; 310 constexpr char NAME[] = "PLUGIN_LOAD"; 311 HiSysEventWatchRule domainNameRule; 312 (void)strcpy_s(domainNameRule.domain, strlen(DOMAIN) + 1, DOMAIN); 313 (void)strcpy_s(domainNameRule.name, strlen(NAME) + 1, NAME); 314 domainNameRule.ruleType = 1; 315 domainNameRule.eventType = 0; 316 HiSysEventWatchRule rules[] = {domainNameRule}; 317 int ret = OH_HiSysEvent_Add_Watcher(&watcher, rules, sizeof(rules) / sizeof(HiSysEventWatchRule)); 318 if (ret == 0) { 319 ret = OH_HiSysEvent_Remove_Watcher(&watcher); 320 } 321 } 322 ``` 323