# 启动性能监控(冷启动耗时)接入配置 > 作者:cheliangzhao > 日期:2026-08-06 > 涉及模块:`entry`(HAP 入口)+ `@kernel/app_monitor_event`(APM 事件 SDK) > 对应需求:冷启动耗时(`cold_start_time`)采集与看板聚合 --- ## 1. 背景与目标 统计同花顺期货鸿蒙版**冷启动耗时**,覆盖三条启动入口(`Index` / `LauncherPage` / `NetworkAnomalyPage`),区分冷启动 / 补投递四种场景,实现启动性能的持续观测与劣化告警。 采集分两条通道: - **链路 A(Elk 追溯,已上线验证)**:把冷启动指标结构化 JSON 经 `ElkService` 异步上报,字段最全,可明细定位。 - **链路 B(HXEventMonitor 分桶,需后台策略开启后生效)**:由 SDK 按桶自动归集,负责看板聚合曲线。 > ⚠️ 链路 B 是**策略驱动**的:SDK 侧在 `EventMonitorStrategy` 找不到 `launch` 模块的开启策略时,`create()/record()` 一律空转并打印 `Monitor.Event cold_start_time eventId has not created!`。应用侧无法绕开,必须由 **APM 后台下发对应模块策略**才能激活。 --- ## 2. 链路 A:Elk 追溯(已生效,无需后台操作) 上报字段(`LaunchElkBuilder`,业务来源 `launch`): | 字段 | 类型 | 说明 | |------|------|------| | `cold_start_time` | number | 冷启动耗时 ms = 系统事件 `extend_time` | | `start_type` | number | 启动类型(当前只统计 `0`=冷启动) | | `entry_page` | string | 入口页(`Index`/`LauncherPage`/`NetworkAnomalyPage`;补投递为 `unknown`) | | `app_version` | string | 应用内部版本号 | | `app_install_status` | string | `normal`/`new_install`/`over_written` | | `response_latency` | number | 离手到动效开始(需 API 22+) | | `animation_finish_time` | number | 动效完成耗时 | | `startability_processstart_dur` | number | 进程创建段(仅冷启动) | | `appattach_to_appforeground_dur` | number | 进程挂载段(仅冷启动) | | `git_commit` | string | 代码级追溯,劣化定位用 | | `is_backfill` | boolean | 是否系统补投递的上次启动遗留事件 | --- ## 3. 链路 B:HXEventMonitor 分桶指标(需后台开启) ### 3.1 后台需下发的模块策略 SDK 由 `HXEventMonitorPlugin.parseMonitorStrategy()` 读取,注入到 `EventStrategyBean` 后按模块打开。请为 **module=`launch`** 下发如下配置: ```json { "module": "launch", "config": { "status": 1, "sampling_rate": 1.0, "interval": 5000, "aggre_time": 60000, "aggre_count": 10 } } ``` 字段说明(对齐 `EventStrategyBean.fromJson`,仅这些字段生效): | 字段 | 取值 | 说明 | |------|------|------| | `module` | `launch` | 必须与代码 `HXEventMonitor.getEventFactory('launch')` 一致 | | `status` | `1` | **必须 `1`(STATUS_OPEN)**;否则 `isOpen()` 为 false,`create/record` 全空转 | | `sampling_rate` | `0~1` | 抽样率,`isOpen()` 需 `status==1 && 抽样通过` 才生效 | | `interval` | ms | 采集间隔 | | `aggre_time` | ms | 聚合时间阈值,达到即触发一次 push | | `aggre_count` | 条 | 聚合数量阈值,达到即触发一次 push | ### 3.2 指标定义 | 项 | 值 | |----|----| | 模块名 `module` | `launch` | | 指标名 `metric` | `cold_start_time` | | 值域 | 冷启动耗时 ms(`extend_time`) | | 分桶 `buckets` | `[500, 600, 700, 800, 1000, 1500, 2000, 3000]`(按实测 600–800ms 主体细分,尾部留劣化锚点) | | 维度1 `start_type` | 冷启动 `0` | | 维度2 `entry_page` | `Index`/`LauncherPage`/`NetworkAnomalyPage`/`unknown`(补投递) | | 维度3 `app_version` | 应用内部版本号 | | 维度4 `app_install_status` | `normal`/`new_install`/`over_written` | ### 3.3 判定生效 后台下发后,重启应用,冷启动日志中: - ✅ 消失:`Monitor.Event cold_start_time eventId has not created!` - ✅ 出现:`Cold start bucket metric recorded: ` 与 SDK 聚合 push 日志 - ✅ 看板出现 `launch` 模块 `cold_start_time` 桶分布 --- ## 4. 相关代码与文件 | 文件 | 作用 | |------|------| | `entry/src/main/ets/monitor/LaunchMonitor.ets` | APP_LAUNCH 订阅、Elk 上报、首帧 `reportDrawnCompleted`、桶指标定义与 record | | `entry/src/main/ets/monitor/LaunchMonitor.ets`(`ensureColdStartMetric`) | 创建 `launch/cold_start_time` 桶指标(幂等) | | `entry/src/main/ets/monitor/plugin/HXLaunchMonitorPlugin.ets` | 仿 `HXCrashMonitorPlugin` 接入的启动插件,在 `startPlugin()` 建指标 | | `entry/src/main/ets/monitor/APMHelper.ets` | 注册 `HXLaunchMonitorPlugin` 及配置类、`.plugin(...)` 列表 | | `entry/src/main/ets/entryability/EntryAbility.ets` | `onCreate` 早注册 `LaunchMonitor.init()` | | `entry/src/main/ets/pages/Index.ets` / `LauncherPage.ets` / `network/NetworkAnomalyPage.ets` | 首帧 `HOME_ROOT` 监听 + `reportFirstFrameOnDraw`/`dispose` | ### 打点时序 ``` EntryAbility.onCreate → LaunchMonitor.init()(注册 APP_LAUNCH watcher) 入口页 aboutToAppear → reportFirstFrameOnDraw(HOME_ROOT) → 首帧 draw → reportDrawnCompleted() 系统产生 APP_LAUNCH 事件(冷启动)→ onReceive ├─ 链路A: ElkService 上传冷启动 JSON(字段见 §2) └─ 链路B: HXEventMonitor record(cold_start_time)(依赖 launch 策略,见 §3) 补投递:icon_input_time 早于 watcher 注册 > 2000ms → 判为 backfill,entry_page=unknown ``` --- ## 5. 真机验证结论(2026-08-06,nova 14 Pro) | 场景 | 结果 | |------|------| | 全新安装首启(`new_install`) | 链路 A:`cold_start_time=1141ms`,Entry=Index,Elk 上报 ✅ | | 二次冷启动(`normal`) | 链路 A:`cold_start_time=1717ms`,Elk 上报 ✅ | | 链路 B(分桶) | ❌ 待后台下发 `launch` 策略(§3.1)后复测 | 编译:`./claude_tool/claude_compile.sh → BUILD_SUCCESS`