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 按先后顺序确定其目的地:
- 已安装的日志; 以后的呼叫不会更改其目的地或选项
- 父 2g 进程, 通过环境继承; 事件前传 父对 IPC 的日志
- A 类
LOG_EVENTS环境目标 — fd 编号或文件路径 - 直接通过的 fd 编号或文件路径
- 当一个选项对象被传递时, 系统临时目录中的会话
无
session: false - 否则记录会不活动,所有的通话都是不公开的
导入 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): 返回 aSerialized<string>路径相对于工作 目录。 一个远远超出目录的目标 一个已经相对的目标, 保持不变log.error(error): 返回 aSerialized<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,记录在会话和活动中 |
maxSegments | 3 | 每届会议保留轮流的 JSONL 部分 |
maxSegmentSize | 512 基贝 | 触发旋转的片段大小 |
session | true | 允许届会倒闭; 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 |
follow | false | 重播历史后跟踪现场事件 |
filter | —— 说 | 事件名前缀(整段); * 通配符, 逗号分隔 |
spans | false | 只产生持续时间跨度的事件 |
debug | false | 包含调试级别事件 |
signal | —— 说 | AbortSignal 停止跟踪 |
timeout | —— 说 | 绝对持续时间以毫秒后停止跟踪 |
idleTimeout | —— 说 | 这么多毫秒之后, 不再跟踪, 没有新事件 |
captureEvents(options?: CaptureOptions) => EventCapture
- 参数
filter?财务报告和审定财务报表debug?: 如TapOptions
返回 a EventCapture 用于接收子进程在继承管道上的事件:
capture.spawnOptions(options?): 返回带有 a 的产卵选项'pipe'附加槽 改为stdio财务报告和审定财务报表LOG_EVENTS指着它, 保存打电话者env财务报告和审定财务报表stdiocapture.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
}