如何按时间区间过滤Linux perf的perf.data文件并生成新文件?
当然可以做到!针对你的需求,我整理了几种可行的方案,从简单的自带工具用法到进阶的手动解析都有,帮你精准过滤出第二阶段的perf事件并生成新的perf.data文件:
解决方案
第一步:先搞定时间戳精度匹配
这是精准过滤的核心前提,必须先对齐时间基准和精度:
- 把你的应用改成输出CLOCK_MONOTONIC时钟的高精度时间戳(微秒或纳秒级)。perf默认用这个时钟记录事件时间,只有和应用的时间基准完全一致,才能准确匹配阶段的时间范围。
- 实现起来很简单:用
clock_gettime(CLOCK_MONOTONIC, &ts)获取时间,然后打印出ts.tv_sec + ts.tv_nsec / 1e9格式的带小数秒数,和perf输出的时间格式完全对齐。
方案一:用perf自带工具快速过滤(推荐)
perf的script和record命令配合就能完成过滤,不需要额外写代码:
1. 确定目标时间段
从你的应用输出里拿到第二阶段的起始和结束时间(比如start_ts=1690000000.123456789,end_ts=1690000010.987654321)。
2. 过滤并生成新的perf.data
执行以下命令:
# 导出所有事件,过滤出时间在目标范围内的记录 perf script | awk -v start=$start_ts -v end=$end_ts '$2 >= start && $2 <= end' > filtered_events.txt # 将过滤后的事件导入生成新的perf.data文件 perf record -i filtered_events.txt -o perf.data.loop1.stage2
处理多核事件无序的问题
如果担心多核事件未按时间排序,过滤后可以先排序再导入(其实不排序也不影响perf后续分析,工具会自动处理无序事件):
perf script | awk -v start=$start_ts -v end=$end_ts '$2 >= start && $2 <= end' | sort -k2n > filtered_sorted.txt perf record -i filtered_sorted.txt -o perf.data.loop1.stage2
方案二:进阶手动解析(适合复杂需求)
如果自带工具满足不了你的自定义逻辑,可以手动解析perf.data格式并过滤,完全遵循你提到的规范:
核心思路
perf.data由头部(header)和事件数据两部分组成:
- 头部包含时钟信息、CPU数量、事件配置等元数据,需要完整保留到新文件里,确保新文件的兼容性。
- 事件数据是一个个带时间戳的采样记录,遍历每个记录,判断时间戳是否在目标范围内,只保留符合条件的记录。
实现方式
- 用perf工具自带的libperf库来读写perf.data,避免自己手动解析二进制格式的麻烦。
- 参考perf源码(比如
perf-script.c或perf-report.c)里的事件读取逻辑,修改成“读取-过滤-写入”的流程:- 用
perf_session_open打开原始perf.data文件。 - 遍历每个事件,检查
event->time字段是否在目标时间范围内。 - 创建新的
perf_session,将符合条件的事件写入其中。 - 用
perf_session__write将新session保存为新的perf.data文件。
- 用
关键注意事项
- 时间基准必须严格一致:一定要确保应用和perf用的是同一个时钟(CLOCK_MONOTONIC),否则过滤结果会完全错误。
- 高精度时间戳是必须的:秒级精度根本无法精准定位阶段,改成微秒/纳秒级才能和perf的事件时间戳匹配。
- 系统级perf.data需要root权限:如果是用
perf record -a生成的文件,处理时需要用sudo执行命令。
内容的提问来源于stack exchange,提问作者osgx
相关产品推荐
相关产品推荐

