Development of Application Event Logging

Introduction

A traditional log system aggregates log information generated by all applications running on the entire device, making it difficult to identify key information in the log. Therefore, an effective logging mechanism is needed to evaluate mission-critical information, for example, number of visits, number of daily active users, user operation habits, and key factors that affect application usage.

HiAppEvent is a module that provides the event logging function for applications to log the fault, statistical, security, and user behavior events reported during running. Based on event information, you will be able to analyze the running status of applications.

Basic Concepts

  • Logging

    Logs changes caused by user operations to provide service data for development, product, and O&M analysis.

Event Design Specifications

  • Event domain: identifies the domain of an event. You are advised to set this parameter to the service module name to differentiate service modules.
  • Event name: specifies the name of an event. You are advised to set this parameter to a specific service name to differentiate services.
  • Event type: specifies the type of an event. Four event types are supported:
    • Behavior event: used to record the daily operation behavior of a user, for example, button click and page redirection.
    • Fault event: used to locate and analyze application faults, for example, frame freezing, network disconnection, and call drop.
    • Statistical event: used to collect statistics on key application behaviors, for example, usage duration and number of visits.
    • Security event: used to record events related to application security, for example, password change and user authorization.
  • Event parameter: specifies the parameters of an event. Each event can contain a group of parameters. You are advised to set this parameter to an event attribute or event context to depict the event details.

Available APIs

The following table provides only a brief description of related APIs. For details, see HiAppEvent.

Table 1 APIs for application event logging

API Description
write(AppEventInfo info, AsyncCallback<void> callback): void Logs application events in asynchronous mode. This API uses an asynchronous callback to return the result.
write(AppEventInfo info): Promise<void> Logs application events in asynchronous mode. This API uses a promise to return the result.

Table 3 APIs for watcher management

API Description
addWatcher(Watcher watcher): AppEventPackageHolder Adds an event watcher to subscribe to expected application events.
removeWatcher(Watcher watcher): void Adds an event watcher to unsubscribe from expected application events.

How to Develop

The following example illustrates how to log and subscribe to button click events of users.

  1. Create an ArkTS application project. In the displayed Project window, choose entry > src > main > ets > entryability > EntryAbility.ts, and double-click EntryAbility.ts. Then, add an event watcher to subscribe to button click events. The complete sample code is as follows:

    import hilog from '@ohos.hilog';
    import Ability from '@ohos.application.Ability'
    import Window from '@ohos.window'
    import hiAppEvent from '@ohos.hiviewdfx.hiAppEvent'
    
    export default class EntryAbility extends Ability {
        onCreate(want, launchParam) {
            hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
            hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
            hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
            hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? '');
    
            hiAppEvent.addWatcher({
                // Add a watcher. You can customize the watcher name. The system identifies different watchers based on their names.
                name: "watcher1",
                // Subscribe to application events you are interested in, for example, button click events.
                appEventFilters: [{ domain: "button" }],
                // Set the subscription callback trigger condition. In this example, a callback is triggered if one event is logged.
                triggerCondition: { row: 1 },
                // Implement the subscription callback function to apply custom processing to the event logging data obtained through subscription.
                onTrigger: function (curRow, curSize, holder) {
                    // If the watcher incurs an error while it is working, return a null holder object after recording the error in the log.
                    if (holder == null) {
                        hilog.error(0x0000, 'testTag', "HiAppEvent holder is null")
                        return
                    }
                    let eventPkg = null
                    // Fetch the subscription event package based on the specified threshold (512 KB by default) until all subscription event data is fetched.
                    // If all subscription event data is fetched, return a null event package object. The subscription callback process is ended.
                    while ((eventPkg = holder.takeNext()) != null) {
                        // Apply custom processing to the event logging data in the event package, for example, print the event logging data in the log.
                        hilog.info(0x0000, 'testTag', `HiAppEvent eventPkg.packageId=%{public}d`, eventPkg.packageId)
                        hilog.info(0x0000, 'testTag', `HiAppEvent eventPkg.row=%{public}d`, eventPkg.row)
                        hilog.info(0x0000, 'testTag', `HiAppEvent eventPkg.size=%{public}d`, eventPkg.size)
                        for (const eventInfo of eventPkg.data) {
                            hilog.info(0x0000, 'testTag', `HiAppEvent eventPkg.info=%{public}s`, eventInfo)
                        }
                    }
                }
            })
        }
    }
    
    
  2. Choose entry > src > main > ets > pages > index.ets, and double-click index.ets. Then, add a button, and enable logging of button click events in its onClick function. The complete sample code is as follows:

    import hiAppEvent from '@ohos.hiviewdfx.hiAppEvent'
    import hilog from '@ohos.hilog'
    
    @Entry
    @Component
    struct Index {
      @State message: string = 'Hello World'
    
      build() {
        Row() {
          Column() {
            Text(this.message)
              .fontSize(50)
              .fontWeight(FontWeight.Bold)
    
            Button("writeTest").onClick(()=>{
              // Enable event logging in the button click function to log button click events.
              hiAppEvent.write({
                // Define the event domain.
                domain: "button",
                // Define the event name.
                name: "click",
                // Define the event type.
                eventType: hiAppEvent.EventType.BEHAVIOR,
                // Define event parameters.
                params: { click_time: 100 }
              }).then(() => {
                hilog.info(0x0000, 'testTag', `HiAppEvent success to write event`)
              }).catch((err) => {
                hilog.error(0x0000, 'testTag', `HiAppEvent err.code: ${err.code}, err.message: ${err.message}`)
              })
            })
          }
          .width('100%')
        }
        .height('100%')
      }
    }
    
  3. Touch the run button on the IDE to run the project. Then, touch the writeTest button on the application UI to trigger application event logging.

  4. View the information printed in the Log window. If logging of the button click event is successful, you will see a message indicating successful event logging as well as the log information specific to processing of the event logging data in the subscription callback.

    HiAppEvent success to write event
    
    HiAppEvent eventPkg.packageId=0
    HiAppEvent eventPkg.row=1
    HiAppEvent eventPkg.size=124
    HiAppEvent eventPkg.info={"domain_":"button","name_":"click","type_":4,"time_":1670268234523,"tz_":"+0800","pid_":3295,"tid_":3309,"click_time":100}