Skip to content

追踪事件

[稳定版: 1 - 实验性]

稳定版: 1 稳定性: 1 - 实验性

源代码: lib/trace_events.js

node:trace_events 模块提供了一种机制,用于集中处理由 V8、Node.js 核心和用户空间代码生成的追踪信息。

可以使用 --trace-event-categories 命令行标志或 node:trace_events 模块启用追踪。--trace-event-categories 标志接受以逗号分隔的类别名称列表。

可用的类别包括:

  • node: 一个空的占位符。

  • node.async_hooks: 启用捕获详细的 async_hooks 追踪数据。async_hooks 事件具有唯一的 asyncId 和特殊的 triggerId triggerAsyncId 属性。

  • node.bootstrap: 启用捕获 Node.js 引导里程碑。

  • node.console: 启用捕获 console.time()console.count() 输出。

  • node.threadpoolwork.sync: 启用捕获线程池同步操作的追踪数据,例如 blobzlibcryptonode_api

  • node.threadpoolwork.async: 启用捕获线程池异步操作的追踪数据,例如 blobzlibcryptonode_api

  • node.dns.native: 启用捕获 DNS 查询的追踪数据。

  • node.net.native: 启用捕获网络的追踪数据。

  • node.environment: 启用捕获 Node.js 环境里程碑。

  • node.fs.sync: 启用捕获文件系统同步方法的追踪数据。

  • node.fs_dir.sync: 启用捕获文件系统同步目录方法的追踪数据。

  • node.fs.async: 启用捕获文件系统异步方法的追踪数据。

  • node.fs_dir.async: 启用捕获文件系统异步目录方法的追踪数据。

  • node.perf: 启用捕获 性能 API 测量数据。

    • node.perf.usertiming: 启用仅捕获性能 API 用户计时测量和标记。
    • node.perf.timerify: 启用仅捕获性能 API timerify 测量数据。
  • node.promises.rejections: 启用捕获追踪数据,跟踪未处理的 Promise 拒绝和处理后的拒绝数量。

  • node.vm.script: 启用捕获 node:vm 模块的 runInNewContext()runInContext()runInThisContext() 方法的追踪数据。

  • v8: V8 事件与 GC、编译和执行相关。

  • node.http: 启用捕获 http 请求/响应的追踪数据。

  • node.module_timer: 启用捕获 CJS 模块加载的追踪数据。

默认情况下,启用 nodenode.async_hooksv8 类别。

bash
node --trace-event-categories v8,node,node.async_hooks server.js

早期版本的 Node.js 需要使用 --trace-events-enabled 标志来启用追踪事件。此要求已被移除。但是,--trace-events-enabled 标志可能仍然可以使用,并且将默认启用 nodenode.async_hooksv8 追踪事件类别。

bash
node --trace-events-enabled

# 等同于 {#is-equivalent-to}

node --trace-event-categories v8,node,node.async_hooks

或者,可以使用 node:trace_events 模块启用追踪事件:

js
const trace_events = require('node:trace_events')
const tracing = trace_events.createTracing({ categories: ['node.perf'] })
tracing.enable() // 为 'node.perf' 类别启用追踪事件捕获

// 执行工作

tracing.disable() // 为 'node.perf' 类别禁用追踪事件捕获

使用启用追踪的 Node.js 运行将生成可在 Chrome 的 chrome://tracing 选项卡中打开的日志文件。

日志文件默认名为 node_trace.${rotation}.log,其中 ${rotation} 是递增的日志轮转 ID。可以使用 --trace-event-file-pattern 指定文件路径模式,该模式接受支持 ${rotation}${pid} 的模板字符串:

bash
node --trace-event-categories v8 --trace-event-file-pattern '${pid}-${rotation}.log' server.js

为了保证在 SIGINTSIGTERMSIGBREAK 等信号事件后正确生成日志文件,请确保在代码中具有适当的处理程序,例如:

js
process.on('SIGINT', function onSigint() {
  console.info('Received SIGINT.')
  process.exit(130) // 或根据操作系统和信号适用的退出代码
})

追踪系统使用与 process.hrtime() 使用的相同的时间源。但是,追踪事件时间戳以微秒表示,而 process.hrtime() 返回纳秒。

此模块的功能在 Worker 线程中不可用。

node:trace_events 模块

新增于:v10.0.0

Tracing 对象

新增于:v10.0.0

Tracing 对象用于启用或禁用特定类别范围的跟踪。实例使用 trace_events.createTracing() 方法创建。

创建时,Tracing 对象处于禁用状态。调用 tracing.enable() 方法会将这些类别添加到已启用的跟踪事件类别集合中。调用 tracing.disable() 方法会将这些类别从已启用的跟踪事件类别集合中移除。

tracing.categories

新增于:v10.0.0

Tracing 对象涵盖的跟踪事件类别的逗号分隔列表。

tracing.disable()

新增于:v10.0.0

禁用此 Tracing 对象。

只有被其他已启用的 Tracing 对象涵盖且--trace-event-categories 标志指定的跟踪事件类别将被禁用。

js
const trace_events = require('node:trace_events')
const t1 = trace_events.createTracing({ categories: ['node', 'v8'] })
const t2 = trace_events.createTracing({ categories: ['node.perf', 'node'] })
t1.enable()
t2.enable()

// 打印 'node,node.perf,v8'
console.log(trace_events.getEnabledCategories())

t2.disable() // 只会禁用 'node.perf' 类别的发射

// 打印 'node,v8'
console.log(trace_events.getEnabledCategories())

tracing.enable()

新增于:v10.0.0

启用此 Tracing 对象,涵盖 Tracing 对象包含的类别集。

tracing.enabled

新增于:v10.0.0

  • <布尔值> 仅当 Tracing 对象已启用时为 true

trace_events.createTracing(options)

新增于:v10.0.0

  • options <对象>

    • categories <字符串数组> 跟踪类别名称的数组。数组中包含的值在可能的情况下会被强制转换为字符串。如果值无法强制转换,则会抛出错误。
  • 返回值:<Tracing>

为给定的 categories 集创建并返回一个 Tracing 对象。

js
const trace_events = require('node:trace_events')
const categories = ['node.perf', 'node.async_hooks']
const tracing = trace_events.createTracing({ categories })
tracing.enable()
// 执行操作
tracing.disable()

trace_events.getEnabledCategories()

新增于:v10.0.0

返回所有当前启用的追踪事件类别的逗号分隔列表。当前启用的追踪事件类别集合由所有当前启用的 Tracing 对象和使用 --trace-event-categories 标志启用的任何类别组成的 并集 决定。

给定下面的 test.js 文件,命令 node --trace-event-categories node.perf test.js 将打印 'node.async_hooks,node.perf' 到控制台。

js
const trace_events = require('node:trace_events')
const t1 = trace_events.createTracing({ categories: ['node.async_hooks'] })
const t2 = trace_events.createTracing({ categories: ['node.perf'] })
const t3 = trace_events.createTracing({ categories: ['v8'] })

t1.enable()
t2.enable()

console.log(trace_events.getEnabledCategories())

示例

通过 inspector 收集追踪事件数据

js
'use strict'

const { Session } = require('node:inspector')
const session = new Session()
session.connect()

function post(message, data) {
  return new Promise((resolve, reject) => {
    session.post(message, data, (err, result) => {
      if (err) reject(new Error(JSON.stringify(err)))
      else resolve(result)
    })
  })
}

async function collect() {
  const data = []
  session.on('NodeTracing.dataCollected', chunk => data.push(chunk))
  session.on('NodeTracing.tracingComplete', () => {
    // done
  })
  const traceConfig = { includedCategories: ['v8'] }
  await post('NodeTracing.start', { traceConfig })
  // do something
  setTimeout(() => {
    post('NodeTracing.stop').then(() => {
      session.disconnect()
      console.log(data)
    })
  }, 1000)
}

collect()