追蹤事件#

穩定性: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() 方法的追蹤資料擷取。
  • v8V8 事件與 GC、編譯和執行相關。
  • node.http:啟用追蹤 http 要求/回應的追蹤資料擷取。

預設啟用 nodenode.async_hooksv8 類別。

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

先前版本的 Node.js 需要使用 --trace-events-enabled 旗標才能啟用追蹤事件。此需求已被移除。不過,--trace-events-enabled 旗標可以使用,且預設會啟用 nodenode.async_hooksv8 追蹤事件類別。

node --trace-events-enabled

# is equivalent to

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

或者,可以使用 node:trace_events 模組啟用追蹤事件

const trace_events = require('node:trace_events');
const tracing = trace_events.createTracing({ categories: ['node.perf'] });
tracing.enable();  // Enable trace event capture for the 'node.perf' category

// do work

tracing.disable();  // Disable trace event capture for the 'node.perf' category 

在啟用追蹤功能的情況下執行 Node.js 會產生記錄檔,這些記錄檔可以在 Chrome 的 chrome://tracing 標籤中開啟。

記錄檔預設稱為 node_trace.${rotation}.log,其中 ${rotation} 是遞增的記錄檔輪替 ID。檔案路徑模式可以使用 --trace-event-file-pattern 指定,它接受支援 ${rotation}${pid} 的範本字串

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

若要確保在類似 SIGINTSIGTERMSIGBREAK 的訊號事件後正確產生記錄檔,請務必在程式碼中提供適當的處理常式,例如

process.on('SIGINT', function onSigint() {
  console.info('Received SIGINT.');
  process.exit(130);  // Or applicable exit code depending on OS and signal
}); 

追蹤系統使用與 process.hrtime() 相同的時間來源。不過,追蹤事件時間戳記是以微秒表示,這與傳回奈秒的 process.hrtime() 不同。

此模組的功能在 Worker 執行緒中不可用。

node:trace_events 模組#

Tracing 物件#

Tracing 物件用於為類別組啟用或停用追蹤。使用 trace_events.createTracing() 方法建立執行個體。

建立時,Tracing 物件會停用。呼叫 tracing.enable() 方法會將類別新增至已啟用追蹤事件類別組。呼叫 tracing.disable() 會將類別從已啟用追蹤事件類別組中移除。

tracing.categories#

Tracing 物件涵蓋的追蹤事件類別清單,以逗號分隔。

tracing.disable()#

停用此 Tracing 物件。

只有其他已啟用 Tracing 物件未涵蓋且未由 --trace-event-categories 旗標指定的追蹤事件類別才會被停用。

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();

// Prints 'node,node.perf,v8'
console.log(trace_events.getEnabledCategories());

t2.disable(); // Will only disable emission of the 'node.perf' category

// Prints 'node,v8'
console.log(trace_events.getEnabledCategories()); 
tracing.enable()#

針對 Tracing 物件涵蓋的類別集啟用此 Tracing 物件。

tracing.enabled#
  • <布林值> 僅在已啟用 Tracing 物件時為 true

trace_events.createTracing(options)#

  • options <物件>
    • categories <字串陣列> 追蹤類別名稱陣列。陣列中包含的值會在可能的情況下強制轉換為字串。如果無法強制轉換值,則會擲回錯誤。
  • 傳回:<Tracing>

針對給定的 categories 集建立並傳回 Tracing 物件。

const trace_events = require('node:trace_events');
const categories = ['node.perf', 'node.async_hooks'];
const tracing = trace_events.createTracing({ categories });
tracing.enable();
// do stuff
tracing.disable(); 

trace_events.getEnabledCategories()#

傳回目前已啟用的所有追蹤事件類別的逗號分隔清單。目前已啟用的追蹤事件類別的目前設定是由所有目前已啟用的 Tracing 物件的聯集,以及使用 --trace-event-categories 旗標啟用的任何類別所決定。

假設有以下檔案 test.js,指令 node --trace-event-categories node.perf test.js 會在主控台列印 'node.async_hooks,node.perf'

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()); 

範例#

透過檢查器收集追蹤事件資料#

'use strict';

const { Session } = require('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();