OpenHarmony源码解析之DFX子系统-标准系统接口使用说明

系统
DFX(Design for X)子系统是为了提升软件质量设计的工具集,目前包含的内容主要有:DFR(Design for Reliability,可靠性)和DFT(Design for Testability,可测试性)特性。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

1 DFX简介

DFX(Design for X)子系统是为了提升软件质量设计的工具集,目前包含的内容主要有:DFR(Design for Reliability,可靠性)和DFT(Design for Testability,可测试性)特性。

目前标准系统已实现以下功能:

  • HiLog:流水日志。
  • HiSysEvent:系统事件记录接口。
  • HiView:插件平台。
  • FaultLoggerd:应用故障订阅和收集。
  • HiAppEvent: js应用事件记录接口。

1.1 OpenHarmony架构图

OpenHarmony 源码解析之DFX子系统-标准系统接口使用说明-鸿蒙HarmonyOS技术社区

注:本文只介绍DFX各组件的使用,后续会有文章单独分析各组件的源码。

2 Hilog

HiLog是日志系统,提供给系统框架、服务、以及应用打印日志,记录用户操作、系统运行状态等。

用户态Process通过日志接口将日志内容写入hilogd buffer中,用户态的hilog工具支持将日志输出到控制台(console)进行查看,同时也支持通过hilog工具给hilogd发送命令将日志落盘,设置指定日志类型缓冲区的大小等。

HiLog架构图如下:

注:目前代码暂未看到有支持读取kernel日志。

代码结构:

/base/hiviewdfx/hilog 
├── frameworks           # 框架代码 
│   └── native          # HiLog native实现代码 
├── interfaces           # 接口 
│   └── native          # 对外C/C++接口 
│       └── innerkits   # 对内部子系统暴露的头文件 
│       └── kits        # 对应用暴露的头文件 
├── services 
│   └── hilogd          # 日志常驻服务实现 
│   └── hilogtool       # 日志工具实现 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

从使用者的角度,只需要关心hilog日志接口和hilog命令行工具的使用方法。

2.1 hilog接口使用说明

2.1.1 主要API说明

OpenHarmony 源码解析之DFX子系统-标准系统接口使用说明-鸿蒙HarmonyOS技术社区

2.1.2 使用方法

在模块BUILD.gn文件中添加依赖

external_deps = [ "hilog_native:libhilog" ] 
  • 1.
  • include头文件"hilog/log.h"
  • 接口调用

代码示例(以下代码从系统源码中摘录)

#include <vector> 
+#include "hilog/log.h" 
#include "string_ex.h" 
#include "uri.h" 
 
using std::string; 
using std::regex; 
+using OHOS::HiviewDFX::HiLog; 
 
namespace OHOS { 
namespace { 
@@ -39,6 +41,7 @@ namespace { 
    const size_t POS_INC_MORE = 2; 
    const size_t POS_INC_AGAIN = 3; 
    const regex SCHEME_REGEX("[a-zA-Z][a-zA-Z|\\d|+|-|.]*$"); 
+    const HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0xD001800, "URI"}; 
}; // namespace 
 
Uri::Uri(const string& uriString) 
@@ -48,6 +51,7 @@ Uri::Uri(const string& uriString) 
    port_ = NOT_CALCULATED; 
 
    if (uriString.empty()) { 
+        HiLog::Error(LABEL, "Input empty!"); 
        return
    } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

2.2 hilog命令行工具使用说明

注:落盘日志文件保存路径为"/data/log/hilog/"。

3 HiSysEvent

hisysevent组件定义了HiSysEvent埋点接口供应用框架、系统服务使用,用于向hiview上报系统事件信息。通过在关键路径埋点记录系统在运行过程中的重要信息,辅助开发者定位问题。

OpenHarmony 源码解析之DFX子系统-标准系统接口使用说明-鸿蒙HarmonyOS技术社区

3.1 接口说明

/** 
     * @brief 写系统事件 
     * @param domain    事件的domain 
     * @param eventName 事件名 
     * @param type      事件类型 
     * @param keyValues 可变参数,键值对 
     * @return 0 成功,其他失败 
     */ 
    template<typename... Types> static int Write(const std::string &domain, const std::string &eventName, 
        EventType type, Types... keyValues) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

 枚举类型EventType定义了事件类型

enum EventType { 
        FAULT     = 1,    // system fault event 
        STATISTIC = 2,    // system statistic event 
        SECURITY  = 3,    // system security event 
        BEHAVIOR  = 4     // system behavior event 
    }; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

 HiSysEvent内部类Domain中定义了一些字符串常量,用于表示不同的domain

3.2 接口使用

在BUILD.gn中增加依赖:

external_deps = [ "hisysevent_native:libhisysevent" ] 
  • 1.

 在类定义头文件或者类实现源文件中,包含HiSysEvent头文件:

#include "hisysevent.h" 
  • 1.

 示例:(以下代码摘自源码)

void EventReport::SendEvent(const EventInfo& eventInfo) 

    auto packageName = AceApplicationInfo::GetInstance().GetPackageName(); 
    if (packageName.size() > MAX_PACKAGE_NAME_LENGTH) { 
        StrTrim(packageName); 
    } 
    OHOS::HiviewDFX::HiSysEvent::Write(OHOS::HiviewDFX::HiSysEvent::Domain::ACE, eventInfo.eventType, 
        OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, 
        EVENT_KEY_ERROR_TYPE, eventInfo.errorType, 
        EVENT_KEY_PACKAGE_NAME, packageName); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

 hiview在收到消息后会打印日志,并把事件保存到

/data/log/LogService/sys_event_db/hisysevent.db 数据库中。

日志如下:

行 10430: 12-06 15:41:03.176   369   537 D 02d10/HiView-EventServer: Start: receive data from client <private> 
行 10431: 12-06 15:41:03.176   369   537 D 02d10/HiView-SysEventSource: Parser: parser raw message size=301, {"domain_":"ACE","name_":"JS_ERROR","type_":1,"time_":1638805263175,"pid_":821,"tid_":839,"PACKAGE_NAME":"","REASON":"Js Crash","SUMMARY":"Lifetime: 0.000000s 
行 10432: 12-06 15:41:03.176   369   537 D 02d10/HiView-SysEventSource: Js-Engine: Quick JS 
行 10433: 12-06 15:41:03.176   369   537 D 02d10/HiView-SysEventSource: Stacktrace: TypeError: cannot read property 'getAppPageStartConfig' of undefined 
行 10434: 12-06 15:41:03.176   369   537 D 02d10/HiView-SysEventSource:     at onPageShow (pages/EntryView.js) 
行 10435: 12-06 15:41:03.176   369   537 D 02d10/HiView-SysEventSource:     at onPageShow (pages/EntryView.js) 
行 10472: 12-06 15:41:03.180   369   537 I 02d10/HiView-SysEventSource: Parser: parser result domain_=ACE eventName_=JS_ERROR 
行 10473: 12-06 15:41:03.180   369   537 D 02d10/HiView-EventSource: PublishPipelineEvent: EventSource PublishPipelineEvent 
行 10474: 12-06 15:41:03.180   369   547 I 02d10/HiView-SysEventService: Convert2SysEvent: domain is ACE, eventName is JS_ERROR. 
行 10485: 12-06 15:41:03.180   369   547 D 02d10/HiView-SysEventDao: Insertinsert db file /data/log/LogService/sys_event_db/hisysevent.db with JS_ERROR 
行 10837: 12-06 15:41:03.232   369   547 I 02d10/HiView-DOCDB: open ejdb success 
行 10838: 12-06 15:41:03.232   369   547 I 02d10/HiView-DOCDB: open doc store 
行 11141: 12-06 15:41:03.249   369   547 D 02d10/HiView-DOCDB: put data to doc store success 
行 11142: 12-06 15:41:03.250   369   547 D 02d10/HiView-SysEventDbMgr: SaveToStore: save sys event 1, JS_ERROR 
行 11227: 12-06 15:41:03.253   369   547 I 02d10/Faultlogger: AddFaultLogIfNeed: Invalid module name 
行 11229: 12-06 15:41:03.253   369   547 I 02d10/HiView-SysEventSource: Recycle: recycle resource 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

4 HiView

Hiview是一个跨平台的终端设备维测服务集。目前开源部分仅包含插件管理平台和系统事件源。

架构图如下:

OpenHarmony 源码解析之DFX子系统-标准系统接口使用说明-鸿蒙HarmonyOS技术社区

Hiview由框架和插件组成,主要包含以下几部分:

  • 操作系统适配层(adapter),对使用的系统服务的接口进行适配。
  • Hiview基础定义(hiview base),包括插件基类、管道的定义,事件、事件队列定义以及一些工具类。
  • Hiview的核心模块(hiview core),包括插件配置,插件管理以及事件源。
  • Hiview服务(hiview services),目前仅包括hiview运行信息dump功能。
  • Hiview插件(plugins),为独立功能的业务模块。
  • Hiview维测服务是由事件驱动的,其核心为分布在系统各处的HiSysEvent桩点。

格式化的事件通过HiSysEvent API上报至hiview进行处理,请参考第三节HiSysEvent的架构图。

1.应用框架、系统服务使用HiSysEvent组件上报系统事件。

2.Hiview中SysEventSource获取消息,解析并组装成管道事件分发给插件处理。

注:hiview目前并未对外提供接口。

5 FaultLoggerd

faultloggerd是OpenHarmony中的C/C++运行时崩溃临时日志的生成及管理模块。主要流程如下:

进程A调用接口订阅故障收集功能。

进程A的异常信号处理器检测到异常信号后Fork出子进程运行processdump程序。

processdump程序Ptrace到父进程上,读取异常线程相关信息,包括寄存器以及调用栈。

processdump程序在读取异常信息后将其写入到/data/log/faultlog/temp目录下中做临时存储。

接口使用方法:

在模块的BUILD.gn文件中添加依赖

deps = ["//base/hiviewdfx/faultloggerd/interfaces/innerkits/signal_handler:dfx_signalhandler"
  • 1.
  • 包含"dfx_signal_handler.h"头文件
  • 调用DFX_InstallSignalHandler()方法订阅故障收集功能。

示例:(以下代码摘自源码)

base/telephony/ril_adapter/hril_hdf/hril_hdf.c中

#include "hril_hdf.h" 
#include <pthread.h> 
#include "dfx_signal_handler.h" //................[1]头文件 
#include "telephony_log_c.h" 
 
static int32_t RilAdapterInit(struct HdfDeviceObject *device) 

    if (device == NULL) { 
        return HDF_ERR_INVALID_OBJECT; 
    } 
    DFX_InstallSignalHandler(); //................[2]订阅故障收集功能 
    struct HdfSBuf *sbuf = HdfSBufTypedObtain(SBUF_IPC); 
    if (sbuf == NULL) { 
        TELEPHONY_LOGE("HdfSampleDriverBind, failed to obtain ipc sbuf"); 
        return HDF_ERR_INVALID_OBJECT; 
    } 
    if (!HdfSbufWriteString(sbuf, "string")) { 
        TELEPHONY_LOGE("HdfSampleDriverBind, failed to write string to ipc sbuf"); 
        HdfSBufRecycle(sbuf); 
        return HDF_FAILURE; 
    } 
    if (sbuf != NULL) { 
        HdfSBufRecycle(sbuf); 
    } 
    TELEPHONY_LOGD("sbuf IPC obtain test success!"); 
    LoadVendor(); 
    return HDF_SUCCESS; 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

注:程序崩溃后会在/data/log/faultlog/temp路径下生成临时文件。系统开发者可以通过日志定位崩溃问题。

6 HiAppEvent

HiAppEvent为JS应用提供事件打点接口,用于帮助应用记录在运行过程中发生的故障信息、统计信息、安全信息、用户行为信息,以支撑开发者分析应用的运行情况。

OpenHarmony 源码解析之DFX子系统-标准系统接口使用说明-鸿蒙HarmonyOS技术社区

6.1 接口说明

js接口定义文件:interface/sdk-js/api/phone/@ohos.hiAppEvent.d.ts

6.1.1 打点接口

JS 事件类型枚举——EventType

| 类型 | 描述|

| ----- | ----- |

| FAULT | 故障类型事件 |

| STATISTIC | 统计类型事件 |

| SECURITY | 安全类型事件 |

| BEHAVIOR | 行为类型事件 |

function write(eventName: string, eventType: EventType, keyValues: object): Promise; 应用事件异步打点方法,使用promise方式作为异步回调。

function write(string eventName, EventType type, object keyValues,

AsyncCallback callback): void 应用事件异步打点方法,使用callback方式作为异步回调。

输入参数说明:

  • eventName:事件名称。
  • eventType:事件类型。
  • keyValues:事件参数键值对,为Json对象类型。
  • callback:回调函数,可以在回调函数中处理接口返回值。返回值为0表示事件参数校验成功,事件正常异步写入事件文件;大于0表示事件存在异常参数,事件在忽略异常参数后再异步写入事件文件;小于0表示事件校验失败,不执行事件异步打点操作。

6.1.2 打点配置接口

function configure(config: ConfigOption): boolean;应用事件打点配置方法,可以对打点功能进行自定义配置。

参数config:应用事件打点配置项。

返回值:boolean,true表示配置成功,false表示配置失败。

ConfigOption应用打点配置选项

| 配置名 | 类型|必填 |说明|

| ----- | ----- |----- | ----- |

| disable | boolean |否|应用打点功能开关,true表示关闭打点功能,false表示不关闭打点功能|

| maxStorage | string |否|打点数据本地存储文件所在目录的配额大小,默认限额为“10M”。所在目录大小超出限额后会对目录进行清理操作,会按从旧到新的顺序逐个删除打点数据文件,直到目录大小不超出限额时停止。|

6.2 接口使用

引入模块:

import hiAppEvent from ‘@ohos.hiAppEvent’ 
  • 1.

应用事件打点:

callback方式

hiAppEvent.write("testevent", hiAppEvent.EventType.BEHAVIOR, {"key":"value"}, 
          (err, value) => { 
              console.log(`HiAppEvent testevent callback`); 
              if (err) { 
                  // 事件写入异常:事件存在异常参数或者事件校验失败不执行写入 
                  console.error(`HiAppEvent json-callback-error code=${err.code}`); 
              } else { 
                  console.log(`HiAppEvent json-callback-success value=${value}`) 
              } 
          }); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

 Promise方式

hiAppEvent.write("test_event", hiAppEvent.EventType.FAULT, {"int_data":100, "str_data":"strValue"}) 
  .then((value) => { 
      // 事件写入正常 
      console.log(`success to write event: ${value}`); 
  }).catch((err) => { 
      // 事件写入异常:事件存在异常参数或者事件校验失败不执行写入 
      console.error(`failed to write event because ${err.code}`); 
  }); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

 应用打点配置

配置应用事件打点功能开关

hiAppEvent.configure({ 
     disable: true 
}); 
  • 1.
  • 2.
  • 3.

配置事件文件目录存储限额大小

hiAppEvent.configure({ 
     maxStorage: '15M' 
}); 
  • 1.
  • 2.
  • 3.

7 总结

本文对标准系统目前已支持的DFX功能模块进行了介绍。demo请下载附件。

https://harmonyos.51cto.com/resource/1646

https://harmonyos.51cto.com/resource/1647

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-01-10 15:30:11

鸿蒙HarmonyOS应用

2023-04-12 15:31:11

系统服务管理鸿蒙

2021-09-18 14:40:37

鸿蒙HarmonyOS应用

2021-11-08 15:04:47

鸿蒙HarmonyOS应用

2022-02-17 20:57:07

OpenHarmon操作系统鸿蒙

2021-12-17 16:42:09

鸿蒙HarmonyOS应用

2022-01-06 16:17:58

鸿蒙HarmonyOS应用

2022-09-15 14:56:12

GDB调试鸿蒙

2022-05-10 11:17:27

电话子系统数据服务模块

2021-11-18 10:28:03

鸿蒙HarmonyOS应用

2022-05-24 15:46:51

Wi-FiSTA模式

2023-04-06 09:14:11

多模输入子系统鸿蒙

2021-09-13 15:15:18

鸿蒙HarmonyOS应用

2023-06-28 15:00:02

开源鸿蒙输入系统架构

2022-10-12 15:14:08

开机动画鸿蒙

2023-12-29 08:45:40

Python3.8鸿蒙解释器

2023-02-01 16:28:30

Linux内核鸿蒙

2021-09-16 15:04:28

鸿蒙HarmonyOS应用

2021-11-08 07:19:45

鸿蒙HarmonyOS应用

2022-04-02 20:45:04

Hi3516开发板操作系统鸿蒙
点赞
收藏

51CTO技术栈公众号