first commit
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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** |
|
||||
|
||||

|
||||
|
||||
**图1:华为平台最新7日数据。7月30日崩溃次数为6,七日合计12次。**
|
||||
|
||||
#### 2.2.2 Grafana最新7日数据
|
||||
|
||||
| 指标 | 数量 |
|
||||
| ----------------- | --: |
|
||||
| 七日Grafana崩溃事件数 | 33 |
|
||||
| 七日影响人数 | 32 |
|
||||
| 7月30日Grafana崩溃事件数 | 17 |
|
||||
|
||||

|
||||
|
||||
**图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日数据
|
||||
|
||||

|
||||
|
||||
**图3:华为平台7月30日崩溃次数为6。**
|
||||
|
||||

|
||||
|
||||
**图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日数据
|
||||
|
||||

|
||||
|
||||
**图5:Grafana在7月30日共17次,影响17人。**
|
||||
|
||||
Grafana使用“崩溃类型 = All”,下方明细把OOM与普通崩溃共同列入“对应版本崩溃列表”。
|
||||
|
||||

|
||||
|
||||
**图6:Grafana明细上半部分,包含3条`Cannot read`、1条`Default OOM`及多条`OutOfMemory`。**
|
||||
|
||||

|
||||
|
||||
**图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监控相关代码,
|
||||
|
||||
|
After Width: | Height: | Size: 388 KiB |
|
After Width: | Height: | Size: 191 KiB |
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 439 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 456 KiB |
|
After Width: | Height: | Size: 498 KiB |
|
After Width: | Height: | Size: 522 KiB |
|
After Width: | Height: | Size: 520 KiB |