Skip to main content

Harmony(鸿蒙)

一、Harmony SDK 简介

Bugly Harmony 版本,支持Harmony OS Next平台基础异常问题的捕获上报,包含Js异常、Cpp异常、AppFreeze、错误,异常捕获后上报到 Bugly平台。Bugly Harmony SDK 基于Harmony平台arkTs开发,可通过Har包集成方式接入,提供arkTs接口。

提醒

Bugly鸿蒙专业版暂时对业务提供免费开放支持。

二、 接入 Harmony SDK

步骤一、注册产品

1、在 Bugly平台 上注册产品,平台选择 Harmony

注册产品

2、按照提示填写产品相关信息,Bundle ID字段可填写鸿蒙AppScope -> app.json5中定义的 bundleName 字段。

注册产品

3、注册完成后,可在左侧栏-设置-产品信息 查看 APP IDAPP KEY 等信息。

注册产品

步骤二、集成SDK

自动集成(推荐)

1、配置内网鸿蒙三方库,执行以下命令。(设置默认存在该三方库,则无需配置)

ohpm config set registry https://ohpm.openharmony.cn/ohpm/
提醒

设置默认原始只有鸿蒙官方三方库,如添加了其他三方库,需通过 ohpm config list 查看设置的三方库,手动将 https://ohpm.openharmony.cn/ohpm/ 追加后重新设置。

2、通过 ohpm 安装bugly库。

ohpm install bugly@latest

3、安装完成后可直接在arkTs中通过 import 导入引用。

手动集成

1、通过三方仓库或其他渠道下载 Bugly.har 三方SDK包。

2、在需要集成的模块下创建 libs 目录,将 Bugly.har 放入目录。

3、在模块的 oh-package.json5 文件中添加对应 dependencies,如下所示。

"dependencies": {
"bugly": "file:./libs/Bugly.har"
}

步骤三、混淆规则配置

注意

业务二次混淆Har包代码,可能导致部分Napi符号或字符串变量不可见,引入运行问题,建议业务直接keep Bugly Har包。

在 hap 工程目录下 obfuscation-rules.txt 混淆规则配置文件中直接添加如下规则。

-keep
../oh_modules/bugly

步骤四、初始化SDK

参考以下代码初始化 Bugly Harmony SDK,我们推荐尽早可能初始化SDK,如将初始化逻辑放在 AbilityonCreate 生命周期中。可参考如下代码进行初始化。

import { Bugly, BuglyBuilder } from "bugly";

initBugly(context: Context): void {
let builder = new BuglyBuilder();

builder.appId = 'xxxxxxx'; // 必填,Bugly产品信息中的APP ID
builder.appKey = 'xxx-xxxx-xxxx-xxxx-xxxx'; // 必填,Bugly产品信息中的APP KEY
builder.deviceId = "12345"; // 必填,设备ID,应保证设备ID对不同设备唯一
builder.platform = BuglyBuilder.PLATFORM_PRO; // 必填,设置上报平台,专业版本需设置为[BuglyBuilder.PLATFORM_PRO]

builder.appVersion = '1.0.0'; // 选填,业务的App版本
builder.buildNum = '0'; // 选填,业务App版本的构建号
builder.appChannel = 'website'; // 选填,业务App渠道
builder.userId = "12345"; // 选填,用户ID,如不设置则为空
builder.deviceModel = "huawei"; // 选填,机型,如不设置则为空
builder.debugMode = true; // 选填,默认开启,开启后Bugly SDK会打印更多调试日志,线上版本可关闭
builder.initDelay = 0; // 选填,延迟初始化时间,单位ms
builder.enableJsCrashProtect = false; // 选填,是否开启Js异常崩溃保护,设置为true后发生未捕获Js异常,进程不会退出

Bugly.init(context, builder); // 如果需等待Bugly完全初始化完成,使用await Bugly.init(context, builder);
}
注意事项
  1. Context需要传递ApplicationContext。
  2. 设备ID非常重要,Bugly使用设备ID来计算设备异常率,强烈建议应用设置正确的设备ID,以确保设备的唯一性。
  3. BuglyBuilder需在init方法前创建,且应避免重复调用init方法。
  4. 需要在调用Bugly.init接口,完成初始化后,再调用其他接口,进行定制化设置,否则设置不生效。

步骤五、验证数据上报

崩溃监控

初始化完成后,可以模拟崩溃进行上报,如执行以下调用。

Bugly.testCrash(Bugly.JS_CRASH); // 模拟Js异常

Bugly.testCrash(Bugly.CPP_CRASH); // 模拟native异常
提醒
  1. 异常问题发生后,需要二次启动Hap应用,即可完成上报。
  2. Crash异常会上报FaultLog信息,可在 附件 tab的 crashInfos.txt 文件中查看。

异常上报后,可在 崩溃->问题列表 中查看上报问题,点击进入 问题详情,查看上报内容。

上报内容

Freeze监控

与崩溃类似,可以通过Bugly提供的测试接口来模拟Freeze,调用后适当滑动屏幕,系统将判定为当前进程Freeze。

Bugly.testCrash(Bugly.APP_FREEZE); // 模拟Freeze异常

或是在UI线程中执行耗时逻辑,触发ANR。

let index = 0
while (true) {
index++
index = index % 2
}

Freeze问题触发上报后,在 Freeze->问题列表 中查看,点击进入 问题详情,查看上报内容。

上报内容

提醒
  1. Freeze异常上报的是Native、arkTs混合堆栈。
  2. Freeze异常会上报FaultLog信息及主线程消息信息,可在 附件 tab的 crashInfos.txt 文件中查看,event_handler 表示主线程未处理消息,event_handler_size_3s 表示THREAD_BLOCK事件3s时任务栈中任务数,event_handler_size_6s 表示THREAD_BLOCK事件6s时任务栈中任务数,peer_binder 表示binder调用信息。

API说明

信息更新接口

Bugly初始化后,更新必要字段,接口如下。

/**
* 更新device id
* @param deviceId device id
*/
public static updateDeviceId(deviceId: string);

/**
* 更新user id
* @param userId user id
*/
public static async updateUserId(userId: string);

/**
* 更新device model
* @param deviceModel
*/
public static updateDeviceModel(deviceModel: string);

错误上报接口

SDK 0.1.0 版本开始支持错误上报,可通过如下两个接口上报错误或自定义异常。

/**
* 上报catch错误
* @param e 错误error
*/
public static postError(e: Error);

/**
* 上报自定义异常
* @param name 异常名
* @param message 异常msg
* @param stack 异常堆栈
* @param storeFirst 是否优先存储,设置后会优先存储到文件,进程重启时上报,需要在异常现场情况下采集的错误设置为true,默认为false
* @param context [可选] 如果未初始化Bugly调用接口,storeFirst设置为true时,传入context也可记录错误(但会缺失部分现场信息)
*/
public static postCustomError(name: string, message: string, stack: string, storeFirst: boolean = false, context?: Context);
提醒
  1. postError 接口适用于arkTs中catch异常的捕获,直接传入catch错误的Error实例,会自动从Error实例中解析出对应的异常名称及堆栈信息。
  2. postCustomError 接口适用于上报自定义异常,如采用跨端Kotlin框架、游戏框架的异常。如果在正常环境下, storeFirst 参数无需设置,如果在进程可能被系统杀死环境下,建议设置 storeFirst 参数为 true ,当前只以同步方式保存异常到本地文件,二次启动进程时上报。

错误上报后,在如下TAB中进行展示。错误支持arkTs与native堆栈翻译,如是自定义错误上报,需保证与崩溃堆栈格式相同。

错误

自定义数据接口

SDK 0.2.0 开始支持设置自定义数据,自定义数据需在 CrashFreeze错误 发生前进行设置,可以进行更新和移除操作,异常上报时会携带设置的自定义数据。

/**
* 添加或更新自定义数据
* @param key 自定义key
* @param value 自定义value
*/
public static putUserData(key: string, value: string);

/**
* 移除自定义数据
* @param key 自定义key
*/
public static removeUserData(key: string);

/**
* 清空自定义数据
*/
public static clearUserData();

上报的自定义数据将在问题详情 -> 现场数据 -> 自定义字段 中进行展示,如下图所示。

自定义数据

自定义附件接口

SDK 0.2.0 开始支持设置业务自定义附件,自定义附件上报当前只支持 CrashFreeze 。在发生异常前,通过如下接口设置自定义附件的路径。

/**
* 设置自定义文件路径
* 传入参数为string数组,受限于AppEvent参数限制,数组值长度需在1024个字符以内
* @param paths 自定义文件路径
*/
public static async setCustomFilePaths(paths: Array<string>);

发生异常重启进程后,自定义附件会进行打包上传,在附件中展示为 custom_log.gzip

注意事项
  1. 自定义数据、自定义附件及现场信息的关联均会使用到系统 hiAppEvent.setEventParam 接口,该接口设置参数值长度需在1024个字符以内,且至多设置64个键值对。因此 自定义附件Array的所有值长度和需在1024个字符以内 ,否则可能设置失败。
  2. 如果业务有自行设置系统 hiAppEvent.setEventParam 接口,请务必预留一定数量的键值对供Bugly设置(5个以上),否则可能影响自定义数据、附件或现场信息关联。

日志导出接口

SDK 0.2.0 开始支持导出Bugly日志打印到业务日志系统中(不设置则默认打印到系统HiLog日志系统中),在初始化前调用如下接口进行设置

/**
* 设置Bugly日志适配器
* @param adapter 适配器
*/
public static setLogAdapter(adapter: BuglyLogAdapter);

/**
* Bugly日志适配接口
*/
export interface BuglyLogAdapter {
// debug级别日志
debug(arg: string): void;
// info级别日志
info(arg: string): void;
// warn级别日志
warn(arg: string): void;
// error级别日志
error(arg: string): void;
// fatal级别日志
fatal(arg: string): void;
}

FaultLog附件管理接口

Bugly注册系统异常回调后,会自动管理系统异常 FaultLog 文件,默认上报完后会进行删除,否则缓存区满会影响后续 FaultLog 文件生成。如不希望Bugly对 FaultLog 文件进行删除,而是自行管理,可通过以下接口进行设置。

/**
* 设置是否在bugly上报完fault log附件后删除
* @param shouldDelete 是否需要bugly删除
*/
public static setDeleteFaultLogFileAfterUpload(shouldDelete: boolean);

异常回调接口

SDK 0.3.3 开始支持Js Crash、Cpp Crash的异常回调,方便在发生异常时,能回调业务进行一些自定义操作,设置接口如下。

/**
* 异常回调接口
*/
export interface ICrashListener {
/**
* 异常发生时
* @param crashType 异常类型,当前仅支持 JsCrash、CppCrash
* @param crashName 异常名称,具体异常名称
* @param crashMsg 异常信息,CppCrash不支持
* @param crashStack 异常堆栈,CppCrash不支持
*/
onCrash(crashType: string, crashName: string, crashMsg: string, crashStack: string): void;
}

设置异常回调接口示例如下。

// 在Bugly初始化前定义接口实现
class DemoCrashListener implements ICrashListener {
onCrash(crashType: string, crashName: string, crashMsg: string, crashStack: string): void {
console.info('receive callback in demo.');
console.info(`Crash Type: ${crashType}`);
console.info(`Crash Name: ${crashName}`);
console.info(`Crash Message: ${crashMsg}`);
console.info(`Crash Stack: ${crashStack}`);
}
}

// Bugly初始化逻辑
let builder = new BuglyBuilder();
...
// 初始化时将接口示例传递给builder.crashListener参数
builder.crashListener = new DemoCrashListener();
...
await Bugly.init(context, builder);
注意事项
  1. 暂不支持App Freeze异常回调。
  2. Cpp Crash回调暂不支持提供堆栈信息。
  3. 请勿在回调中进行复杂操作,异常现场回调暂时无法保障稳定性,可能引入未知风险,请谨慎开启。

三、FAQ

1.为什么本地崩溃没有上报?如何进行排查?

首先确认Bugly本地已被正确初始化,在初始化时将Bugly的debug模式 builder.debugMode设置为true,查看 hiLog 日志打印如下,则表明Bugly已被正确初始化。

04-18 00:30:20.192   11522-11522  A00000/Bugly pid-11522 I  --------------------------------------------------------------------------------------------
04-18 00:30:20.192 11522-11522 A00000/Bugly pid-11522 I [init] Bugly debug模式开启 -- Bugly running in debug model.
04-18 00:30:20.192 11522-11522 A00000/Bugly pid-11522 I [init] Bugly debug模式将输出详细SDK Log -- More detailed log of Bugly SDK will be output in debug model.
04-18 00:30:20.192 11522-11522 A00000/Bugly pid-11522 I --------------------------------------------------------------------------------------------
04-18 00:30:20.214   11522-11522  A00000/Bugly pid-11522 I [init] init Bugly success.

其次确认异常是否能被Bugly正常上报,在触发异常后,IDE的 FaultLog 中可以查看到对应的错误信息。

FaultLog

重启应用,预计在10-15s左右能看见Bugly的上报日志,如下。

04-18 03:20:21.616   6260-6260    A00000/Bugly com.tencent.bugly I      upload Success, upload type: NativeCrash, record id: 62056e9c-6954-4c1c-aaf9-7d1479915d49.

2.为什么有的信息没有数据展示?

当前Bugly SDK版本基于Harmony OS Next 5.0版本开发,API Level 12,部分信息系统未提供获取API。

Bugly Harmony SDK持续建设完善中,如有疑问或诉求,可咨询Bugly小助手。

3.如何翻译鸿蒙Native堆栈?如何翻译arkTs混淆堆栈?

详情请参考 鸿蒙符号表

如有疑问或诉求,可咨询Bugly小助手。