1# HiSysEvent Query
2
3
4## Overview
5
6HiSysEvent allows you to query system events by specifying search criteria. For example, for a power consumption module, you can query required system events for analysis.
7
8
9## How to Develop
10
11### Available APIs
12
13#### C++ APIs
14
15HiSysEvent query is implemented using the API provided by the **HiSysEventManager** class. For details, see the [API Header Files](/base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent_manager/include/).
16
17> **NOTE**
18>
19> For details about **HiSysEventRecord** in the **OnQuery()** API of **HiSysEventQueryCallback**, see Table 4 in [HiSysEvent Listening](subsys-dfx-hisysevent-listening.md).
20
21  **Table 1** Description of the C++ HiSysEvent query API
22
23| Name| Description|
24| -------- | -------- |
25| int32_t Query(struct&nbsp;QueryArg&amp;&nbsp;arg,<br>std::vector&lt;QueryRule&gt;&amp;&nbsp;rules,<br>std::shared_ptr&lt;HiSysEventQueryCallback&gt;&nbsp;callback) | Queries system events by search criteria such as the time segment, event domain, and event name.<br>Input arguments:<br>- **arg**: event query parameter.<br>- **rules**: event filtering rules.<br>- **callback**: callback object for event query.<br>Return value:<br>- **0**: Query is successful.<br>- A negative value: Query has failed.|
26
27  **Table 2** Description of QueryArg objects
28
29| Field| Type| Description|
30| -------- | -------- | -------- |
31| beginTime | long long | Start time for query. The value is a Unix timestamp, in milliseconds.|
32| endTime | long long | End time for query. The value is a Unix timestamp, in milliseconds.|
33| maxEvents | int | Maximum number of returned events.|
34
35   **Table 3** Description of EventType enums
36
37| Event Type| Value| Description|
38| ------------ | ---- | ------------------ |
39| FAULT        | 1    | Fault type.    |
40| STATISTIC    | 2    | Statistical type.    |
41| SECURITY     | 3    | Security type.    |
42| BEHAVIOR     | 4    | User behavior type.|
43
44  **Table 4** RuleType enum values
45
46| Rule Type| Value| Description|
47| ------------ | ---- | ------------------ |
48| WHOLE_WORD   | 1    | Whole word matching.    |
49| PREFIX       | 2    | Prefix matching.    |
50| REGULAR      | 3    | Regular expression matching.    |
51
52  **Table 5** Description of QueryRule objects
53
54| Name| Description|
55| -------- | -------- |
56| QueryRule(const&nbsp;std::string&amp;&nbsp;domain,<br>const&nbsp;std::vector&lt;std::string&gt;&amp;&nbsp;eventList,<br>RuleType&nbsp;ruleType,<br>uint32_t&nbsp;eventType,<br>const&nbsp;std::string&&nbsp;cond) | Constructor used to create a **QueryRule** object.<br>Input arguments:<br>- **domain**: domain to which the event of the **QueryRule** object belongs, in the string format. By default, an empty string indicates that the domain is successfully matched.<br>**eventList**: event name list, in the **std::vector&lt;std::string&gt;** format. By default, an empty string indicates that the event names on the list are successfully matched.<br>- **ruleType**: rule type. For details, see Table 4.<br>- **eventType**: system event type. The value is of the uint32_t type. For details about the system event types, see Table 3. When **eventType** is set to **0**, all types of events are queried.<br>- **cond**: query criteria. The value is of the string type.|
57
58The **condition** parameter must be in the specified JSON string format. For example:
59
60    ```json
61    {
62        "version":"V1",
63        "condition":{
64            "and":[
65                {"param":"type_","op":">","value":0},
66                {"param":"uid_","op":"=","value":1201}
67            ]
68        }
69    }
70    ```
71- The **version** field is mandatory, indicating the supported version of the input condition. Currently, only **V1** is supported.
72- The **condition** field is mandatory, indicating the input condition.
73  - The **and** field is optional, indicating the AND relationship between conditions.
74    - The **param** field is mandatory, indicating the parameter name for condition matching. The value must be a string.
75    - The **op** field is mandatory, indicating the parameter comparison operator for condition matching. The value must be a string. Supported comparison operators include the following: =, >, <, >=, and <=.
76    - The **value** field is mandatory, indicating the parameter value for condition matching. The value must be a string or an integer.
77
78
79
80
81
82**Table 6** Description of HiSysEventQueryCallback objects
83
84| Name| Description|
85| -------- | -------- |
86| void&nbsp;HiSysEventQueryCallback::OnQuery(std::shared_ptr&lt;std::vector&lt;HiSysEventRecord&gt;&gt;&nbsp;sysEvents) | Callback object for event query.<br>Input arguments:<br>- **sysEvents**: event list.|
87| void&nbsp;HiSysEventQueryCallback::OnComplete(int32_t&nbsp;reason,&nbsp;int32_t&nbsp;total) | Callback object for completion of event query.<br>Input arguments:<br>- **reason**: reason for completion of event query. The value **0** indicates that the query is normal, and any other value indicates that the query has failed.<br>- **total**: total number of events returned in this query.|
88
89#### C APIs
90
91HiSysEvent query is implemented using the API provided in the following table. For details, see the [API Header Files](/base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent_manager/include/).
92
93  **Table 7** Description of the C HiSysEvent query API
94
95| Name                                                    | Description                                                        |
96| ------------------------------------------------------------ | ------------------------------------------------------------ |
97| int OH_HiSysEvent_Query(const HiSysEventQueryArg& arg, HiSysEventQueryRule rules[], size_t ruleSize, HiSysEventQueryCallback& callback); | Queries system events by search criteria such as the time segment, event domain, event name, and event parameter.<br>Input arguments:<br>- **arg**: event query parameter.<br>- **rules**: event filtering rules.<br>- **ruleSize**: number of event filtering rules.<br>- **callback**: callback object for event query.<br>Return value:<br>- **0**: Query is successful.<br>- A negative value: Query has failed.|
98
99  **Table 8** Description of the HiSysEventQueryArg structure
100
101| Field | Type| Description                                                |
102| --------- | -------- | ---------------------------------------------------- |
103| beginTime | int64_t  | Start time for query. The value is a Unix timestamp, in milliseconds.|
104| endTime   | int64_t  | End time for query. The value is a Unix timestamp, in milliseconds.|
105| maxEvents | int32_t  | Maximum number of returned events.                    |
106
107  **Table 9** Description of the HiSysEventQueryRule structure
108
109| Field     | Type | Description                              |
110| ------------- | --------- | ---------------------------------- |
111| domain        | char[]    | Event domain.          |
112| eventList     | char\[][] | Event name list.      |
113| eventListSize | size_t    | Size of the event name list.  |
114| condition     | char*     | Custom event parameter conditions for the query.|
115
116  **Table 10** Description of the HiSysEventQueryCallback structure
117
118| Field  | Type                                          | Description                                                        |
119| ---------- | -------------------------------------------------- | ------------------------------------------------------------ |
120| OnQuery    | void (*)(HiSysEventRecord records[], size_t size); | Callback object for event query.<br>Input arguments:<br>- **records**: event list.<br>- **size**: size of the event list.|
121| OnComplete | void (*)(int32_t reason, int32_t total);           | Callback object for completion of event query.<br>Input arguments:<br>- **reason**: reason for completion of event query. The value **0** indicates that the query is normal, and any other value indicates that the query has failed.<br>- **total**: total number of events returned in this query.|
122
123  **Table 11** Description of the HiSysEventRecord event structure
124
125| Field | Type           | Description                      |
126| --------- | ------------------- | -------------------------- |
127| domain    | char[]              | Event domain.          |
128| eventName | char\[]             | Event name.              |
129| type      | HiSysEventEventType | Event type.              |
130| time      | uint64_t            | Event timestamp.            |
131| tz        | char\[]             | Event time zone.              |
132| pid       | int64_t             | Process ID of the event.            |
133| tid       | int64_t             | Thread ID of the event.            |
134| uid       | int64_t             | User ID of the event.            |
135| traceId   | uint64_t            | Distributed call chain trace ID of the event.    |
136| spandId   | uint64_t            | Span ID for the distributed call chain trace of the event.  |
137| pspanId   | uint64_t            | Parent span ID for the distributed call chain trace of the event.|
138| traceFlag | int                 | Distributed call chain trace flag of the event.  |
139| level     | char*               | Event level.              |
140| tag       | char*               | Event tag.              |
141| jsonStr   | char*               | Event content.              |
142
143  **Table 12** Description of HiSysEventRecord APIs
144
145| Name                                                    |                                                              |
146| ------------------------------------------------------------ | ------------------------------------------------------------ |
147| void OH_HiSysEvent_GetParamNames(const HiSysEventRecord& record, char*** params, size_t& len); | Obtains all parameter names of an event.<br>Input arguments:<br>- **record**: event structure.<br>- **params**: parameter name array.<br>- **len**: size of the parameter name array.|
148| int OH_HiSysEvent_GetParamInt64Value(const HiSysEventRecord& record, const char* name, int64_t& value); | Parses the parameter value in the event to an int64_t value and assigns the value to **value**.<br>Input arguments:<br>- **record**: event structure.<br>- **name**: parameter name.<br>- **value**: parameter value of the int64_t type.|
149| int OH_HiSysEvent_GetParamUint64Value(const HiSysEventRecord& record, const char* name, uint64_t& value); | Parses the parameter value in the event to a uint64_t value and assigns the value to **value**.<br>Input arguments:<br>- **record**: event structure.<br>- **name**: parameter name.<br>- **value**: parameter value of the uint64_t type.|
150| int OH_HiSysEvent_GetParamDoubleValue(const HiSysEventRecord& record, const char* name, double& value); | Parses the parameter value in the event to a double value and assigns the value to **value**.<br>Input arguments:<br>- **record**: event structure.<br>- **name**: parameter name.<br>- **value**: parameter value of the double type.|
151| int OH_HiSysEvent_GetParamStringValue(const HiSysEventRecord& record, const char* name, char** value); | Parses the parameter value in the event to a char array value and assigns the value to **value**. You need to release the memory manually after usage.<br>Input arguments:<br>- **record**: event structure.<br>- **name**: parameter name.<br>- **value**: char\* reference.|
152| int OH_HiSysEvent_GetParamInt64Values(const HiSysEventRecord& record, const char* name, int64_t** value, size_t& len); | Parses the parameter value in the event to a int64_t array value and assigns the value to **value**. You need to release the memory manually after usage.<br>Input arguments:<br>- **record**: event structure.<br>- **name**: parameter name.<br>- **value**: int64_t\* reference.<br>- **len**: array size.|
153| int OH_HiSysEvent_GetParamUint64Values(const HiSysEventRecord& record, const char* name, uint64_t** value, size_t& len); | Parses the parameter value in the event to a uint64_t array value and assigns the value to **value**. You need to release the memory manually after usage.<br>Input arguments:<br>- **record**: event structure.<br>- **name**: parameter name.<br>- **value**: uint64_t\* reference.<br>- **len**: array size.|
154| int OH_HiSysEvent_GetParamDoubleValues(const HiSysEventRecord& record, const char* name, double** value, size_t& len); | Parses the parameter value in the event to a double array value and assigns the value to **value**. You need to release the memory manually after usage.<br>Input arguments:<br>- **record**: event structure.<br>- **name**: parameter name.<br>- **value**: double\* reference.<br>- **len**: array size.|
155| int OH_HiSysEvent_GetParamStringValues(const HiSysEventRecord& record, const char* name, char*** value, size_t& len); | Parses the parameter value in the event to a char* array value and assigns the value to **value**. You need to release the memory manually after usage.<br>Input arguments:<br>- **record**: event structure.<br>- **name**: parameter name.<br>- **value**: char\*\* reference.<br>- **len**: array size.|
156
157The return values of the HiSysEventRecord APIs are described as follows:
158
159- **0**: The parsing is successful.
160- -**1**: The event fails to be initialized.
161- -**2**: The parameter name does not exist.
162- -**3**: The type of the parameter value to be parsed does not match the type of the input parameter value.
163
164### How to Develop
165
166#### C++ HiSysEvent Query
167
1681. Import the corresponding header file.
169
170    ```c++
171    #include "hisysevent_manager.h"
172    ```
173
1742. Implement the callback API for the service domain.
175
176    ```c++
177    class TestQueryCallback : public HiSysEventQueryCallback {
178    public:
179        void OnQuery(std::shared_ptr<std::vector<HiSysEventRecord>> sysEvents) override
180        {
181            if (sysEvents == nullptr) {
182                return;
183            }
184            for_each((*sysEvents).cbegin(), (*sysEvents).cend(), [](const HiSysEventRecord& event) {
185                std::cout << event.AsJson() << std::endl;
186            });
187        }
188
189        void OnComplete(int32_t reason, int32_t total) override
190        {
191            std::cout << "Query completed" << std::endl;
192            return;
193        }
194    };
195    ```
196
1973. Call the query API while passing in **QueryArg**, **QueryRule**, and **QueryCallback**.
198
199    ```c++
200    // Create a QueryArg object.
201    long long startTime = 0;
202    long long endTime = 1668245644000; //2022-11-12 09:34:04
203    int queryCount = 10;
204    QueryArg arg(startTime, endTime, queryCount);
205
206    // Create a QueryRule object.
207    QueryRule rule("HIVIEWDFX", { "PLUGIN_LOAD" });
208    std::vector<QueryRule> queryRules = { rule };
209
210    // Create a QueryCallback object.
211    auto queryCallback = std::make_shared<TestQueryCallback>();
212
213    // Call the query API.
214    HiSysEventManager::Query(arg, queryRules, queryCallback);
215    ```
216
217#### C HiSysEvent Query
218
2191. Import the corresponding header file.
220
221    ```c++
222    #include "hisysevent_manager_c.h"
223    ```
224
2252. Implement the callback API for the service domain.
226
227    ```c++
228    void OnQueryTest(HiSysEventRecord records[], size_t size)
229    {
230        for (size_t i = 0; i < size; i++) {
231            printf("OnQuery: event=%s", records[i].jsonStr);
232        }
233    }
234
235    void OnCompleteTest(int32_t reason, int32_t total)
236    {
237        printf("OnCompleted, res=%d, total=%d\n", reason, total);
238    }
239    ```
240
2413. Call the query API while passing in **HiSysEventQueryArg**, **HiSysEventQueryRule**, and **HiSysEventQueryCallback**.
242
243    ```c++
244    // Create a HiSysEventQueryArg object.
245    HiSysEventQueryArg arg;
246    arg.beginTime = 0;
247    arg.endTime = 1668245644000; //2022-11-12 09:34:04
248    arg.maxEvents = 10;
249
250    // Create a HiSysEventQueryRule object.
251    constexpr char TEST_DOMAIN[] = "HIVIEWDFX";
252    constexpr char TEST_NAME[] = "PLUGIN_LOAD";
253    HiSysEventQueryRule rule;
254    (void)strcpy_s(rule.domain, strlen(TEST_DOMAIN) + 1, TEST_DOMAIN);
255    (void)strcpy_s(rule.eventList[0], strlen(TEST_NAME) + 1, TEST_NAME);
256    rule.eventListSize = 1;
257    rule.condition = nullptr;
258    HiSysEventQueryRule rules[] = { rule };
259
260    // Create a HiSysEventQueryCallback object.
261    HiSysEventQueryCallback callback;
262    callback.OnQuery = OnQueryTest;
263    callback.OnComplete = OnCompleteTest;
264
265    // Call the query API.
266    OH_HiSysEvent_Query(arg, rules, sizeof(rules) / sizeof(HiSysEventQueryRule), callback);
267    ```
268
269### Development Examples
270
271#### C++ HiSysEvent Query
272
273Suppose you want to query all events generated up to the current time with domain being **HIVIEWDFX** and name being **PLUGIN_LOAD**. The sample code is as follows:
274
2751. Add the **libhisysevent** and **libhisyseventmanager** dependencies of the **hisysevent** component to the **BUILD.gn** file of the service module.
276
277    ```c++
278    external_deps = [
279      "hisysevent:libhisysevent",
280      "hisysevent:libhisyseventmanager",
281    ]
282    ```
283
2842. Call the query API in the **TestQuery()** function of the service module.
285
286    ```c++
287    #include "hisysevent_manager.h"
288    #include <iostream>
289    #include <unistd.h>
290
291    using namespace OHOS::HiviewDFX;
292
293    class TestQueryCallback : public HiSysEventQueryCallback {
294    public:
295        void OnQuery(std::shared_ptr<std::vector<HiSysEventRecord>> sysEvents) override
296        {
297            if (sysEvents == nullptr) {
298                return;
299            }
300            for_each((*sysEvents).cbegin(), (*sysEvents).cend(), [](const HiSysEventRecord& event) {
301                std::cout << event.AsJson() << std::endl;
302            });
303        }
304
305        void OnComplete(int32_t reason, int32_t total) override
306        {
307            std::cout << "Query completed" << std::endl;
308            return;
309        }
310    };
311
312    int64_t GetMilliseconds()
313    {
314        auto now = std::chrono::system_clock::now();
315        auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
316        return millisecs.count();
317    }
318
319    void TestQuery()
320    {
321        long long startTime = 0;
322        long long endTime = GetMilliseconds();
323        int maxEvents = 100;
324        QueryArg arg(startTime, endTime, maxEvents);
325        QueryRule rule("HIVIEWDFX", { "PLUGIN_LOAD" });
326        std::vector<QueryRule> queryRules = { rule };
327        auto queryCallback = std::make_shared<TestQueryCallback>();
328        int ret = HiSysEventManager::Query(arg, queryRules, queryCallback);
329    }
330    ```
331
332#### C HiSysEvent Query
333
334Suppose you want to query all events generated up to the current time with domain being **HIVIEWDFX** and name being **PLUGIN_LOAD**. The sample code is as follows:
335
3361. Add the **libhisyseventmanager** dependency of the **hisysevent** component to the **BUILD.gn** file of the service module.
337
338```c++
339    external_deps = [ "hisysevent:libhisyseventmanager" ]
340
341    // for strcpy_s
342    deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
343```
344
3452. Call the query API in the **TestQuery()** function of the service module.
346
347    ```c++
348    #include "hisysevent_manager_c.h"
349    #include <securec.h>
350    #include <time.h>
351
352    void OnQueryTest(HiSysEventRecord records[], size_t size)
353    {
354        for (size_t i = 0; i < size; i++) {
355            printf("OnQuery: event=%s", records[i].jsonStr);
356        }
357    }
358
359    void OnCompleteTest(int32_t reason, int32_t total)
360    {
361        printf("OnCompleted, res=%d, total=%d\n", reason, total);
362    }
363
364    int64_t GetMilliseconds()
365    {
366        return time(NULL);
367    }
368
369    void TestQuery()
370    {
371        HiSysEventQueryArg arg;
372        arg.beginTime = 0;
373        arg.endTime = GetMilliseconds();
374        arg.maxEvents = 100;
375        constexpr char TEST_DOMAIN[] = "HIVIEWDFX";
376        constexpr char TEST_NAME[] = "PLUGIN_LOAD";
377        HiSysEventQueryRule rule;
378        (void)strcpy_s(rule.domain, strlen(TEST_DOMAIN) + 1, TEST_DOMAIN);
379        (void)strcpy_s(rule.eventList[0], strlen(TEST_NAME) + 1, TEST_NAME);
380        rule.eventListSize = 1;
381        rule.condition = nullptr;
382        HiSysEventQueryRule rules[] = { rule };
383        HiSysEventQueryCallback callback;
384        callback.OnQuery = OnQueryTest;
385        callback.OnComplete = OnCompleteTest;
386        int ret = OH_HiSysEvent_Query(arg, rules, sizeof(rules) / sizeof(HiSysEventQueryRule), callback);
387    }
388    ```
389