关于 alibabacloud-emas-apm-query
alibabacloud-emas-apm-query 是用于排查 Alibaba Cloud EMAS APM 移动应用问题的技能。它将只读 CLI 查询、代表性事件样本、堆栈与日志检查,以及可选的源码定位整合为排障流程。
主要功能
- 01按错误率或数量排列问题
- 02检查问题指标和受影响版本
- 03获取代表性事件样本
- 04查看堆栈与业务日志
- 05将堆栈映射到源码
适用场景
- 01确定优先处理的移动应用问题
- 02比较不同设备或版本的问题样本
- 03从事件堆栈和日志中寻找线索
- 04定位源码行并提出修复方案
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ aliyun/ alibabacloud-aiops-skills --skill alibabacloud-emas-apm-query安装后在 Claude Code 中输入/alibabacloud-emas-apm-query确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/system-filters/anr-android.jsoncrash-android.jsoncrash-harmony.jsoncrash-iphoneos.jsoncustom-android.jsoncustom-harmony.jsoncustom-iphoneos.jsonindex.jsonlag-android.jsonlag-harmony.jsonlag-iphoneos.jsonmemory_alloc-android.jsonmemory_alloc-iphoneos.jsonmemory_leak-android.jsonmemory_leak-iphoneos.jsonreferences/acceptance-criteria.mdappkey-detection.mdbiz-module-reference.mdcli-installation-guide.mdfilter-reference.mdget-error.mdget-errors.mdget-issue.mdget-issues.mdram-policies.mdrelated-commands.mdtroubleshoot-workflow.mdverification-method.mdscripts/dig_issue.shlist_top_issues.sh详细介绍
alibabacloud-emas-apm-query
1. 场景说明与架构
移动应用接入 Alibaba Cloud EMAS APM 后,每天产生的 crash / anr / lag / custom / memory_leak / memory_alloc 事件会由 SDK 汇总并上报到后端。典型的问题排查工作流如下:
- 找出最值得修复的问题:按错误率 / 错误数排序 → 选择 Top 3~5
- 检查特定 Issue 的情况:获取其汇总指标和受影响版本
- 查找多个有代表性的样本:涵盖不同设备 / 版本 / 网络
- 阅读样本中的堆栈和业务日志:寻找可采取行动的线索
- 对照应用源代码并提出修复方案
此技能将上述 5 个步骤整合为一个 CLI 流水线。整个过程只调用 aliyun emas-appmonitor 的 4 个只读 API,且不依赖任何数据库 / 日志服务:
GetIssues → GetIssue → GetErrors → GetError
↓
(optional) stack ↔ user APP source → precise file:line + fix diff
支持的 BizModules:crash / anr / lag / custom / memory_leak / memory_alloc
支持的操作系统:android / iphoneos / harmony(harmony 不支持 anr / memory_*)
2. 前置条件
| 项目 | 要求 | 自检命令 |
|---|---|---|
| Aliyun CLI 版本 | >= 3.3.3 | aliyun version |
| 插件 | aliyun-cli-emas-appmonitor | aliyun emas-appmonitor --help |
| jq | 任意版本(脚本必需) | jq --version |
完整安装步骤:references/cli-installation-guide.md。建议:启用一次自动安装插件:
aliyun configure set --auto-plugin-install true
aliyun plugin update
3. 凭证预检查
不要输出 AK/SK 值;只需确认存在可用的配置文件:
aliyun configure list
预期输出中应包含一个 current 配置文件,其 Mode / RegionId 均非空。若没有,请根据 references/cli-installation-guide.md#Configuration 配置 AK / OAuth / StsToken / RamRoleArn 中的一种。
此技能在整个生命周期内都不会读取或转发 AK / SK 字段值本身。
4. AI 模式生命周期
开始(技能运行前):
aliyun configure ai-mode enable
aliyun configure ai-mode set-user-agent --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-emas-apm-query"
结束(问题排查完成后):
aliyun configure ai-mode disable
5. RAM 权限
此技能只需要 4 个只读的 emasha:View* 操作(ViewIssues / ViewIssue / ViewErrors / ViewError)。EMAS AppMonitor 的 RamCode 为 emasha,且不支持资源级授权,因此 Resource 固定为 "*"。
完整的最小权限 JSON 策略、对应的系统策略(AliyunEMASAppMonitorReadOnlyAccess / AliyunEMASAppMonitorFullAccess),以及常见权限错误的排查方法,请参阅 references/ram-policies.md。
[MUST] 权限失败处理:执行期间,任何命令或 API 调用因权限错误失败时,都必须按以下流程处理:
- 阅读
references/ram-policies.md,获取此 SKILL 所需权限的完整列表- 使用
ram-permission-diagnose技能引导用户申请所需权限- 暂停并等待用户确认已授予所需权限
6. 参数确认
重要:参数确认 — 在执行任何命令或 API 调用之前, 必须先与用户确认所有可由用户自定义的参数(例如 RegionId、实例名称、CIDR 块、 密码、域名、资源规格等)。未经用户明确批准,切勿假设或使用默认值。
| 参数 | 必填 | 类型 | 描述 | 默认值 |
|---|---|---|---|---|
app-key | 是 | int64 | EMAS APP Key(通常为 9 位或更多位数)。优先从当前工作区的 SDK 初始化代码中推断(参见 references/appkey-detection.md 中的 6 类规则);如果找到且仅找到一个匹配项,向用户说明并等待确认;如果找到多个匹配项,列出候选项并让用户选择;如果未找到,请用户手动提供。 | 无(默认从工作区探测) |
os | 是 | enum | android / iphoneos / harmony(H5 使用 h5,不在此范围内)。根据项目类型与 app-key 一起推断:build.gradle / AndroidManifest.xml → android;*.xcodeproj / Podfile → iphoneos;module.json5 + ets/ → harmony。对于跨平台 Flutter / Unity 项目,用户必须选择一个(android / iphoneos)。 | 无(默认根据项目类型探测) |
time-range | 是 | object | StartTime=<ms> EndTime=<ms> Granularity=1 GranularityUnit=<HOUR|DAY> | 最近 24 小时(用户可覆盖) |
biz-module | 否 | list | 如果省略,将扫描全部 6 个模块;如果指定,则仅分析该模块 | 全部 6 个 |
digest-hash | 否 | string | 如果用户已知特定 Issue,则跳过 Top-N 阶段,直接深入分析 | 无 |
top-n | 否 | int | Top 问题数量 | 5 |
filter-json | 否 | string | 进一步缩小范围(特定版本 / 设备型号 / 区域……),使用 JSON 字符串 | 不应用 |
时间戳单位:所有 API 均使用 Unix 毫秒。如果用户传入的值以秒为单位(< 1e12),脚本会自动乘以 1000。
biz-module 注意事项:CLI 的 --help 列出了旧版枚举(exception / crash / lag / custom / h5JsError / h5WhiteScreen);但 anr / memory_leak / memory_alloc 实际上会传递到后端并正常工作。此技能默认扫描用户要求的全部 6 个模块;请参见 references/biz-module-reference.md。
time-range 注意事项:在某些环境中,后端会拒绝 Granularity=60 GranularityUnit=MINUTE(返回 Code: 200, Message: "unknown error")。始终优先使用 Granularity=1 GranularityUnit=DAY 或 GranularityUnit=HOUR。
--os 注意事项:CLI 的 --help 将 --os 标记为可选,但实际上 省略该参数会返回空列表且不报错(Model.Items=[]、Total=0)。所有 4 个 API 都必须显式传入 --os。
--did 注意事项:get-error 的 --did 也在 --help 中标记为可选,但 后端实际上隐式要求该参数。省略后会返回 Code: 100011 Parameter Not Enough。请从 get-errors 的 Items[*].Did 中获取(dig_issue.sh 已处理此逻辑;手动调用 aliyun emas-appmonitor get-error 时,请显式传入该参数)。
DigestHash 的双重语义:get-errors 返回的 Items[*].DigestHash 是 单个事件的哈希,与传入的聚合 --digest-hash 不同。接下来调用 get-error 时,仍须使用聚合哈希(即在 get-issues / get-issue 中使用的哈希);不要切换为单事件哈希。
复用 biz-module:从 get-issues 获取 Top Issue 时使用的 bizModule,必须在接下来的三个步骤(get-issue / get-errors / get-error)中继续使用;否则响应将为空(同一个 DigestHash 只存在于一个 bizModule 下)。list_top_issues.sh 已为每一行附加 bm 字段,便于复用。
7. 核心工作流
flowchart TD
Start[User request] --> DetectCtx{Workspace can infer AppKey+OS?}
DetectCtx -- single match --> ConfirmCtx[Echo for user confirmation]
DetectCtx -- multiple matches --> PickCtx[List candidates, let user pick]
DetectCtx -- miss --> AskCtx[Ask user for AppKey + OS]
ConfirmCtx --> HasHash
PickCtx --> HasHash
AskCtx --> HasHash
HasHash{digestHash provided?}
HasHash -- yes --> SingleIssue[get-issue: fetch single Issue metadata]
HasHash -- no --> ParallelIssues[Parallel get-issues over 6 bizModules]
ParallelIssues --> TopN[Sort by errorRate, take Top 3-5]
TopN --> IterateTop[Iterate Top Issues]
IterateTop --> SingleIssue
SingleIssue --> GetErrors[get-errors: latest 3-5 samples]
GetErrors --> PickSample["Sample policy: latest / hot device / latest affected version"]
PickSample --> GetError[get-error: stack/threads/logs/dimensions]
GetError --> HasCode{CWD has APP source?}
HasCode -- yes --> CodeMatch[stack -> file + line -> diff]
HasCode -- no --> CliReport[CLI-only diagnostic report]
CodeMatch --> Report[Final report: issue list + root cause + fix]
CliReport --> Report
Report --> CallFailed{Any CLI call failed?}
CallFailed -- yes --> CliSelfDiag["CLI self-diagnose: --log-level debug / --cli-dry-run / configure list / plugin update"]
CallFailed -- no --> endNode[Done]
CliSelfDiag --> endNode
7.0 运行时定位 Skill 目录($SKILL_DIR)
加载 SKILL.md 时,Agent 已知 Skill 自身的路径(请参阅上下文中 <available_skills> 下的 fullPath / path 字段)。运行任何需要读取此 Skill 中捆绑资源(scripts/ / assets/ / references/)的 bash 命令之前,Agent 必须先将 SKILL.md 所在目录导出到 SKILL_DIR,且仅执行一次:
# The Agent fills in the absolute path of SKILL.md into the placeholder, then exports once
export SKILL_DIR="$(cd "$(dirname "<ABSOLUTE_PATH_OF_SKILL.md>")" && pwd)"
# Self-check: all three directories must exist
[[ -d "$SKILL_DIR/scripts" && -d "$SKILL_DIR/assets" && -d "$SKILL_DIR/references" ]] \
|| { echo "[ERROR] SKILL_DIR does not point to the root of this Skill: $SKILL_DIR" >&2; exit 1; }
规则:
- 不要硬编码
~/.cursor/skills-cursor/...或~/.claude/skills/...:此 Skill 可能分发在仓库中(.agent/skills/alibabacloud-emas-apm-query/),也可能位于用户级目录中,其绝对路径会因主机而异。 - 不要依赖进入 Skill 目录后使用相对路径:脚本会将生成的文件写入当前工作目录(用户的 APP 源码根目录);
cd会破坏这一语义。 - bash 脚本有回退机制:
scripts/list_top_issues.sh和scripts/dig_issue.sh会在开头通过BASH_SOURCE自动检测自身位置,因此即使未导出$SKILL_DIR,也能找到它。SKILL.md 中的其他内联jq/rg命令仍要求 Agent 先导出$SKILL_DIR。
7.1 阶段 A:Top N(未提供 digest-hash 时)
使用 scripts/list_top_issues.sh 并行扫描 6 个 biz_modules:
bash "$SKILL_DIR/scripts/list_top_issues.sh" \
--app-key <AppKey> \
--os <iphoneos|android|harmony> \
--start-time <startMs> \
--end-time <endMs> \
--top-n 5 \
--order-by ErrorRate
输出为合并后的 Top-N 表格,每行包含 {bm, digestHash, ec, er, edc, edr, name, type, reason}。
要添加筛选条件(例如“仅限 3.5.x 版本”),追加 --filter-json '{"Key":"appVersion","Operator":"in","Values":["3.5.0","3.5.1"]}';请参阅 references/filter-reference.md。
7.2 阶段 B:深入排查单个 Issue
使用 scripts/dig_issue.sh:
bash "$SKILL_DIR/scripts/dig_issue.sh" \
--app-key <AppKey> \
--os <iphoneos|android|harmony> \
--biz-module <crash|anr|lag|custom|memory_leak|memory_alloc> \
--digest-hash <13-char Base36> \
--start-time <startMs> --end-time <endMs> \
--sample-size 3
输出目录:
emas-apm-dig-<AppKey>-<DigestHash>-<epoch>/
01-get-issue.json
02-get-errors.json (contains the ClientTime/Uuid/Did triples)
samples/<Uuid>.json (complete JSON per sample, includes Backtrace/EventLog etc.)
report.md (structured markdown report)
7.3 阶段 C:代码映射 + 差异(如果 CWD 包含 APP 源码)
遵循 references/troubleshoot-workflow.md:
- 确定平台(Android / iOS / Harmony / RN / Flutter / Web)
Model.Backtrace→ 保留 APP 用户栈帧 → grep 源码 → 定位文件:行号- 使用
EventLog+Controllers+Threads+CustomInfo丰富时间线 - 输出最小差异(≤ 20 行 + 一句“原因”说明)
如果 CWD 不包含源码:仅输出 CLI 诊断报告(Issue 概览、样本维度对比、代表性堆栈),并附加提示:“切换到 APP 源码目录即可进行代码级定位”。
7.4 故障处理(仅限 CLI)
当任何 aliyun emas-appmonitor 调用失败时,按顺序执行以下自检:
aliyun configure list # 1. current profile / mode / region
aliyun plugin update # 2. latest plugin
aliyun emas-appmonitor <cmd> ... --cli-dry-run # 3. parameter serialization check
aliyun emas-appmonitor <cmd> ... --log-level debug # 4. HTTP body + RequestId
不要引导用户查询任何服务端数据源。
8. 成功验证
完整的 6 步 CLI 自检(包含可运行命令以及每步的通过/失败标准)见 references/verification-method.md。正确与错误 CLI 模式对照表见 references/acceptance-criteria.md。核心标准:
- 可访问:
get-issuesdry-run 成功打印 HTTP 正文 - 非空:某个 biz_module 的
Model.Total >= 1 - 稳定:使用相同参数调用两次,返回相同的 Top 5
DigestHash - 筛选有效:添加筛选条件后,
Total严格小于或等于完整数量 - 三级链路:
issues → issue → errors → error能端到端获取 Stack - 可诊断:发生人为诱发的错误时,输出包含
RequestId和ErrorCode
9. 清理
此 skill 为只读;它不会创建任何需要清理的云资源。
拆除仅涉及两项:
aliyun configure ai-mode disable
# (optional) delete the local JSON directories produced by dig_issue.sh
rm -rf ./emas-apm-dig-*
10. 最佳实践
- 先探测,再询问:进入主流程前,按照
references/appkey-detection.md在用户的工作区中 grep SDK 初始化代码,以推断app-key/os;命中后再向用户确认,而不是一开始就询问。 - 先看 Top,再深入排查:不要一开始就对每个 Issue 运行
dig_issue.sh——先使用list_top_issues.sh汇总 Top N,再逐一深入排查。CLI 调用总数为O(N),而不是O(all)。 - 始终传入
--os:--help中将全部 4 个 API 的--os标记为可选,但省略时会静默返回空结果。始终明确指定android / iphoneos / harmony。 get-error必须传入--did:--help中将其标记为可选,但后端实际上要求传入;从get-errors响应中的Items[*].Did获取该值。- 复用
biz-module:后续调用get-issue/get-errors/get-error时,必须使用在get-issues中返回该 Issue 的同一个 bizModule;切换后会返回空结果。 - 将时间范围从“宽”缩到“窄”:开始诊断时使用 24h /
Granularity=1 GranularityUnit=DAY;定位到具体版本 / 设备后,将范围缩至 1~4 小时,并使用GranularityUnit=HOUR。 - 过滤条件是 JSON 字符串:整个
--filter值必须是单个 JSON 字符串;使用jq -cn构造嵌套的SubFilters,避免手动转义出错(参见references/filter-reference.md)。 - 多账号场景:通过
aliyun configure list确认 profile,并显式传入--profile <name>,不要依赖隐式环境变量切换。 - 持久化
get-error响应:此 API 响应可能从数百 KB 到数 MB 不等;不要用head/tail截断 JSON。先写入> /tmp/emas-error-XXX.json,再用jq处理。 - Android 混淆:遇到
a.a.a.b.c这样的类名时,先向用户索取mapping.txt,再尝试代码映射,不要猜测。 - iOS 符号化未完成:当
Model.SymbolicStatus=false时,Stack中包含许多原始地址;只输出设备 / 版本维度的结论,并在上传 dSYM 后重新分析。 - 并行 QPS 控制:
list_top_issues.sh内置了sleep 0.3s以避免触发限流;扫描 6 个 biz_modules 总共只需 2~3 秒,无需额外并发。 biz-module结果为空不代表出错:harmony下的anr / memory_*或流量极低的 AppKey 返回Total=0都属正常,不要重试。- 不要反向使用此技能来写入数据:全部 4 个 API 都是
Get*/View*。如果用户希望“更新 Issue 状态”或“标记为已修复”,这属于UpdateIssueStatus等写入 API,超出本技能范围。
11. 参考链接
| 文档 | 用途 |
|---|---|
references/cli-installation-guide.md | Aliyun CLI 安装 / 配置 / 插件 / 凭据 |
references/appkey-detection.md | 从用户工作区识别 Android / iOS / Harmony / Flutter / Unity / H5 上的 AppKey 和操作系统 |
references/ram-policies.md | 最小权限 JSON + 权限失败处理 |
references/get-issues.md | GetIssues 参数 / 响应 / 排序 |
references/get-issue.md | GetIssue 参数 / 响应 |
references/get-errors.md | GetErrors 参数 / 响应 |
references/get-error.md | GetError 参数 / 响应 |
references/filter-reference.md | --filter 结构 / 运算符 / SubFilters / dry-run 验证 |
references/biz-module-reference.md | 6 个 biz_modules × 平台 × 可用的 filterCode 列表 |
references/troubleshoot-workflow.md | 从堆栈到源代码再到差异的完整流程 |
references/related-commands.md | 所有 aliyun emas-appmonitor 命令速查表 + 技能边界 |
references/verification-method.md | 包含通过 / 失败标准的 6 步可运行 CLI 验证 |
references/acceptance-criteria.md | 正确与错误的 CLI 模式对照表(用于审查 / 自检) |
assets/system-filters/index.json | 14 个静态过滤器快照索引(biz_module × 平台) |