文档管理中心
FAQ应用质量技术质量稳定性HiAppEvent获取的日志过长无法传输

HiAppEvent获取的日志过长无法传输

问题现象

使用HiAppEvent监听卡死的异常,获取的故障文件里面会把控制台的所有日志都输出,这样会造成大量冗余日志,经应用测试,整个报文大概在90万字,超出了后台的最大字符限制,如何不使用文件传输的方式,使用普通请求将报错日志传送给后台。

背景知识

HiAppEvent是在系统层面为应用开发者提供的一种事件打点机制,帮助应用记录在运行过程中发生的故障信息、统计信息、安全信息、用户行为信息,支撑开发者分析应用的运行情况。以便进一步统计分析访问数、日常用户活跃数量、用户操作习惯以及其他影响用户使用产品的关键因素。

解决方案

可以设置最大单次传输的数据大小为maxBufferLength,在HiAppEvent回调中获取到故障日志文件路径后,创建一个长度不超过maxBufferLength的ArrayBuffer,使用fs将故障日志文件读取到ArrayBuffer中再发送网络请求。

收起
自动换行
深色代码主题
复制
  1. import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
  2. import { window } from '@kit.ArkUI';
  3. import { hiAppEvent, hilog } from '@kit.PerformanceAnalysisKit';
  4. import { fileIo as fs } from '@kit.CoreFileKit';
  5. const DOMAIN = 0x0000;
  6. export default class EntryAbility extends UIAbility {
  7. onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  8. try {
  9. this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
  10. } catch (err) {
  11. hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
  12. }
  13. hilog.info(DOMAIN, 'testTag', want.toString());
  14. hilog.info(DOMAIN, 'testTag', launchParam.toString());
  15. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
  16. hiAppEvent.addWatcher({
  17. name: "watcher",
  18. appEventFilters: [
  19. {
  20. domain: hiAppEvent.domain.OS,
  21. names: [hiAppEvent.event.APP_FREEZE, hiAppEvent.event.APP_CRASH]
  22. }
  23. ],
  24. onReceive: (domain: string, appEventGroups: Array<hiAppEvent.AppEventGroup>) => {
  25. hilog.info(0x0000, 'testTag', `HiAppEvent onReceive: domain=${domain}`);
  26. for (const eventGroup of appEventGroups) {
  27. hilog.info(0x0000, 'testTag', `HiAppEvent eventName=${eventGroup.name}`);
  28. for (const eventInfo of eventGroup.appEventInfos) {
  29. let logPath: string = eventInfo.params['external_log'][0]; // 获取首个日志文件路径
  30. let accessible = fs.accessSync(logPath);
  31. if (accessible) {
  32. let maxBufferLength = 4096;
  33. let file = fs.openSync(logPath, fs.OpenMode.READ_ONLY);
  34. try {
  35. let stat = fs.statSync(logPath); // 获取文件信息
  36. let bufferLength = Math.min(stat.size, maxBufferLength);// 限制要发送的数据大小
  37. let buf = new ArrayBuffer(bufferLength); // 创建缓冲区
  38. fs.readSync(file.fd, buf); // 读取内容到缓冲区
  39. // sendByHttps() 自行实现将数据异步发送给后台
  40. } finally {
  41. fs.closeSync(file); // 关闭文件
  42. }
  43. }
  44. }
  45. }
  46. }
  47. });
  48. }
  49. onDestroy(): void {
  50. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
  51. }
  52. onWindowStageCreate(windowStage: window.WindowStage): void {
  53. // Main window is created, set main page for this ability
  54. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
  55. windowStage.loadContent('pages/Index', (err) => {
  56. if (err.code) {
  57. hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
  58. return;
  59. }
  60. hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
  61. });
  62. }
  63. onWindowStageDestroy(): void {
  64. // Main window is destroyed, release UI related resources
  65. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  66. }
  67. onForeground(): void {
  68. // Ability has brought to foreground
  69. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
  70. }
  71. onBackground(): void {
  72. // Ability has back to background
  73. hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
  74. }
  75. }

常见FAQ

Q:订阅崩溃事件hiAppEvent.addWatcher中onReceive回调在应用里能正常执行,在元服务里不执行。

A:API18之后可以实现在元服务里执行hiAppEvent.addWatcher中onReceive回调,API18版本之前不支持在元服务实现该事件。

Q:订阅应用终止事件,如果有资源泄漏导致的崩溃,如内存,句柄,线程泄漏导致的崩溃,会被应用终止事件监听到吗?

A:不会,终止事件是指应用程序被系统强制退出的情况,而崩溃主要是应用自身代码异常的情况,两种情况虽然都可以通过HiAppEvent订阅,但却是不同的订阅方式,详细参考:订阅崩溃事件订阅终止事件

Q:扩展进程的崩溃,能否在APP进程通过注册HiAppEvent的APP_CRASH事件监听到?

A:关于HiAppEvent对于扩展进程崩溃事件的订阅,只要在同一个应用内,A、B两个进程,进程A已调用addWatcher()接口订阅崩溃事件。如果进程B发生崩溃,进程A也能收到进程B的崩溃回调。只要进程A和B的应用名一致即可。

Q:AGC下的APMS异常管理与HiAppEvent崩溃订阅是否冲突?

A:APMS采集现网应用崩溃信息,与HiAppEvent不冲突。

在 FAQ 中进行搜索
请输入您想要搜索的关键词