2g

中文文档
1.0.1发布于 2026/10/14MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 602.6万

代理商和开发商的低管理结构事件日志

中文使用文档
文档目录15 节
  1. 1个p-4,1个p-3,1个p-3,1个p-3,2个p-3,1个p-3,2个p-3,1个p-3,1个p-3,2个p-3…
  2. 执行情况
  3. 快开始
  4. 行为
  5. 激活
  6. 会议
  7. 调试事件
  8. 更改会话元数据
  9. 递延有效载荷助手
  10. 类型事件
  11. 国 际
  12. 测试
  13. API 参考
  14. 2g
  15. 2g/api

1个p-4,1个p-3,1个p-3,1个p-3,2个p-3,1个p-3,2个p-3,1个p-3,1个p-3,2个p-3,1个p-3,1个p-3,2个p-3,2个p-3,2个p-3,2个p-3,1个p-3,1个p-3,2个p-3,2个p-3,2个p-3,2个p-3,2个p-3,2个p-3,1个p-3,2个p-3,2个p-3,2个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-4,1个p-3,1个p-3,1个p-3,1个p-3,1个p-3,1个p-4,1个p-3,1个p-3,1个p-3,1个p-3,1

代理商和开发商的低管理结构事件日志

2g 是命令行工具的结构化事件日志。 它写着JSONL日志 可重放、跟踪或导出到微量格式.

总之, 2g, (中文(简体) ),

  • 保持低价伐木, 允许离开
  • 将限定的会话日志写入系统临时目录
  • 将工人和儿童进程活动提前至同一届会议
  • 允许工具和代理对运行中的命令进行挖掘
  • 通过类型Script声明合并生成类型事件有效载荷

执行情况

目标 2g 替换临时 debug 带有结构化事件的记录 总是被记录的,没有 仪器编码路径支付它。 禁用伐木 调用是单项属性检查,启用的调用会直接串行成批 文件流——没有交换格式,没有运输谈判,也没有 呼叫者已建立的有效载荷以外的活动分配.

这样做的明确目的是:

  • 文书CLI进程,培育工人和儿童进程,统一他们的活动 输入一个会话日志
  • 保持有限度的、自我清理的最近会议记录,使工具和代理人能够 发现并重放事实
  • 在不知晓或不减缓这些进程的情况下进入实时进程

因此,会话会通过单个分批的 fd 写出新线框 JSONL,旋转 通过本地插座向用户直播。 儿童 流程和工人通过通过 环境,因此整个过程树同意在一个目的地.

包裹装了两个入口 这样消费者就不会装上生产者的图表和副产品 相反:

  • 2g - 生产商表面仪器工艺进口
  • 2g/api ——读会话的工具消耗面

快开始

当 CLI 命令启动时安装一次日志, 然后在任意软件包中创建日志 :

import { installEventLogger, events } from '2g';

installEventLogger({
  command: 'expo start -p web',
  metadata: { version: '1.0.0' },
});

const log = events('metro');

log('ready', { port: 8081 });

const end = log.span();
end('bundle', { platform: 'ios', cached: false });

从另一个终端接入会话 :

2g tap "expo start" --filter metro:* --tail

行为

激活

installEventLogger 按先后顺序确定其目的地:

  1. 已安装的日志; 以后的呼叫不会更改其目的地或选项
  2. 父 2g 进程, 通过环境继承; 事件前传 父对 IPC 的日志
  3. A 类 LOG_EVENTS 环境目标 — fd 编号或文件路径
  4. 直接通过的 fd 编号或文件路径
  5. 当一个选项对象被传递时, 系统临时目录中的会话 无 session: false
  6. 否则记录会不活动,所有的通话都是不公开的

导入 2g 自动附加到继承的父日志。 如果安装 伐木机,一个后期 installEventLogger 调用不能覆盖其目的或选项.

通话 installEventLogger() 没有参数 只有在 LOG_EVENTS 或存在父母程序——儿童程序、工人和 图书馆。 通过 session: false 保留此仅包含的激活,同时仍然提供 选项。 没有未安装:每个进程安装一次并拆除 离开.

何时 LOG_EVENTS 目标 studout,, console 透明重定向到 stderr 所以 事件输出仍然可以机器读取.

会议

会话位于 event-log-<uid> 在系统临时目录中。 每个 会话目录包含旋转 JSONL 段(0.jsonl 为当前),a meta.json 描述进程,以及用于现场订阅者和儿童IPC的本地套接字。 与 默认为 3 段 × 512 KiB, 会话大致保留了最后的 12k 事件 .

断层会话通过机会性清理:退出会话在7天后被移除, 只有最新的100个退出会话才保留下来。 一个无法写入的临时目录 禁用会话抓取而不影响主机进程.

调试事件

events.debug(category) 为聊天、调试级别事件创建日志。 调试事件 携带 _l: 1 在电线上。 会话输出在发送站点丢弃它们——保存 正常历史的轮换预算——除非 LOG_DEBUG 设置或 installEventLogger 被通过 debug: true;明确的文件/fd目标默认记录它们. 明确 debug 选项在安装时优先于这些默认值. tap 财务报告和审定财务报表 export 跳过调试事件, 除非 --debug (CLI)或 (中文(简体) ) debug: true (API)通过.

在会话模式下, LOG_DEBUG 还打印匹配事件,包括转发的孩子 事件,以可读格式显示。 明确的文件/fd目标不添加此镜像, 财务报告和审定财务报表 debug: true 单枪匹马才能录制 这个 LOG_DEBUG 过滤器选择什么 打印, 不记录哪个调试事件 :

LOG_DEBUG=metro:* expo start
LOG_DEBUG=* expo export

更改会话元数据

声明您期望的应用程序元数据, 然后在安装时或作为 数值变为已知 :

import { installEventLogger, updateEventLoggerMetadata } from '2g';

declare module '2g' {
  interface MetadataRegistry {
    port: number;
    ready: boolean;
    devServerUrl: string | null;
  }
}

installEventLogger({ metadata: { version: '1.0.0', ready: false } });
updateEventLoggerMetadata({
  port: 8081,
  devServerUrl: 'http://localhost:8081',
});
updateEventLoggerMetadata({ ready: true });

两个调用都接受部分,JSON相容的元数据. 更新简单合并 : 提供的密钥替换以前的值,包括嵌入对象和阵列. 顶级 undefined 值被忽略,使已存在的值保持不变.

初始值喷出 root:init; 后期补丁弹出 root:updateB. 届会持续存在 它们自己的元数据在 meta.json,可见于 ps 财务报告和审定财务报表 list(). 儿童最新情况 不更改父的元数据。 从顶级元数据密钥开始 _ 在保存时被省略.

元数据序列化在保留时省略了循环引用和 BigInt 值 有效的字段( 被允许的数组元素变为 null) (中文(简体) ).

使用 metadata.version 用于应用程序版本。 会议 meta.json 存储 format: 'v0-jsonl' 与应用程序元数据分开.

递延有效载荷助手

log.path(absolutePath) 日志路径相对于工作目录,以及 log.error(error) 序列化错误为 { name, message, code, stack, cause }两者 返回时 Serialized<T> 那些只写着一件事情的包装, 因此禁用日志跳过 path.relative 电话和 error.stack 完全实现. 接受有效载荷 Serialized<T> 无论他们申报的类型在哪里 T, (中文(简体) ), 这样 EventRegistry 声明继续使用线形.

类型事件

扩展 EventRegistry 键; 键为 category:kind 和有效载荷 通过声明合并实现软件包的合并 :

declare module '2g' {
  interface EventRegistry {
    'metro:ready': { port: number };
    'metro:bundle': { platform?: string; cached?: boolean };
  }
}

未知的事件名称不可调用, 保留有线字段( Q)_e, (中文(简体) ), _t, (中文(简体) ), _d, (中文(简体) ), _l, (中文(简体) ), _w(中文(简体) ) 在有效载荷类型中被拒绝,没有所需密钥的有效载荷成为可选的 参数. 2g typegen 将整个项目的登记声明合并为 一个计划.

类别和事件名称必须是非空的 ASCII 标识器,只使用字母, 数字, _, (中文(简体) ), -, (中文(简体) ), .,以及 :。类型脚本检查文稿; typegen 登记的支票 名称。 动态字符串、 JavaScript 调用器和类型断言必须遵循 同一惯例:伐木不会在运行时验证或逃避名称。 设置动态 文本在有效载荷中.

国 际

使用 CLI 查找会话、 重放日志或导出痕迹 :

2g ps --json
2g tap "expo start" --filter metro:* --tail
2g export "expo start" --format chrome-trace -o trace.json
2g export "expo start" --format opentelemetry -o otel.json
2g typegen --project tsconfig.json --format dts
2g clean --json

选择者匹配由 PID,命令,会话目录,或工作目录组成的会话. --filter 模式是整个片段匹配的事件名前缀 - metro:bundling 匹配 metro:bundling 财务报告和审定财务报表 metro:bundling:started,但不会 metro:bundling2 ——和a * 搭配任何东西,甚至跨段. tap 财务报告和审定财务报表 export 重放保留历史 先说. --tail 附加活事件; 即时写入的事件 --tail 附加 可能两次出现在接合处.

打开 Chrome 痕迹 (原始内容存档于2013-10-12). ui.perfetto.dev 或者通过克罗姆·德夫图尔(Chrome DevTools) 性能 − “Load profile”(作为平面火焰图提交); chrome://tracing 实值 堕地. 对于运行命令的近效视图, 尾随导出 :

2g export "expo start" --tail -o trace.json

测试

在集成测试中将一个子进程的事件通过将一个管子作为它的 LOG_EVENTS 目标 :

import { spawn } from 'node:child_process';
import { captureEvents } from '2g/api';

const capture = captureEvents({ filter: 'metro:*' });
const child = spawn(
  'expo',
  ['export'],
  capture.spawnOptions({ env: process.env })
);

const events = await capture.attach(child).collect();

spawnOptions 将管子附加到 stdio 和点 LOG_EVENTS at; attach 消耗管子和剖析事件, 也可以用 for await 为活人服务 消费。 当管子关上时,迭接结束, 所以每个事件孩子写 已经收到.

[大 这孩子的活动被冲出自然出口 呼叫的儿童代码 process.exit() 应 await flushEventLogger() 首先或后续事件可能会丢失.

API 参考

2g

由仪器加工过程导入的生产者条目.

events(category: string) => EventLogger

返回输入的日志 category。日志可以直接调用并携带 帮助者 :

  • log(event, data?): 写出 category:event 与有效载荷相对应
  • log.span(): 开始一个跨度;返回一个 end(event, data?) 写单曲的函数 持续时间为 _d (将事件命名为 :done编号 ::failed (在结尾)
  • log.path(target): 返回 a Serialized<string> 路径相对于工作 目录。 一个远远超出目录的目标 一个已经相对的目标, 保持不变
  • log.error(error): 返回 a Serialized<SerializedError> 联 合 国 { name, message, code, stack, cause },有因子链连续递归
  • log.category: 类别字符串

结束于 :started, (中文(简体) ), :done,或 :failed 是命名公约; 跟踪 导出从显示的名称中去除后缀 .

events.debug(category: string) => EventLogger

页:1 events(category),但事件为调试级别(_l: 1)并须遵守 调试取笑.

installEventLogger(target?: string | number | InstallEventLoggerOptions) => void

  • 接受一个明确的目标(fd 数字或文件路径)或选项对象

安装上方启动优先进程后的日志 。 所有选项 可选 :

选项默认说明
command参数v在会话元数据中记录的命令行
metadata{}初始应用程序元数据,包括可选 version,记录在会话和活动中
maxSegments3每届会议保留轮流的 JSONL 部分
maxSegmentSize512 基贝触发旋转的片段大小
sessiontrue允许届会倒闭; false 保持仅嵌入激活
debug变化记录调试事件;默认为 true 明确目标 LOG_DEBUG 显示会话和 IPC 输出

flushEventLogger() => Promise<void>

排水管缓冲事件到活动目的地. 立即决定何时伐木 不活动.

getEventLoggerInfo() => EventLoggerInfo | null

返回活动目的地 - { destination, isUserVisibleOutput, debug } 加一个 file, (中文(简体) ), fd,或 sessionDir -或者说 null 当日志不活动时. isUserVisibleOutput 实值 true 当事件写入 stdout 或 stderr 时.

interface Serialized<T>

interface Serialized<T> {
  toJSON(): T;
}

序列化为 T 当一个事件被记录的时候。 接受有效载荷类型 Serialized<T> 地点 T 被宣布,所以用户代码可以推迟自己的昂贵 价值相同.

2g/api

读取会话的工具的消耗项 .

list(options?: ListSessionsOptions) => Promise<ListedSession[]>

  • 参数
    • selector?: 由 PID、 命令、 会话目录或工作目录匹配

返回已知会话, 首先是最新的会话 。 每个 ListedSession 携带 pid, (中文(简体) ), command, (中文(简体) ), cwd, (中文(简体) ), startedAt, (中文(简体) ), alive,以及 sessionDir。 。 。 .

resolveSession(selector?: string) => Promise<ListedSession>

确定一个选取者精确到一个会话, 更喜欢唯一的活匹配 。 掷出何时 没有匹配或选择者是模糊的.

tap(sessionDir: string, options?: TapOptions) => AsyncIterable<ParsedEvent>

重放会话保留的历史,可选地跟随现场活动.

选项默认说明
since—— 说从一个期间重放( R)'5m',Unix时间、ISO日期,或 Date
followfalse重播历史后跟踪现场事件
filter—— 说事件名前缀(整段); * 通配符, 逗号分隔
spansfalse只产生持续时间跨度的事件
debugfalse包含调试级别事件
signal—— 说AbortSignal 停止跟踪
timeout—— 说绝对持续时间以毫秒后停止跟踪
idleTimeout—— 说这么多毫秒之后, 不再跟踪, 没有新事件

captureEvents(options?: CaptureOptions) => EventCapture

  • 参数
    • filter? 财务报告和审定财务报表 debug?: 如 TapOptions

返回 a EventCapture 用于接收子进程在继承管道上的事件:

  • capture.spawnOptions(options?): 返回带有 a 的产卵选项 'pipe' 附加槽 改为 stdio 财务报告和审定财务报表 LOG_EVENTS 指着它, 保存打电话者 env 财务报告和审定财务报表 stdio
  • capture.attach(child):消耗了孩子的管;俘虏是一种 AsyncIterable<ParsedEvent> 当管道关闭时结束
  • capture.collect(): 移动到尾端并返回所有事件

interface ParsedEvent

解析出JSONL事件的线条格式;所有其他属性都是有效载荷场.

interface ParsedEvent {
  _e: string; // "category:kind"
  _t: number; // wall-clock timestamp in milliseconds
  _d?: number; // span duration in milliseconds
  _l?: number; // level; 1 marks debug events
  _w?: string; // originating worker or child process
}

版本与发布记录

2g 共发布 56 个版本,首次发布于 2019/06/17;过去 12 个月发布了 54 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.1latest2026/10/1424 天前
1.0.1-canary-a8e5e77b349c861b08a21f4ed18af6b79ce3b1ffcanary2026/10/1424 天前
1.0.02026/10/1029 天前
1.0.0-canary-1972abe8ed7ab8dce53894c578a26756c8a19fd42026/10/1029 天前
1.0.0-canary-c70584fd9d8b33c36a61916a2dd5db627f52ffd42026/10/1029 天前
1.0.0-canary-c6d52b937a30b3dae167f40b6820ba3e843292872026/10/1029 天前

关于 2g 的常见问题

2g 是什么?

代理商和开发商的低管理结构事件日志

如何安装 2g?

在项目目录运行 npm install 2g,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 2g,可以用 npx 2g 直接运行。

2g 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

2g 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

2g 可以商用吗?

2g 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

2g 的下载量有多少?

根据 npm 官方下载统计,2g 在 2026/10/04 – 2026/11/02 这 30 天内被下载 6,025,630 次,日均约 200,854 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

2g 还在维护吗?

最新版本 1.0.1 发布于 2026/10/14(24 天前);至今共发布 56 个版本,其中过去 12 个月发布了 54 个;首次发布于 2019/06/17。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。