first commit

This commit is contained in:
clz
2026-07-31 17:23:11 +08:00
commit ffb55e29cc
14 changed files with 533 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+33
View File
@@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"footnotes": false,
"properties": true,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": true,
"bases": true,
"webviewer": false
}
+197
View File
@@ -0,0 +1,197 @@
{
"main": {
"id": "ad0ce60dbd95598b",
"type": "split",
"children": [
{
"id": "ab2cfe633a80cfd0",
"type": "tabs",
"children": [
{
"id": "9775ada2a6c4ad3e",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "HarmonyOS APM分析报告_20260731.md",
"mode": "source",
"source": false
},
"icon": "lucide-file",
"title": "HarmonyOS APM分析报告_20260731"
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "fe7025aab3adf23b",
"type": "split",
"children": [
{
"id": "8c1852d68ec6f400",
"type": "tabs",
"children": [
{
"id": "35bfd092fe57ec1a",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical",
"autoReveal": false,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-folder-closed",
"title": "文件列表"
}
},
{
"id": "f3546004181c68b3",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
},
"icon": "lucide-search",
"title": "搜索"
}
},
{
"id": "27b1b85764e4bd04",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-bookmark",
"title": "书签"
}
}
]
}
],
"direction": "horizontal",
"width": 300,
"collapsed": true
},
"right": {
"id": "97f5dfc3d6a31228",
"type": "split",
"children": [
{
"id": "8848d2e75dabcdd1",
"type": "tabs",
"children": [
{
"id": "06769677b1e54513",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "HarmonyOS APM分析报告_20260731.md",
"collapseAll": true,
"extraContext": true,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-coming-in",
"title": "反向链接"
}
},
{
"id": "b29901a5b8b6ffe5",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "HarmonyOS APM分析报告_20260731.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-going-out",
"title": "出链"
}
},
{
"id": "1428d6a20d2a4be0",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-tags",
"title": "标签"
}
},
{
"id": "4e44d2f4dbdfc859",
"type": "leaf",
"state": {
"type": "all-properties",
"state": {
"sortOrder": "frequency",
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-archive",
"title": "添加笔记属性"
}
},
{
"id": "fa2822a2042ecf50",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "HarmonyOS APM分析报告_20260731.md",
"followCursor": false,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-list",
"title": "大纲"
}
}
],
"currentTab": 4
}
],
"direction": "horizontal",
"width": 300
},
"left-ribbon": {
"hiddenItems": {
"switcher:打开快速切换": false,
"graph:查看关系图谱": false,
"canvas:新建白板": false,
"daily-notes:打开/创建今天的日记": false,
"templates:插入模板": false,
"command-palette:打开命令面板": false,
"bases:新建数据库": false
}
},
"active": "9775ada2a6c4ad3e",
"lastOpenFiles": [
"未命名.md",
"HarmonyOS APM分析报告_20260731.md"
]
}
+301
View File
@@ -0,0 +1,301 @@
# HarmonyOS APM分析报告
# 崩溃问题统计与分析
## 1. 结论摘要
最新7日数据中(2026.7.24-2026.7.30):
| 数据源 | 七日数量 | 7月30日数量 | 当前统计口径 |
| ------- | ---: | ------: | ----------------------- |
| 华为平台 | 12 | 6 | JS_ERROR、CPP_CRASH等崩溃事件 |
| Grafana | 33 | 17 | “崩溃类型 = All”,包含OOM |
两边的汇总事件类型未对齐。Grafana当前的“崩溃数”实际包含普通崩溃和OOM异常,而华为平台的“崩溃”统计不包含OOM异常。
核心结论:
1. **主要差异由统计不一致造成。** Grafana将13次OOM计入“崩溃数”,华为平台则将OOM单独展示。
2. **排除OOM后仍有2次差异。** 华为平台包含3次CPP_CRASH,而Grafana非OOM明细中只有3条JS类异常和1条`unKnowException`(已确认为CPP_CRASH)。
3. 因此Grafana平台统计的崩溃率与实际值相比偏高,**后续应将OOM异常排除崩溃统计,并入内存泄漏统计表盘**。并进一步分析CPP_CRASH缺失原因。
## 2. 数据截图展示和分析
### 2.1 核对范围
| 维度 | 核对值 |
| ----- | ------------------------------------------ |
| 应用 | `mobile-archive-am-qihuo-harmony` |
| 应用版本 | `FUHM037.08.390.10.32` / `1.20.02 / 10031` |
| 统计周期 | 2026-07-24至2026-07-30 |
| 重点核对日 | 2026-07-30 |
### 2.2 最新7日数据
#### 2.2.1 华为平台最新7日数据
| 日期 | 华为平台崩溃次数 |
|---|---:|
| 7月24日 | 0 |
| 7月25日 | 0 |
| 7月26日 | 0 |
| 7月27日 | 0 |
| 7月28日 | 3 |
| 7月29日 | 3 |
| 7月30日 | 6 |
| **合计** | **12** |
![华为平台最新7日崩溃趋势](report-assets/01-latest-platform-7day.png)
**图1:华为平台最新7日数据。7月30日崩溃次数为6,七日合计12次。**
#### 2.2.2 Grafana最新7日数据
| 指标 | 数量 |
| ----------------- | --: |
| 七日Grafana崩溃事件数 | 33 |
| 七日影响人数 | 32 |
| 7月30日Grafana崩溃事件数 | 17 |
![Grafana最新7日崩溃趋势](report-assets/02-latest-grafana-7day.png)
**图2:Grafana最新7日数据。该版本七日共33次,7月30日为17次。
#### 2.2.3 七日汇总分析
```text
Grafana 33次 = 崩溃(7次) + OOM(26次) + 可能的其他异常类型
华为平台 12次 = 崩溃事件
```
Grafana平台统计崩溃中大部分是OOM异常(26次),实际崩溃事件仅为(7次),且少于华为平台的12次崩溃。
### 2.3 华为平台7月30日数据
![华为平台7月30日崩溃次数](report-assets/03-current-platform-summary.png)
**图3:华为平台7月30日崩溃次数为6。**
![华为平台7月30日完整问题列表](report-assets/04-current-platform-detail.png)
**图4:华为平台7月30日共6条问题,每条发生1次。**
华为平台6条事件构成如下:
| 问题边界 | 类型 | 模块或位置摘要 | 次数 |
|---|---|---|---:|
| SYSTEM | CPP_CRASH | `/system/lib64/platformsdk/libuv.so` | 1 |
| APP | JS_ERROR | `MultiTypeInputRule.ts:22 / processInsert` | 1 |
| APP | CPP_CRASH | `libweituo_sdk_ohos.so` | 1 |
| APP | JS_ERROR | `MultiTypeInputRule.ts:22 / processInsert` | 1 |
| SYSTEM | CPP_CRASH | `libarkweb_engine.so` | 1 |
| APP | JS_ERROR | `NumberInputRule.ts:27 / shouldInsert` | 1 |
类型汇总:
```text
JS_ERROR 3次
CPP_CRASH 3次
合计 6次
```
### 2.4 Grafana 7月30日数据
![Grafana7月30日汇总](report-assets/05-grafana-day-summary.png)
**图5Grafana在7月30日共17次,影响17人。**
Grafana使用“崩溃类型 = All”,下方明细把OOM与普通崩溃共同列入“对应版本崩溃列表”。
![Grafana7月30日明细上半部分](report-assets/06-grafana-detail-part1.png)
**图6:Grafana明细上半部分,包含3条`Cannot read`、1条`Default OOM`及多条`OutOfMemory`。**
![Grafana7月30日明细下半部分](report-assets/07-grafana-detail-part2.png)
**图7:Grafana明细下半部分,包含其余`OutOfMemory`记录及1条`unKnowException`。**
Grafana当日17条事件分类如下:
| Grafana描述类别 | 条数 | 是否计入华为平台“崩溃”页 |
| ----------------------------------------- | -----: | ------------- |
| `Cannot read property index of undefined` | 3 | 是,属于JS类崩溃 |
| `unKnowException` | 1 | 是Native崩溃 |
| `Default oom error` | 1 | 否,应归入OOM |
| `OutOfMemory when trying to allocate...` | 12 | 否,应归入OOM |
| **合计** | **17** | — |
### 2.5 OOM明细及核算
| 序号 | OOM描述或申请字节数 | 次数 |
|---:|---|---:|
| 1 | `Default oom error` | 1 |
| 2 | `OutOfMemory: 79,953,920 bytes` | 1 |
| 3 | `OutOfMemory: 84,148,224 bytes` | 1 |
| 4 | `OutOfMemory: 89,915,392 bytes` | 1 |
| 5 | `OutOfMemory: 99,352,576 bytes` | 1 |
| 6 | `OutOfMemory: 100,663,296 bytes` | 1 |
| 7 | `OutOfMemory: 100,925,440 bytes` | 1 |
| 8 | `OutOfMemory: 119,013,376 bytes` | 1 |
| 9 | `OutOfMemory: 120,324,096 bytes` | 1 |
| 10 | `OutOfMemory: 122,159,104 bytes` | 1 |
| 11 | `OutOfMemory: 139,722,752 bytes` | 1 |
| 12 | `OutOfMemory: 143,130,624 bytes` | 1 |
| 13 | `OutOfMemory: 169,869,312 bytes` | 1 |
| **合计** | **OOM事件** | **13** |
排除OOM后的核算结果:
```text
Grafana可比崩溃数
= Grafana当日全口径事件数 - OOM事件数
= 17 - 13
= 4
```
### 2.6 当日对比结果
| 核对项 | 数量 |
|---|---:|
| Grafana全口径事件数 | 17 |
| Grafana OOM | 13 |
| Grafana排除OOM | 4 |
| 华为平台崩溃 | 6 |
| **剩余差异** | **2** |
现有截图中的Grafana崩溃ID被截断,暂时无法与华为平台问题特征ID进行ID级关联。因此,13条OOM的分类结论明确;剩余2条差异的精确归属仍需ELK原始记录或完整详情确认。
## 3. 问题定性
### 3.1 统计事件类型并非完全是崩溃事件
Grafana统计“崩溃数量”,但却将OOM同时计入。
华为平台采用:
- “崩溃”页展示JS_ERROR、CPP_CRASH等崩溃事件。
- “OOM”页单独展示内存溢出事件。
因此,使用Grafana的崩溃总数与实际上相比偏大
该问题属于**指标定义与界面表达不一致**,容易让使用者误以为两边存在大规模数据缺失。
### 3.2 两次CPP/Native类事件未对齐
排除OOM后,两边类型构成对比:
| 类型 | 华为平台 | Grafana明细 | 备注 |
| ------------- | ----: | --------------------------: | -------------------------------------------------------------------------------------------------- |
| JS类崩溃 | 3 | 3条`Cannot read property...` | 经过对比两平台数据内容一致 |
| CPP/Native类崩溃 | 3 | 1条`unKnowException`属于该类 | 华为平台的CPP_CRASH统计包含APP原因导致的崩溃,和**系统原因**导致的崩溃。<br><br>但是Grafana仅采集到了一条系统原因的CPP_CRASH,确实另外两个CPP_CRASH |
| **合计** | **6** | **4** | |
3条JS类事件基本可以对应。`unKnowException`对应其中1条Native事件,但仍有2条CPP_CRASH未在Grafana中以明确崩溃类型呈现。
### 3.3 最终定性
本次问题由两个层面组成:
1. **指标统计问题:** Grafana把OOM计入“崩溃数量”,导致汇总数明显偏高。
2. **数据链路问题:** 排除OOM后,仍有2条CPP/Native崩溃未对齐,存在漏报或者识别错误问题。
最终定性:
> **Grafana崩溃指标口径过宽,同时Native崩溃采集或展示存在漏报问题,需进一步分析。
# 启动耗时采集上报
## 1. 现状
目前与其他端相比,鸿蒙端APM缺失启动耗时的统计与上报功能,需要上线该功能来监控和分析启动耗时问题。
## 2. 技术可行性
### 2.1 获取应用开始启动的时间
在鸿蒙开发中,要监听用户手指点击应用图标开始启动的时间,可以通过系统提供的**启动耗时事件**来获取。系统会在用户点击图标时自动打点记录,开发者通过订阅 `HiAppEvent``APP_STARTUP`的事件,即可在参数 `icon_input_time` 拿到这个精确的时间戳。
**示例代码**
```typescript
import { hiAppEvent, hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
// 订阅应用启动耗时事件
hiAppEvent.addWatcher({
name: "appStartupWatcher",
// 订阅应用启动事件
events: ["APP_LAUNCH"],
onReceive: (domain: string, events: Array<hiAppEvent.AppEventPackage>) => {
for (const event of events) {
// 获取事件携带的参数
const params = event.params as Record<string, Object>;
// icon_input_time:用户点击桌面图标离手的时间戳(毫秒)
const iconInputTime = params['icon_input_time'] as number;
// extend_time:开发者调用 reportDrawnCompleted 的时间戳
const extendTime = params['extend_time'] as number;
// ......
}
}
});
```
注意,上述参数中的`extend_time`时间是根据开发者自定义调用`reportDrawnCompleted`时的时间戳,会在下述章节中阐述调用时机。
### 2.2 获取应用首屏渲染完毕的时间
要判断首页渲染完毕通常指**首帧内容完整绘制到屏幕**的时刻。可以通过 `@kit.ArkUI.inspector``createComponentObserver` 接口,监听首页根组件的 `draw` 事件,在回调中记录时间戳,即为渲染完成时刻。
**示例代码**
```typescript
import { inspector } from '@kit.ArkUI';
@Entry
@Component
struct HomePage {
@State startTime: number = 0;
private listener: inspector.ComponentObserver =
this.getUIContext().getUIInspector().createComponentObserver('HOME_ROOT');
private onDrawComplete = () => {
const renderEndTime = new Date().getTime();
console.info('首页渲染完成时间戳:', renderEndTime);
// 可在此处计算启动耗时:renderEndTime - icon_input_time
};
aboutToAppear() {
this.startTime = new Date().getTime();
this.listener.on('draw', this.onDrawComplete);
}
aboutToDisappear() {
this.listener.off('draw', this.onDrawComplete);
}
build() {
Column() {
// 首页核心内容
}
.id('HOME_ROOT') // 必须与 createComponentObserver 的 id 一致
.width('100%')
.height('100%')
}
}
```
# 改进目标与方向
## 改进目标
| 优先级 | 改进项 | 具体措施 | 验收标准 |
| --- | ------------ | ------------------------------------------ | --------------------------------- |
| P0 | 崩溃采集 | 将上报崩溃事件中的OOM识别拆分出来,仅上报真正的崩溃事件。OOM单独通过接口上报。 | 崩溃指标应只包含实际的崩溃类型,OOM独立统计。可大幅减小崩溃率。 |
| P1 | CPP崩溃数量与实际不符 | 分析找出CPP_CRASH漏报或是漏统计原因,并修复 | 展示崩溃数量的统计中,应包含全部的CPP_CRASH数据。 |
| P0 | 启动耗时统计上报 | 监听应用启动事件获取用户点击桌面事件和应用首屏渲染结束时间,计算出启动耗时 | 可准确获取应用启动耗时并上报统计。 |
| | | | |
| | | | |
## 后续方向
1. 分析项目http监控相关代码,定位并降低HTTP请求慢率等指标
2. 分析项目web监控相关代码,
Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB