npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hmtrace-parser

v0.12.2

Published

Kernel trace format helpers (checkpoint_revoked, perf trace text blocks)

Readme

hmtrace-parser

内核 trace 相关辅助:为 hiperf_txt_parser 提供 RLS 版本内核事件的 perf trace 文本格式块(format: / print fmt:),以及对 checkpoint_revoked 事件中 revoke_reason 的解析与展开;另含 hitrace ftrace 文本 与 raw .sys 二进制 的解析、按 tgid 过滤、导出回 txt、fieldDict 解码、VFS 操作码可读化(op_flag_readable / reason_readable)、FFRT gid 聚合(tracing_mark_write / I13),以及供 hiperf 侧车合并使用的 hitrace 线程索引快照 构建。

依赖分层:本库直接依赖 hm-pt-core(≥ 2.0.0)获取 TraceParserRegistry、RecordSample、HitraceThreadIndexSnapshot 等公共类型与 trace format 解码原语;不再依赖 hiperf。解析 perf 文本、批量 raw 解码与 hitrace 侧车合并仍由 hiperf(≥ 2.1.0)提供,由调用方(如 snapshot_checker)自行组合。本库仅导出 trace 机制层、profile 策略层、hitrace 预处理与领域工具,不 re-export hm-pt-core 或 hiperf 已有符号。

源码按职责分层:

| 层 | 路径 | 职责 | |----|------|------| | trace(机制) | src/lib/trace/ | 接收 TraceEventFormat[],构建 TraceParserRegistry | | profile(策略) | src/lib/profile/ | RLS format 块、字段变换、getTraceEventFormats、op_flag 可读化 | | profile(续) | cp_revoked.ts、backtrack.ts | revoke_reason 解析、backtrack 配对策略 | | hitrace | src/lib/hitrace/ | ftrace 文本行解析、raw .sys 二进制解析、按 tgid 过滤、导出 txt、按 event name 解码 function 为 fieldDict、由 PerfData 合成 hitrace(buildHitraceDataFromPerf)、构建线程索引快照 |

  • Node.js ≥ 18
  • ESM("type": "module")

安装

npm install hmtrace-parser

与 hiperf 组合解码 perf 文本时,另装 hiperf_txt_parser@^2.1.0(及 hiperf 自带的 hm-pt-core 传递依赖)。

用法概览

主入口 hmtrace-parser

当前包仅发布主入口(exports["."]),聚合 trace、profile、hitrace、logger 各层导出:

import {
  parsePerfData,
  decodePerfRawData,
  type HitraceSidecarOptions,
} from "hiperf_txt_parser";
import {
  setHmtraceLogger,
  type TraceEventFormat,
  type TraceRegistryOptions,
  buildTraceRegistry,
  getTraceEventFormats,
  getTraceEventFormatProfiles,
  buildTraceRegistryFromProfile,
  expandCheckpointRevokedFieldDict,
  passthroughFieldDict,
  applyOpFlagReadableFields,
  parseOpFlagMask,
  opFlagMaskToReadable,
  VFS_OP_FLAG_BITS,
  backtrackFS,
  backtrackStrategyRls,
  resolveBacktrackStrategy,
  buildHitraceIndexSnapshot,
  buildHitraceDataFromPerf,
  decodeHitraceFunctions,
  hiperfEventNameFromSampleType,
  mapTraceFormatNameToHitraceFunctionName,
  buildHitracePidTaskMap,
  resolvePerfSampleTaskName,
  parseHitraceText,
  parseHitraceFile,
  parseHitraceRawSysBuffer,
  parseHitraceRawSysFile,
  formatHitraceRecordLine,
  saveHitraceDataToTxt,
  filterHitraceByTgid,
  filterHitraceRecordsByTgid,
  type HitraceData,
  type HitraceRecord,
} from "hmtrace-parser";

由 decoded PerfData 合成 HitraceData

buildHitraceDataFromPerf 仅依赖 hm-pt-core 的 PerfData(不依赖 hiperf_txt_parser)。映射约定与 timeline.ts 一致:sample.pid→tgid、sample.tid→pid;无任务名时 task 默认用 String(tid)。可选传入 pidTaskMap(或自定义 resolveTask):由 buildHitracePidTaskMap 自采集 hitrace 文本构建 hitrace.pid → task,用于丰富合成行任务名(monitor 阶段通常 pid 不重复;重复时保留首次)。

严格转换规则(任一条样本不满足即抛错):

  1. 每条样本必须有非空 traceFieldDict
  2. function.name ← traceEventName(format name);print 映射为 tracing_mark_write(与 raw .sys 解析同一归一化)
  3. function.content ← tracePrintContent(print 模式渲染文本)
  4. function.fieldDict ← traceFieldDict 拷贝

合成后可再走 decodeHitraceFunctions(预填充 fieldDict 时跳过 content 反解析,仍应用 transform)。

perf raw 解码(调用方组合)

本库提供 format 块与 registry 构建;解析 perf 文本与批量 raw 解码由 hiperf 完成。省略 profile 名时等价于 default / rls:

import { parsePerfData, decodePerfRawData } from "hiperf_txt_parser";
import {
  getTraceEventFormats,
  buildTraceRegistryFromProfile,
} from "hmtrace-parser";

const formats = getTraceEventFormats();
const registry = buildTraceRegistryFromProfile(undefined, {
  readable: true, // 默认 true:追加 op_flag_readable / reason_readable
});
const perfData = parsePerfData(text);

const decoded = await decodePerfRawData(perfData, registry, {
  tracePrintMode: "fieldDict",
});

hitrace 与 perf 合并(hiperf ≥ 2.1.0)

hiperf 1.4.2 起,decodePerfRawData 支持 options.hitrace 侧车:传入预处理后的 HitraceThreadIndexSnapshot 与合并策略(fallback / overlay / off)。快照由本库 buildHitraceIndexSnapshot 构建:

import {
  parsePerfData,
  decodePerfRawData,
  type HitraceSidecarOptions,
} from "hiperf_txt_parser";
import {
  getTraceEventFormats,
  buildTraceRegistryFromProfile,
  buildHitraceIndexSnapshot,
} from "hmtrace-parser";

const formats = getTraceEventFormats();

const hitraceIndex = await buildHitraceIndexSnapshot(
  { filePath: "samples/bug.hitrace" },
  formats,
  {
    tracePrintMode: "fieldDict",
    readable: true, // 默认 true
  },
);

const hitrace: HitraceSidecarOptions = {
  index: hitraceIndex,
  strategy: "fallback",
};

const perfData = parsePerfData(perfText);
const decoded = await decodePerfRawData(perfData, registry, {
  tracePrintMode: "fieldDict",
  hitrace,
});

buildHitraceIndexSnapshot 入参支持 { filePath, encoding?, highWaterMark? } 或已解析的 { data: HitraceData }(filePath 在内部通过流式 parseHitraceFile 读取)。快照仅含 timestampNs、functionName、fieldDict(由 ftrace content 反解析,不合成 perf raw 字节);合并侧车时由消费方(如 snapshot_checker)写 traceFieldDict 并将 sample raw.size 置 0。options 默认剔除 function name 不在 formats 中的行;includeUnknownEvents: true 可保留未登记事件(空 fieldDict)。快照键为 ${tgid}:${pid}(hitrace 语义),与 hiperf RecordSample 的 pid(进程)/ tid(线程)对齐。

Logger

| 导出 | 说明 | |------|------| | setHmtraceLogger | 注入 trace / debug / info / error 日志实现;未调用时相关模块日志为 no-op |

Profile 策略层(RLS)

内置 RLS trace 事件格式(TraceEventFormat:text + 可选 transformFieldDict)。default 与 rls 为同一套定义的别名;未知 profile 名回退至该定义。

| 导出 | 说明 | |------|------| | getTraceEventFormats(profile?) | 取 RLS 格式列表(浅拷贝) | | getTraceEventFormatProfiles() | 返回 ["default", "rls"] | | buildTraceRegistryFromProfile(profile?, options?) | 构建 TraceParserRegistry | | expandCheckpointRevokedFieldDict / passthroughFieldDict | 字段字典变换 | | applyOpFlagReadableFields / parseOpFlagMask / parseOpFlagMaskHex / opFlagMaskToReadable | VFS 操作码映射与可读化 | | VFS_OP_FLAG_BITS | 硬编码 bit → 名称表(与 samples/op_flag.md 一致) |

当前事件(RLS):

| 事件 | ID | 说明 | |------|-----|------| | vfs_snapshot_dump_monitor | 33220 | 含 name、revoke_id、op_flag;hitrace content 为空格分隔 key=value | | checkpoint_revoked | 32945 | 含 checkpoint_monitor_id、type、revoke_reason;FS(type=0)时展开 revoke_reason kv | | tracing_mark_write | 298 | 含 buffer(ftrace content 整段字符串);解码时展开 mark_type、trace_tag、is_ffrt 等;I13 为 FFRT 生命周期事件,进一步解析 ffrt_event、gid、label。raw .sys 内 format 名可能为 print,解析后归一化为此名 |

FFRT gid 聚合

采集时需打开 ffrt tag(tracing_mark_write 中 I13)。FFRT worker 线程名通常以 OS_FFRT 为前缀。raw .sys 中该事件 format 名可能为 print,解析后已归一化为 tracing_mark_write,可直接用于 gid 聚合。

| 导出 | 说明 | |------|------| | parseTracingMarkWriteContent(buffer) | 解析 tracing_mark_write buffer 字符串为结构化字段 | | aggregateFfrtByGid(data, formats, options?) | 解码后按 tgid + gid 聚合生命周期事件与 exec 片段内伴生事件 | | aggregateFfrtByGidFromRecords(records, options?) | 对已解码记录聚合(不再解码) | | FfrtGidAggregate | 含 lifecycleRecords、execSlices、companionRecords、anomalies |

companionRecords 仅包含各 exec 片段 [exec_begin, exec_end] 时间窗内、运行于 OS_FFRT* 线程上的非生命周期记录;可通过 includeEventNames / excludeEventNames 按 function.name 过滤。

import {
  parseHitraceText,
  getTraceEventFormats,
  aggregateFfrtByGid,
} from "hmtrace-parser";

const data = parseHitraceText(ffrtTraceText);
const aggregates = aggregateFfrtByGid(data, getTraceEventFormats(), {
  tgid: 1000,
  gid: 17,
  includeEventNames: ["sched_switch", "cpu_frequency"],
});

for (const agg of aggregates) {
  console.log(agg.gid, agg.execSlices, agg.companionRecords.length);
}

VFS 操作码可读化(readable)

映射表见 samples/op_flag.md(WRITE、MMAP、…、SPLICE_WRITE,bit 0–13)。解码时在保留原字段前提下追加:

| 事件 | 原字段 | 可读字段 | 条件 | |------|--------|----------|------| | vfs_snapshot_dump_monitor | op_flag | op_flag_readable | 掩码可解析 | | checkpoint_revoked(type=0) | reason | reason_readable | revoke_reason 已展开且 kv 中含 reason:<op_flag>(%x 十六进制) |

规则摘要:

  • 多 bit 以 | 连接(如 WRITE|ACCESS)
  • 含未知 bit 时打 error 日志,不写入 readable 字段
  • readable: false 时不追加可读字段(适用于 buildTraceRegistry、buildTraceRegistryFromProfile、decodeHitraceFunctions、buildHitraceIndexSnapshot)

说明:checkpoint_revoked 展开后的 reason 与 vfs_snapshot_dump_monitor 的 op_flag 均按内核 %x / %lx 十六进制解析(如 20 → 0x20 → ACCESS,40 → 0x40 → FACCESS)。content/raw 反解析若已在 rawFieldMap 中给出数值,则优先用该数值计算 readable,避免十进制 stringify(如 32)被误当作 hex。

示例(type=0):

revoke_reason = "devid:9, fs:ab, index:1, reason:20"
  → 展开后 reason="20", reason_readable="ACCESS"   (0x20 = ACCESS)

Trace 机制层

| 导出 | 说明 | |------|------| | buildTraceRegistry(formats, options?) | 由 TraceEventFormat[] 构建 TraceParserRegistry;默认包装可读化 transform |

hitrace 与 perf raw 共用同一 registry:transform 先执行 profile 逻辑(如展开 revoke_reason),再追加 *_readable 字段。

Hitrace 层

解析

| 导出 | 说明 | |------|------| | parseHitraceText(text) | 解析整段 ftrace 文本为 HitraceData | | parseHitraceFile(filePath, options?) | 流式解析 hitrace 文件为 HitraceData(options: encoding?、highWaterMark?) | | ParseHitraceFileOptions | parseHitraceFile 选项类型 | | parseHitraceRawSysBuffer(buf) | 解析 hitrace raw .sys 二进制缓冲,解码为 HitraceData(含内嵌 format) | | parseHitraceRawSysFile(filePath) | 读取并解析 .sys 文件 | | HitraceRawSysParseResult | { formats, data, cmdlines, tgids } | | HitraceData | 聚合类型,{ records: HitraceRecord[] } | | HitraceRecord | 单条 ftrace 数据行:task、pid(线程 tid)、tgid(进程 pid)、cpu、flags、timestamp(秒)、function |

ftrace 数据行形态:TASK-PID (TGID) [CPU] FLAGS TIMESTAMP: function: content。解析时跳过空行、# 注释与 tracer: 行;不保留文件头元数据。

parseHitraceText 逐行调用 parseHitraceLine,产出 HitraceRecord 列表(此阶段 function.fieldDict 尚未填充)。大文件请用 parseHitraceFile 流式读取,避免整文件载入单个 string。

.sys 为 hitrace raw 二进制。布局要点:

  • 文件头 12B(HBHI native alignment)
  • 随后按 segment 存放 events format、cmdlines、tgids 与各 CPU 的 raw page(每段 8B 头:type u32 + size u32)
  • 每个 raw page 固定 4096B;page 头为真机实测 17B(QQB = timestamp u64 + length u64 + core_id u8),事件流从偏移 17 开始

parseHitraceRawSysBuffer / parseHitraceRawSysFile 用文件内 format 解码事件,产出与文本链路对齐的 HitraceData(timestamp 为秒,flags 由 common_flags 渲染);记录按时间排序。同一 .sys 内允许重复声明相同 event ID。

事件名归一化:真机 .sys 中 FFRT 等用户态标记的 format 名为 print(ftrace 事件),解析时归一化为 tracing_mark_write(与 text / hiperf 链路一致,常量 HITRACE_PRINT_FUNCTION_NAME)。否则无法绑定 expandTracingMarkWriteFieldDict,fieldDict 不会展开 is_ffrt / ffrt_event / gid,aggregateFfrtByGid 也会跳过这些记录。

import {
  parseHitraceRawSysFile,
  aggregateFfrtByGid,
} from "hmtrace-parser";

const { formats, data } = parseHitraceRawSysFile("trace.sys");
// data.records[].function.name 已将 print 归一化为 tracing_mark_write
const aggregates = aggregateFfrtByGid(data, formats);

过滤

面向解析结果中的 HitraceRecord,按 tgid(进程组 / 进程 pid)或 function.name 筛选:

| 导出 | 说明 | |------|------| | filterHitraceRecordsByTgid(records, tgid) | 过滤 HitraceRecord[],保留 record.tgid === tgid | | filterHitraceByTgid(data, tgid) | 同上,入参/出参为 HitraceData | | filterHitraceRecordsByFunctionName(records, filter) | 按事件名过滤 record 列表(见下 HitraceFunctionNameFilter) | | filterHitraceByFunctionName(data, filter) | 同上,包装为 HitraceData | | filterHitraceRecordsExcludingFunctionName(records, name) | 按事件名黑名单排除(name 为 string 或 string[]) | | filterHitraceExcludingFunctionName(data, name) | 同上,包装为 HitraceData | | HitraceFunctionNameFilter | 过滤条件:string(单事件白名单)、string[](多事件白名单;空数组表示不匹配任何行)、{ include?, exclude? }(白名单与黑名单可组合,include / exclude 均为 string 或 string[]) |

导出

将 HitraceRecord / HitraceData 写回 ftrace 数据行 txt 文件(不含 tracer: 与注释头)。使用 saveHitraceDataToTxt 逐行流式写入,避免将全部内容拼接为单个 string(受 V8 max string 长度限制):

| 导出 | 说明 | |------|------| | formatHitraceRecordLine(record) | 单条记录 → 一行 ftrace 文本(不含行尾换行) | | saveHitraceDataToTxt(filePath, data, options?) | 逐行写入文件;默认 \n 分隔且末行后追加换行 | | SaveHitraceDataToTxtOptions | lineEnding、trailingLineEnding、encoding |

写入后可通过 parseHitraceFile / parseHitraceText 再次解析,字段语义与导出前一致(往返测试已覆盖)。function.content 为空时,导出行在事件名后不追加 :。

典型流程:解析 → 按 tgid 过滤 → 写入文件:

import {
  parseHitraceText,
  filterHitraceRecordsByTgid,
  saveHitraceDataToTxt,
} from "hmtrace-parser";

const data = parseHitraceText(hitraceText);
const records = filterHitraceRecordsByTgid(data.records, 952);
await saveHitraceDataToTxt("out.hitrace", { records });

解码与侧车快照

| 导出 | 说明 | |------|------| | buildHitraceIndexSnapshot(input, formats, options?) | 解析 + 解码 + 线程分桶,产出 HitraceThreadIndexSnapshot |

低层工具(如 decodeHitraceFunctions、buildHitraceThreadIndex、registryByEventName)仍存在于 src/lib/hitrace/,供本库内部与测试使用,未从主入口导出。FFRT 聚合见上文 FFRT gid 聚合 小节。

Backtrack

在已解码、且 traceFieldDict 已填充的 RecordSample 上做 backtrack 配对。默认按 revoke_id 配对:vfs_snapshot_dump_monitor(backtrack op)与 FS checkpoint_revoked(invalid op)。

历史 devid + fs + index 配对须显式传入 backtrackStrategy: backtrackStrategyDefault(未从主入口导出,测试/internal 使用)。

| 导出 | 说明 | |------|------| | backtrackFS(perfData \| samples, options?) | 返回 BacktrackResult:[recordSamples, map] | | backtrackStrategyRls | 默认 revoke_id 配对策略 | | resolveBacktrackStrategy(profile?) | 解析策略(当前恒为 RLS) |

开发

npm install
npm run build   # 输出到 dist/
npm test        # 单元测试
npm run test:all  # 单元测试 + perf 测试

许可证

MIT