Skip to content

Inspector

[Stable: 2 - Stable]

Stable: 2 Stability: 2 - Stable

Исходный код: lib/inspector.js

Модуль node:inspector предоставляет API для взаимодействия с инспектором V8.

Доступ к нему можно получить с помощью:

js
import * as inspector from 'node:inspector/promises'
js
const inspector = require('node:inspector/promises')

или

js
import * as inspector from 'node:inspector'
js
const inspector = require('node:inspector')

API на основе Promise

[Stable: 1 - Experimental]

Stable: 1 Stability: 1 - Experimental

Добавлено в: v19.0.0

Class: inspector.Session

inspector.Session используется для отправки сообщений в бэкэнд инспектора V8 и получения ответов на сообщения и уведомлений.

new inspector.Session()

Добавлено в: v8.0.0

Создает новый экземпляр класса inspector.Session. Сеанс инспектора должен быть подключен через session.connect() прежде чем сообщения смогут быть отправлены в бэкэнд инспектора.

При использовании Session, объект, выведенный API консоли, не будет освобожден, если мы не выполним вручную команду Runtime.DiscardConsoleEntries.

Событие: 'inspectorNotification'

Добавлено в: v8.0.0

  • <Object> Объект сообщения уведомления

Генерируется при получении любого уведомления от инспектора V8.

js
session.on('inspectorNotification', message => console.log(message.method))
// Debugger.paused
// Debugger.resumed

Также можно подписаться только на уведомления с определенным методом:

Событие: &lt;inspector-protocol-method&gt;; {#event-<inspector-protocol-method>;}

Добавлено в: v8.0.0

  • <Object> Объект сообщения уведомления

Генерируется при получении уведомления инспектора, поле метода которого установлено в значение \<inspector-protocol-method\>.

В следующем фрагменте устанавливается обработчик события 'Debugger.paused', и выводится причина приостановки программы всякий раз, когда выполнение программы приостанавливается (например, через точки останова):

js
session.on('Debugger.paused', ({ params }) => {
  console.log(params.hitBreakpoints)
})
// [ '/the/file/that/has/the/breakpoint.js:11:0' ]

session.connect()

Добавлено в: v8.0.0

Подключает сеанс к серверной части инспектора.

session.connectToMainThread()

Добавлено в: v12.11.0

Подключает сеанс к серверной части инспектора главного потока. Исключение будет выброшено, если этот API не был вызван в потоке Worker.

session.disconnect()

Добавлено в: v8.0.0

Немедленно закрывает сеанс. Все ожидающие обратные вызовы сообщений будут вызваны с ошибкой. Для возможности отправки сообщений необходимо будет вызвать session.connect(). Переподключенный сеанс потеряет все состояния инспектора, такие как включенные агенты или настроенные точки останова.

session.post(method[, params])

Добавлено в: v19.0.0

Отправляет сообщение на серверную часть инспектора.

js
import { Session } from 'node:inspector/promises'
try {
  const session = new Session()
  session.connect()
  const result = await session.post('Runtime.evaluate', { expression: '2 + 2' })
  console.log(result)
} catch (error) {
  console.error(error)
}
// Вывод: { result: { type: 'number', value: 4, description: '4' } }

Последняя версия протокола инспектора V8 опубликована на Chrome DevTools Protocol Viewer.

Инспектор Node.js поддерживает все домены протокола Chrome DevTools, объявленные V8. Домен протокола Chrome DevTools предоставляет интерфейс для взаимодействия с одним из агентов среды выполнения, используемых для проверки состояния приложения и прослушивания событий среды выполнения.

Пример использования

Помимо отладчика, различные профилировщики V8 доступны через протокол DevTools.

Профилировщик ЦП

Вот пример использования профилировщика ЦП:

js
import { Session } from 'node:inspector/promises'
import fs from 'node:fs'
const session = new Session()
session.connect()

await session.post('Profiler.enable')
await session.post('Profiler.start')
// Вызов бизнес-логики для измерения здесь...

// немного позже...
const { profile } = await session.post('Profiler.stop')

// Запись профиля на диск, загрузка и т. д.
fs.writeFileSync('./profile.cpuprofile', JSON.stringify(profile))
Профилировщик кучи

Вот пример использования профилировщика кучи:

js
import { Session } from 'node:inspector/promises'
import fs from 'node:fs'
const session = new Session()

const fd = fs.openSync('profile.heapsnapshot', 'w')

session.connect()

session.on('HeapProfiler.addHeapSnapshotChunk', m => {
  fs.writeSync(fd, m.params.chunk)
})

const result = await session.post('HeapProfiler.takeHeapSnapshot', null)
console.log('HeapProfiler.takeHeapSnapshot done:', result)
session.disconnect()
fs.closeSync(fd)

API обратных вызовов

Класс: inspector.Session

inspector.Session используется для отправки сообщений в back-end инспектора V8 и получения ответов на сообщения и уведомлений.

new inspector.Session()

Добавлено в: v8.0.0

Создает новый экземпляр класса inspector.Session. Сеанс инспектора должен быть подключен через session.connect() прежде чем сообщения смогут быть отправлены в back-end инспектора.

При использовании Session объект, выводимый API консоли, не будет освобожден, если мы вручную не выполним команду Runtime.DiscardConsoleEntries.

Событие: 'inspectorNotification'

Добавлено в: v8.0.0

  • <Object> Объект сообщения уведомления

Генерируется при получении любого уведомления от инспектора V8.

js
session.on('inspectorNotification', message => console.log(message.method))
// Debugger.paused
// Debugger.resumed

Также можно подписаться только на уведомления с определенным методом:

Событие: &lt;inspector-protocol-method&gt;; {#event-<inspector-protocol-method>;_1}

Добавлено в: v8.0.0

  • <Object> Объект сообщения уведомления

Генерируется при получении уведомления инспектора, поле метода которого установлено в значение \<inspector-protocol-method\>.

В следующем фрагменте устанавливается прослушиватель события 'Debugger.paused', и выводится причина приостановки программы всякий раз, когда выполнение программы приостанавливается (например, через точки останова):

js
session.on('Debugger.paused', ({ params }) => {
  console.log(params.hitBreakpoints)
})
// [ '/the/file/that/has/the/breakpoint.js:11:0' ]

session.connect()

Добавлено в: v8.0.0

Подключает сеанс к серверной части инспектора.

session.connectToMainThread()

Добавлено в: v12.11.0

Подключает сеанс к серверной части инспектора основного потока. Если этот API не был вызван в потоке Worker, будет выброшено исключение.

session.disconnect()

Добавлено в: v8.0.0

Немедленно закрывает сеанс. Все ожидающие обратные вызовы сообщений будут вызваны с ошибкой. session.connect() необходимо будет вызвать, чтобы снова отправлять сообщения. Переподключенный сеанс потеряет все состояние инспектора, такое как включенные агенты или настроенные точки останова.

session.post(method[, params][, callback])

[История]

ВерсияИзменения
v18.0.0Передача недопустимого обратного вызова в аргумент callback теперь вызывает ERR_INVALID_ARG_TYPE вместо ERR_INVALID_CALLBACK.
v8.0.0Добавлено в: v8.0.0

Отправляет сообщение на серверную часть инспектора. callback будет уведомлен о получении ответа. callback - это функция, которая принимает два необязательных аргумента: ошибку и результат, зависящий от сообщения.

js
session.post('Runtime.evaluate', { expression: '2 + 2' }, (error, { result }) => console.log(result))
// Вывод: { type: 'number', value: 4, description: '4' }

Последняя версия протокола инспектора V8 опубликована в Средстве просмотра протокола Chrome DevTools.

Инспектор Node.js поддерживает все домены протокола Chrome DevTools, объявленные V8. Домен протокола Chrome DevTools предоставляет интерфейс для взаимодействия с одним из агентов времени выполнения, используемых для проверки состояния приложения и прослушивания событий времени выполнения.

Нельзя установить reportProgress в true при отправке команды HeapProfiler.takeHeapSnapshot или HeapProfiler.stopTrackingHeapObjects в V8.

Пример использования

Помимо отладчика, различные профилировщики V8 доступны через протокол DevTools.

Профилировщик ЦП

Вот пример использования профилировщика ЦП:

js
const inspector = require('node:inspector')
const fs = require('node:fs')
const session = new inspector.Session()
session.connect()

session.post('Profiler.enable', () => {
  session.post('Profiler.start', () => {
    // Вызов бизнес-логики, подлежащей измерению, здесь...

    // немного позже...
    session.post('Profiler.stop', (err, { profile }) => {
      // Запись профиля на диск, загрузка и т.д.
      if (!err) {
        fs.writeFileSync('./profile.cpuprofile', JSON.stringify(profile))
      }
    })
  })
})
Профилировщик кучи

Вот пример использования профилировщика кучи:

js
const inspector = require('node:inspector')
const fs = require('node:fs')
const session = new inspector.Session()

const fd = fs.openSync('profile.heapsnapshot', 'w')

session.connect()

session.on('HeapProfiler.addHeapSnapshotChunk', m => {
  fs.writeSync(fd, m.params.chunk)
})

session.post('HeapProfiler.takeHeapSnapshot', null, (err, r) => {
  console.log('HeapProfiler.takeHeapSnapshot done:', err, r)
  session.disconnect()
  fs.closeSync(fd)
})

Общие объекты

inspector.close()

[История]

ВерсияИзменения
v18.10.0API доступен в потоках worker.
v9.0.0Добавлено в: v9.0.0

Пытается закрыть все оставшиеся соединения, блокируя цикл событий до тех пор, пока все они не будут закрыты. После закрытия всех соединений деактивирует инспектор.

inspector.console

  • <Объект> Объект для отправки сообщений в удаленную консоль инспектора.
js
require('node:inspector').console.log('a message')

Консоль инспектора не имеет паритета API с консолью Node.js.

inspector.open([port[, host[, wait]]])

[История]

ВерсияИзменения
v20.6.0inspector.open() теперь возвращает объект Disposable.
  • port <число> Порт для прослушивания подключений инспектора. Необязательно. По умолчанию: то, что было указано в командной строке.
  • host <строка> Хост для прослушивания подключений инспектора. Необязательно. По умолчанию: то, что было указано в командной строке.
  • wait <булево> Блокировать до тех пор, пока клиент не подключится. Необязательно. По умолчанию: false.
  • Возвращает: <Disposable> Объект Disposable, который вызывает inspector.close().

Активировать инспектор на хосте и порте. Эквивалентно node --inspect=[[host:]port], но может быть выполнено программным способом после запуска node.

Если wait имеет значение true, будет блокироваться до тех пор, пока клиент не подключится к порту инспектора и управление потоком не будет передано клиенту отладчика.

См. предупреждение о безопасности относительно использования параметра host.

inspector.url()

Возвращает URL активного инспектора или undefined, если его нет.

bash
$ node --inspect -p 'inspector.url()'
Debugger listening on ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34
For help, see: https://nodejs.org/en/docs/inspector
ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34

$ node --inspect=localhost:3000 -p 'inspector.url()'
Debugger listening on ws://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a
For help, see: https://nodejs.org/en/docs/inspector
ws://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a

$ node -p 'inspector.url()'
undefined

inspector.waitForDebugger()

Добавлен в: v12.7.0

Блокирует выполнение до тех пор, пока клиент (существующий или подключившийся позже) не отправит команду Runtime.runIfWaitingForDebugger.

Если активного инспектора нет, будет выброшено исключение.

Интеграция с DevTools

Модуль node:inspector предоставляет API для интеграции с инструментами разработчика, поддерживающими протокол Chrome DevTools. Фронтенды DevTools, подключенные к запущенному экземпляру Node.js, могут перехватывать события протокола, отправляемые из экземпляра, и отображать их соответствующим образом для облегчения отладки. Следующие методы передают событие протокола всем подключенным фронтендам. Передаваемые методам params могут быть необязательными, в зависимости от протокола.

js
// Событие `Network.requestWillBeSent` будет вызвано.
inspector.Network.requestWillBeSent({
  requestId: 'request-id-1',
  timestamp: Date.now() / 1000,
  wallTime: Date.now(),
  request: {
    url: 'https://nodejs.org/en',
    method: 'GET',
  },
})

inspector.Network.requestWillBeSent([params])

Добавлен в: v22.6.0, v20.18.0

[Стабильность: 1 - Экспериментальный]

Стабильность: 1 Стабильность: 1 - Экспериментальный

Эта функция доступна только при включенном флаге --experimental-network-inspection.

Передает событие Network.requestWillBeSent подключенным фронтендам. Это событие указывает на то, что приложение собирается отправить HTTP-запрос.

inspector.Network.responseReceived([params])

Добавлен в: v22.6.0, v20.18.0

[Стабильность: 1 - Экспериментальный]

Стабильность: 1 Стабильность: 1 - Экспериментальный

Эта функция доступна только при включенном флаге --experimental-network-inspection.

Передает событие Network.responseReceived подключенным фронтендам. Это событие указывает на то, что HTTP-ответ доступен.

inspector.Network.loadingFinished([params])

Добавлено в: v22.6.0, v20.18.0

[Стабильность: 1 - Экспериментально]

Стабильность: 1 Стабильность: 1 - Экспериментально

Эта функция доступна только при включенном флаге --experimental-network-inspection.

Передает событие Network.loadingFinished подключенным клиентам. Это событие указывает на завершение загрузки HTTP-запроса.

inspector.Network.loadingFailed([params])

Добавлено в: v22.7.0, v20.18.0

[Стабильность: 1 - Экспериментально]

Стабильность: 1 Стабильность: 1 - Экспериментально

Эта функция доступна только при включенном флаге --experimental-network-inspection.

Передает событие Network.loadingFailed подключенным клиентам. Это событие указывает на сбой загрузки HTTP-запроса.

Поддержка точек останова

Протокол Chrome DevTools Debugger domain позволяет inspector.Session подключаться к программе и устанавливать точки останова для пошагового выполнения кода.

Однако следует избегать установки точек останова с помощью однопоточного inspector.Session, подключенного с помощью session.connect(), поскольку подключаемая и приостанавливаемая программа — это сам отладчик. Вместо этого попробуйте подключиться к главному потоку с помощью session.connectToMainThread() и установить точки останова в потоке worker, или подключиться с помощью программы Debugger через WebSocket-соединение.