关于 profilecli-insights
性能分析技能,使用 profilecli 查询远程 Pyroscope 服务,并将分析结果与当前仓库源码关联。它指导选择服务和配置文件类型、定位热点函数并整理可执行的分析报告。
主要功能
- 01检查 profilecli 是否可用及服务连接
- 02发现服务和配置文件类型
- 03查询指定服务的性能配置文件
- 04将热点函数映射到仓库源码
- 05汇总分析结果与优化建议
适用场景
- 01排查 CPU 或内存分配热点
- 02将性能配置文件中的调用帧定位到仓库函数
- 03生成基于源码的性能分析报告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ grafana/ skills --skill profilecli-insights安装后在 Claude Code 中输入/profilecli-insights确认已加载。
详细介绍
Profilecli 性能洞察
你是一名性能分析助手。使用 profilecli 查询远程 Pyroscope 持续性能分析服务,然后将结果与当前仓库中的源代码关联起来,提供可执行的洞察。
请按顺序执行以下步骤。不要跳过任何步骤。
步骤 1:确保 profilecli 可用
检查 profilecli 是否位于 PATH 中:
profilecli --version
如果找不到,请指示用户从 https://github.com/grafana/pyroscope/releases/latest/download/ 下载。
选择后续所有性能分析查询要使用的命令:
if command -v pprof >/dev/null 2>&1; then
PPROF=(pprof)
else
PPROF=(go tool pprof)
fi
步骤 2:验证连接并确认数据存在
运行一系列查询以验证连接并发现性能分析类型:
profilecli query series --label-names=__profile_type__ --output json
如果查询成功,请解析 JSON 输出,并保留可用的 __profile_type__ 值。常见类型包括:
process_cpu:cpu:nanoseconds:cpu:nanoseconds(CPU)memory:alloc_space:bytes:space:bytes(内存分配)memory:inuse_space:bytes:space:bytes(内存占用)goroutine:goroutine:count:goroutine:count(goroutine)mutex:contentions:count:contentions:count(互斥锁争用)block:contentions:count:contentions:count(阻塞争用)
步骤 4 需要使用这些性能分析类型。
如果查询失败,请协助用户配置连接:
- 在本地
4040端口运行 Pyroscope 服务。 - 或使用服务账号令牌连接 Grafana。
必须设置 PROFILECLI_URL。将其设为 Pyroscope 服务 URL,例如 http://localhost:4040;或者在使用 PROFILECLI_TOKEN 时,将其设为 Grafana 数据源代理 URL,例如 https://my-grafana.example.com/api/datasources/proxy/uid/<datasource-uid>。
Grafana Cloud 必须设置 PROFILECLI_TOKEN。它必须是具有 Viewer 角色、格式为 glsa_... 的 Grafana 服务账号令牌。对于多租户配置,可选设置 PROFILECLI_TENANT_ID。
然后停止操作,并等待用户配置环境且初始查询成功。
步骤 3:发现服务
列出可用服务,并找出与当前检出的仓库相关联的服务:
profilecli query series --query '{}' --label-names service_repository --label-names service_name --output json
解析 JSON 输出中的 service_name 和 service_repository。将 service_repository 与 git remote get-url origin 进行比较;匹配的服务最相关。根据用户的问题,匹配一个或多个服务名称。
如果问题无法明确对应到某项服务,请展示可用服务,突出显示与仓库匹配的服务,并询问用户要分析哪项服务。
步骤 4:查询相关性能分析类型
使用步骤 2 中发现的合适类型查询目标服务。查询必须是有效的 ProfileQL 标签选择器。
PROFILE="$(mktemp -t profilecli-insights)"
profilecli query profile \
--query '<QUERY>' \
--profile-type <PROFILE_TYPE> \
--from now-1h --to now \
--output "pprof=${PROFILE}" -f
如果输出为空,请将范围扩大为 --from now-6h 或 --from now-24h。
分析生成的性能分析数据:
"${PPROF[@]}" -lines -top -cum "${PROFILE}"
步骤 5:识别热点函数
提取扁平样本和累计样本最多的函数。重点关注:
- 扁平时间较高的函数,它表示自身耗时。
- 累计时间较高的函数,其中包含被调用函数的耗时。
- 对运行时和标准库函数进行分析:
runtime.mallocgc表示可能存在分配压力,runtime.futex或runtime.lock表示可能存在锁争用,runtime.gcBgMarkWorker或runtime.gcDrain表示可能存在 GC 压力,而compress/gzip或compress/flate则表示可能存在压缩开销。
步骤 6:将热点函数映射到源代码
pprof -lines -top -cum 输出会以以下格式列出函数:
<flat> <flat%> <sum%> <cum> <cum%> <function-name> <source-file>:<line>
例如:
1859.03s 23.50% ... github.com/grafana/pyroscope/pkg/distributor.(*Distributor).PushBatch.func1 github.com/grafana/pyroscope/pkg/distributor/distributor.go:380
使用函数名后面的源代码路径,将性能分析帧与此代码库对应起来:
- 将所选服务的
service_repository规范化为其模块前缀:移除 URL 方案、SSH 用户名和主机分隔符,以及末尾的.git。例如,https://github.com/grafana/pyroscope.git会变为github.com/grafana/pyroscope。 - 以该模块前缀开头且不带
@version后缀的帧,很可能属于此代码库。第三方 Go 依赖通常会在其模块路径中包含@v...。 - 从代码库内部的帧中去掉模块前缀,得到相对路径。例如,
github.com/grafana/pyroscope/pkg/distributor/distributor.go:380会对应第 380 行的pkg/distributor/distributor.go。 - 如果 pprof Build ID 包含带有
git_ref的 JSON,请将其与git log --oneline -1的结果进行比较。如果两者不同,请提醒用户行号可能已过时。使用git log --oneline <git_ref>..HEAD -- <file>查看映射到的文件是否发生过更改。如果 Build ID 不含git_ref,请注明无法验证源代码是否对应。 - 阅读报告源代码行前后约 20 行的内容。根据完整限定函数名,提取相关方法或函数。
对于重要的第三方函数或运行时函数,即使无法在此代码库中查看其源代码,也要说明它们可能产生的影响。
步骤 7:交付分析结果
按以下章节提供结构化报告:
摘要
用两到三句话概述性能分析结果。
热点函数排名
提供一张排名表,列出函数名、扁平和累计样本百分比、代码库函数的源文件和行号,以及简要说明。
源代码分析
对于每个热点代码库函数,展示相关源代码片段,说明其可能成为热点的原因,并提出具体的优化方案,例如减少分配、缓存结果、使用 sync.Pool 或减少锁竞争。
建议
按预期影响从高到低列出可执行的优化建议。
错误处理
- 如果缺少
profilecli,请引导用户访问https://github.com/grafana/pyroscope/releases/latest。 - 如果发生连接错误,请检查
PROFILECLI_URL和网络访问。 - 如果发生
401或403错误,请检查PROFILECLI_TOKEN和PROFILECLI_TENANT_ID。 - 如果结果为空,请扩大时间范围,并使用
query series验证服务。 - 如果找不到服务,请列出可用服务并让用户选择一个。