Skip to content

Канал диагностики

[История]

ВерсияИзменения
v19.2.0, v18.13.0diagnostics_channel теперь стабилен.
v15.1.0, v14.17.0Добавлено в: v15.1.0, v14.17.0

[Стабильный: 2 - Стабильный]

Стабильный: 2 Стабильность: 2 - Стабильный

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

Модуль node:diagnostics_channel предоставляет API для создания именованных каналов для передачи произвольных данных сообщений в целях диагностики.

Доступ к нему можно получить, используя:

js
import diagnostics_channel from 'node:diagnostics_channel'
js
const diagnostics_channel = require('node:diagnostics_channel')

Предполагается, что автор модуля, желающий сообщать диагностические сообщения, создаст один или несколько каналов верхнего уровня для передачи сообщений. Каналы также могут быть получены во время выполнения, но это не рекомендуется из-за дополнительных накладных расходов. Каналы могут быть экспортированы для удобства, но пока имя известно, его можно получить в любом месте.

Если вы намерены, чтобы ваш модуль создавал диагностические данные для потребления другими, рекомендуется включить документацию о том, какие именованные каналы используются, а также о форме данных сообщения. Имена каналов обычно должны включать имя модуля, чтобы избежать конфликтов с данными из других модулей.

Публичный API

Обзор

Ниже приведен простой обзор публичного API.

js
import diagnostics_channel from 'node:diagnostics_channel'

// Получение многоразового объекта канала
const channel = diagnostics_channel.channel('my-channel')

function onMessage(message, name) {
  // Получены данные
}

// Подписка на канал
diagnostics_channel.subscribe('my-channel', onMessage)

// Проверка наличия активного подписчика у канала
if (channel.hasSubscribers) {
  // Публикация данных в канал
  channel.publish({
    some: 'data',
  })
}

// Отписка от канала
diagnostics_channel.unsubscribe('my-channel', onMessage)
js
const diagnostics_channel = require('node:diagnostics_channel')

// Получение многоразового объекта канала
const channel = diagnostics_channel.channel('my-channel')

function onMessage(message, name) {
  // Получены данные
}

// Подписка на канал
diagnostics_channel.subscribe('my-channel', onMessage)

// Проверка наличия активного подписчика у канала
if (channel.hasSubscribers) {
  // Публикация данных в канал
  channel.publish({
    some: 'data',
  })
}

// Отписка от канала
diagnostics_channel.unsubscribe('my-channel', onMessage)

diagnostics_channel.hasSubscribers(name)

Добавлено в: v15.1.0, v14.17.0

  • name <string> | <symbol> Имя канала
  • Возвращает: <boolean> Если есть активные подписчики

Проверяет, есть ли активные подписчики на указанный канал. Это полезно, если подготовка сообщения, которое вы хотите отправить, может быть дорогостоящей.

Этот API является необязательным, но полезным при попытке публиковать сообщения из очень чувствительного к производительности кода.

js
import diagnostics_channel from 'node:diagnostics_channel'

if (diagnostics_channel.hasSubscribers('my-channel')) {
  // Есть подписчики, подготовить и опубликовать сообщение
}
js
const diagnostics_channel = require('node:diagnostics_channel')

if (diagnostics_channel.hasSubscribers('my-channel')) {
  // Есть подписчики, подготовить и опубликовать сообщение
}

diagnostics_channel.channel(name)

Добавлено в: v15.1.0, v14.17.0

  • name <string> | <symbol> Имя канала
  • Возвращает: <Channel> Объект именованного канала

Это основная точка входа для всех, кто хочет публиковать данные в именованный канал. Он создает объект канала, который оптимизирован для минимизации накладных расходов во время публикации.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channel = diagnostics_channel.channel('my-channel')
js
const diagnostics_channel = require('node:diagnostics_channel')

const channel = diagnostics_channel.channel('my-channel')

diagnostics_channel.subscribe(name, onMessage)

Добавлено в: v18.7.0, v16.17.0

Регистрирует обработчик сообщений для подписки на этот канал. Этот обработчик сообщений будет запускаться синхронно всякий раз, когда сообщение публикуется в канале. Любые ошибки, возникшие в обработчике сообщений, вызовут событие 'uncaughtException'.

js
import diagnostics_channel from 'node:diagnostics_channel'

diagnostics_channel.subscribe('my-channel', (message, name) => {
  // Получены данные
})
js
const diagnostics_channel = require('node:diagnostics_channel')

diagnostics_channel.subscribe('my-channel', (message, name) => {
  // Получены данные
})

diagnostics_channel.unsubscribe(name, onMessage)

Добавлено в: v18.7.0, v16.17.0

  • name <string> | <symbol> Имя канала
  • onMessage <Function> Предыдущий подписанный обработчик для удаления
  • Возвращает: <boolean> true, если обработчик был найден, false в противном случае.

Удаляет обработчик сообщений, ранее зарегистрированный для этого канала с помощью diagnostics_channel.subscribe(name, onMessage).

js
import diagnostics_channel from 'node:diagnostics_channel'

function onMessage(message, name) {
  // Получены данные
}

diagnostics_channel.subscribe('my-channel', onMessage)

diagnostics_channel.unsubscribe('my-channel', onMessage)
js
const diagnostics_channel = require('node:diagnostics_channel')

function onMessage(message, name) {
  // Получены данные
}

diagnostics_channel.subscribe('my-channel', onMessage)

diagnostics_channel.unsubscribe('my-channel', onMessage)

diagnostics_channel.tracingChannel(nameOrChannels)

Добавлено в: v19.9.0, v18.19.0

[Stable: 1 - Experimental]

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

Создает оболочку TracingChannel для заданных каналов TracingChannel. Если задано имя, соответствующие каналы трассировки будут созданы в форме tracing:${name}:${eventType}, где eventType соответствует типам каналов TracingChannel.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channelsByName = diagnostics_channel.tracingChannel('my-channel')

// или...

const channelsByCollection = diagnostics_channel.tracingChannel({
  start: diagnostics_channel.channel('tracing:my-channel:start'),
  end: diagnostics_channel.channel('tracing:my-channel:end'),
  asyncStart: diagnostics_channel.channel('tracing:my-channel:asyncStart'),
  asyncEnd: diagnostics_channel.channel('tracing:my-channel:asyncEnd'),
  error: diagnostics_channel.channel('tracing:my-channel:error'),
})
js
const diagnostics_channel = require('node:diagnostics_channel')

const channelsByName = diagnostics_channel.tracingChannel('my-channel')

// или...

const channelsByCollection = diagnostics_channel.tracingChannel({
  start: diagnostics_channel.channel('tracing:my-channel:start'),
  end: diagnostics_channel.channel('tracing:my-channel:end'),
  asyncStart: diagnostics_channel.channel('tracing:my-channel:asyncStart'),
  asyncEnd: diagnostics_channel.channel('tracing:my-channel:asyncEnd'),
  error: diagnostics_channel.channel('tracing:my-channel:error'),
})

Класс: Channel

Добавлено в: v15.1.0, v14.17.0

Класс Channel представляет отдельный именованный канал в конвейере данных. Он используется для отслеживания подписчиков и публикации сообщений, когда есть подписчики. Он существует как отдельный объект, чтобы избежать поиска каналов во время публикации, что обеспечивает очень высокую скорость публикации и позволяет интенсивно использовать его с минимальными затратами. Каналы создаются с помощью diagnostics_channel.channel(name), создание канала напрямую с помощью new Channel(name) не поддерживается.

channel.hasSubscribers

Добавлено в: v15.1.0, v14.17.0

  • Возвращает: <boolean> Если есть активные подписчики

Проверяет наличие активных подписчиков у этого канала. Это полезно, если сообщение, которое вы хотите отправить, может быть дорогостоящим для подготовки.

Этот API является необязательным, но полезным при попытке публикации сообщений из кода, очень чувствительного к производительности.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channel = diagnostics_channel.channel('my-channel')

if (channel.hasSubscribers) {
  // Есть подписчики, подготовить и опубликовать сообщение
}
js
const diagnostics_channel = require('node:diagnostics_channel')

const channel = diagnostics_channel.channel('my-channel')

if (channel.hasSubscribers) {
  // Есть подписчики, подготовить и опубликовать сообщение
}

channel.publish(message)

Добавлено в: v15.1.0, v14.17.0

  • message <any> Сообщение для отправки подписчикам канала

Публикует сообщение всем подписчикам канала. Это вызовет обработчики сообщений синхронно, поэтому они будут выполняться в том же контексте.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channel = diagnostics_channel.channel('my-channel')

channel.publish({
  some: 'message',
})
js
const diagnostics_channel = require('node:diagnostics_channel')

const channel = diagnostics_channel.channel('my-channel')

channel.publish({
  some: 'message',
})

channel.subscribe(onMessage)

Добавлено в: v15.1.0, v14.17.0

Устарело с: v18.7.0, v16.17.0

[Стабильность: 0 - Устарело]

Стабильность: 0 Стабильность: 0 - Устарело: Используйте diagnostics_channel.subscribe(name, onMessage)

  • onMessage <Function> Обработчик для получения сообщений канала

Регистрирует обработчик сообщений для подписки на этот канал. Этот обработчик сообщений будет выполняться синхронно всякий раз, когда сообщение публикуется в канал. Любые ошибки, возникающие в обработчике сообщений, вызовут событие 'uncaughtException'.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channel = diagnostics_channel.channel('my-channel')

channel.subscribe((message, name) => {
  // Получены данные
})
js
const diagnostics_channel = require('node:diagnostics_channel')

const channel = diagnostics_channel.channel('my-channel')

channel.subscribe((message, name) => {
  // Получены данные
})

channel.unsubscribe(onMessage)

[История]

ВерсияИзменения
v18.7.0, v16.17.0Устарело с: v18.7.0, v16.17.0
v17.1.0, v16.14.0, v14.19.0Добавлено возвращаемое значение. Добавлено для каналов без подписчиков.
v15.1.0, v14.17.0Добавлено в: v15.1.0, v14.17.0

[Стабильность: 0 - Устарело]

Стабильность: 0 Стабильность: 0 - Устарело: Используйте diagnostics_channel.unsubscribe(name, onMessage)

  • onMessage <Function> Предыдущий подписанный обработчик для удаления
  • Возвращает: <boolean> true, если обработчик был найден, false в противном случае.

Удаляет обработчик сообщений, ранее зарегистрированный для этого канала с помощью channel.subscribe(onMessage).

js
import diagnostics_channel from 'node:diagnostics_channel'

const channel = diagnostics_channel.channel('my-channel')

function onMessage(message, name) {
  // Получены данные
}

channel.subscribe(onMessage)

channel.unsubscribe(onMessage)
js
const diagnostics_channel = require('node:diagnostics_channel')

const channel = diagnostics_channel.channel('my-channel')

function onMessage(message, name) {
  // Получены данные
}

channel.subscribe(onMessage)

channel.unsubscribe(onMessage)

channel.bindStore(store[, transform])

Добавлено в: v19.9.0, v18.19.0

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

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

  • store <AsyncLocalStorage> Хранилище, к которому привязывать данные контекста.
  • transform <Function> Преобразование данных контекста перед установкой контекста хранилища.

Когда вызывается channel.runStores(context, ...), переданные данные контекста будут применены к любому хранилищу, привязанному к каналу. Если хранилище уже было привязано, предыдущая функция transform будет заменена новой. Функция transform может быть опущена, чтобы установить переданные данные контекста непосредственно в качестве контекста.

js
import diagnostics_channel from 'node:diagnostics_channel'
import { AsyncLocalStorage } from 'node:async_hooks'

const store = new AsyncLocalStorage()

const channel = diagnostics_channel.channel('my-channel')

channel.bindStore(store, data => {
  return { data }
})
js
const diagnostics_channel = require('node:diagnostics_channel')
const { AsyncLocalStorage } = require('node:async_hooks')

const store = new AsyncLocalStorage()

const channel = diagnostics_channel.channel('my-channel')

channel.bindStore(store, data => {
  return { data }
})

channel.unbindStore(store)

Добавлено в: v19.9.0, v18.19.0

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

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

  • store <AsyncLocalStorage> Хранилище, которое нужно отвязать от канала.
  • Возвращает: <boolean> true, если хранилище было найдено, false в противном случае.

Удалите обработчик сообщений, ранее зарегистрированный для этого канала с помощью channel.bindStore(store).

js
import diagnostics_channel from 'node:diagnostics_channel'
import { AsyncLocalStorage } from 'node:async_hooks'

const store = new AsyncLocalStorage()

const channel = diagnostics_channel.channel('my-channel')

channel.bindStore(store)
channel.unbindStore(store)
js
const diagnostics_channel = require('node:diagnostics_channel')
const { AsyncLocalStorage } = require('node:async_hooks')

const store = new AsyncLocalStorage()

const channel = diagnostics_channel.channel('my-channel')

channel.bindStore(store)
channel.unbindStore(store)

channel.runStores(context, fn[, thisArg[, ...args]])

Добавлено в: v19.9.0, v18.19.0

[Stable: 1 - Experimental]

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

  • context <any> Сообщение для отправки подписчикам и привязки к хранилищам.
  • fn <Function> Обработчик для запуска в контексте введенного хранилища.
  • thisArg <any> Получатель, который будет использоваться для вызова функции.
  • ...args <any> Необязательные аргументы для передачи функции.

Применяет предоставленные данные к любым экземплярам AsyncLocalStorage, привязанным к каналу, на время выполнения заданной функции, затем публикует в канале в пределах области применения этих данных к хранилищам.

Если функция преобразования была передана channel.bindStore(store), она будет применена для преобразования данных сообщения до того, как они станут значением контекста для хранилища. Предыдущий контекст хранилища доступен из функции преобразования в случаях, когда требуется связывание контекста.

Контекст, применяемый к хранилищу, должен быть доступен в любом асинхронном коде, который продолжает выполнение, начатое во время заданной функции, однако возможны ситуации, когда может произойти потеря контекста.

js
import diagnostics_channel from 'node:diagnostics_channel'
import { AsyncLocalStorage } from 'node:async_hooks'

const store = new AsyncLocalStorage()

const channel = diagnostics_channel.channel('my-channel')

channel.bindStore(store, message => {
  const parent = store.getStore()
  return new Span(message, parent)
})
channel.runStores({ some: 'message' }, () => {
  store.getStore() // Span({ some: 'message' })
})
js
const diagnostics_channel = require('node:diagnostics_channel')
const { AsyncLocalStorage } = require('node:async_hooks')

const store = new AsyncLocalStorage()

const channel = diagnostics_channel.channel('my-channel')

channel.bindStore(store, message => {
  const parent = store.getStore()
  return new Span(message, parent)
})
channel.runStores({ some: 'message' }, () => {
  store.getStore() // Span({ some: 'message' })
})

Класс: TracingChannel

Добавлено в: v19.9.0, v18.19.0

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

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

Класс TracingChannel представляет собой набор каналов TracingChannel, которые вместе выражают одно отслеживаемое действие. Он используется для формализации и упрощения процесса создания событий для отслеживания потока приложения. diagnostics_channel.tracingChannel() используется для создания TracingChannel. Как и в случае с Channel, рекомендуется создавать и повторно использовать один TracingChannel на верхнем уровне файла, а не создавать их динамически.

tracingChannel.subscribe(subscribers)

Добавлено в: v19.9.0, v18.19.0

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

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

Вспомогательная функция для подписки набора функций на соответствующие каналы. Это то же самое, что и вызов channel.subscribe(onMessage) для каждого канала отдельно.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.subscribe({
  start(message) {
    // Обработка начального сообщения
  },
  end(message) {
    // Обработка конечного сообщения
  },
  asyncStart(message) {
    // Обработка сообщения asyncStart
  },
  asyncEnd(message) {
    // Обработка сообщения asyncEnd
  },
  error(message) {
    // Обработка сообщения об ошибке
  },
})
js
const diagnostics_channel = require('node:diagnostics_channel')

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.subscribe({
  start(message) {
    // Обработка начального сообщения
  },
  end(message) {
    // Обработка конечного сообщения
  },
  asyncStart(message) {
    // Обработка сообщения asyncStart
  },
  asyncEnd(message) {
    // Обработка сообщения asyncEnd
  },
  error(message) {
    // Обработка сообщения об ошибке
  },
})

tracingChannel.unsubscribe(subscribers)

Добавлено в: v19.9.0, v18.19.0

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

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

Вспомогательная функция для отписки набора функций от соответствующих каналов. Это то же самое, что вызов channel.unsubscribe(onMessage) на каждом канале по отдельности.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.unsubscribe({
  start(message) {
    // Handle start message
  },
  end(message) {
    // Handle end message
  },
  asyncStart(message) {
    // Handle asyncStart message
  },
  asyncEnd(message) {
    // Handle asyncEnd message
  },
  error(message) {
    // Handle error message
  },
})
js
const diagnostics_channel = require('node:diagnostics_channel')

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.unsubscribe({
  start(message) {
    // Handle start message
  },
  end(message) {
    // Handle end message
  },
  asyncStart(message) {
    // Handle asyncStart message
  },
  asyncEnd(message) {
    // Handle asyncEnd message
  },
  error(message) {
    // Handle error message
  },
})

tracingChannel.traceSync(fn[, context[, thisArg[, ...args]]])

Добавлено в: v19.9.0, v18.19.0

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

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

  • fn <Function> Функция, вокруг которой нужно обернуть трассировку
  • context <Object> Общий объект для корреляции событий
  • thisArg <any> Приемник, который будет использован для вызова функции
  • ...args <any> Необязательные аргументы для передачи в функцию
  • Возвращает: <any> Возвращаемое значение заданной функции

Трассировка синхронного вызова функции. Это всегда будет создавать событие start и событие end вокруг выполнения и может создать событие error, если заданная функция вызовет ошибку. Это запустит заданную функцию с помощью channel.runStores(context, ...) в канале start, что гарантирует, что все события должны иметь все привязанные хранилища, установленные в соответствии с этим контекстом трассировки.

Чтобы гарантировать формирование только правильных графов трассировки, события будут публиковаться только в том случае, если подписчики присутствуют до начала трассировки. Подписки, которые добавлены после начала трассировки, не будут получать будущие события из этой трассировки, будут видны только будущие трассировки.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.traceSync(
  () => {
    // Do something
  },
  {
    some: 'thing',
  }
)
js
const diagnostics_channel = require('node:diagnostics_channel')

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.traceSync(
  () => {
    // Do something
  },
  {
    some: 'thing',
  }
)

tracingChannel.tracePromise(fn[, context[, thisArg[, ...args]]])

Добавлено в: v19.9.0, v18.19.0

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

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

  • fn <Function> Функция, возвращающая Promise, для обертывания трассировкой
  • context <Object> Общий объект для корреляции событий трассировки
  • thisArg <any> Приемник, который будет использоваться для вызова функции
  • ...args <any> Необязательные аргументы для передачи в функцию
  • Возвращает: <Promise> Цепочка от промиса, возвращенного заданной функцией

Отслеживает вызов функции, возвращающей промис. Это всегда будет генерировать событие start и событие end вокруг синхронной части выполнения функции, и будет генерировать событие asyncStart и событие asyncEnd при достижении продолжения промиса. Он также может сгенерировать событие error, если заданная функция выдает ошибку или возвращенный промис отклоняется. Это запустит данную функцию, используя channel.runStores(context, ...) на канале start, что гарантирует, что все события должны иметь любые привязанные хранилища, установленные в соответствии с этим контекстом трассировки.

Чтобы гарантировать формирование только правильных графов трассировки, события будут публиковаться только в том случае, если подписчики присутствуют до начала трассировки. Подписки, добавленные после начала трассировки, не будут получать будущие события от этой трассировки, будут видны только будущие трассировки.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.tracePromise(
  async () => {
    // Do something
  },
  {
    some: 'thing',
  }
)
js
const diagnostics_channel = require('node:diagnostics_channel')

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.tracePromise(
  async () => {
    // Do something
  },
  {
    some: 'thing',
  }
)

tracingChannel.traceCallback(fn[, position[, context[, thisArg[, ...args]]]])

Добавлено в: v19.9.0, v18.19.0

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

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

  • fn <Function> Функция обратного вызова, используемая для обертывания трассировки
  • position <number> Позиция аргумента обратного вызова с нулевым индексом (по умолчанию последний аргумент, если передано undefined)
  • context <Object> Общий объект для корреляции событий трассировки (по умолчанию {} если передано undefined)
  • thisArg <any> Получатель, который будет использоваться для вызова функции
  • ...args <any> Аргументы для передачи в функцию (должны включать обратный вызов)
  • Возвращает: <any> Возвращаемое значение заданной функции

Трассировка вызова функции, получающей обратный вызов. Ожидается, что обратный вызов будет следовать соглашению об ошибке как первом аргументе, обычно используемом. Это всегда будет производить событие start и событие end вокруг синхронной части выполнения функции и будет производить событие asyncStart и событие asyncEnd вокруг выполнения обратного вызова. Он также может произвести событие error, если данная функция выдает ошибку или если установлен первый аргумент, переданный в обратный вызов. Это запустит данную функцию, используя channel.runStores(context, ...) на канале start, что гарантирует, что все события должны иметь все привязанные хранилища, установленные в соответствии с этим контекстом трассировки.

Чтобы гарантировать формирование только правильных графов трассировки, события будут публиковаться только в том случае, если подписчики присутствуют до начала трассировки. Подписки, добавленные после начала трассировки, не будут получать будущие события из этой трассировки, будут видны только будущие трассировки.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.traceCallback(
  (arg1, callback) => {
    // Выполнить что-нибудь
    callback(null, 'result')
  },
  1,
  {
    some: 'thing',
  },
  thisArg,
  arg1,
  callback
)
js
const diagnostics_channel = require('node:diagnostics_channel')

const channels = diagnostics_channel.tracingChannel('my-channel')

channels.traceCallback(
  (arg1, callback) => {
    // Выполнить что-нибудь
    callback(null, 'result')
  },
  1,
  {
    some: 'thing',
  },
  thisArg,
  arg1,
  callback
)

Обратный вызов также будет запущен с помощью channel.runStores(context, ...), что в некоторых случаях обеспечивает восстановление потери контекста.

js
import diagnostics_channel from 'node:diagnostics_channel'
import { AsyncLocalStorage } from 'node:async_hooks'

const channels = diagnostics_channel.tracingChannel('my-channel')
const myStore = new AsyncLocalStorage()

// Стартовый канал устанавливает начальные данные хранилища во что-то
// и сохраняет это значение данных хранилища в объекте контекста трассировки
channels.start.bindStore(myStore, data => {
  const span = new Span(data)
  data.span = span
  return span
})

// Затем asyncStart может восстановить эти данные, которые он сохранил ранее
channels.asyncStart.bindStore(myStore, data => {
  return data.span
})
js
const diagnostics_channel = require('node:diagnostics_channel')
const { AsyncLocalStorage } = require('node:async_hooks')

const channels = diagnostics_channel.tracingChannel('my-channel')
const myStore = new AsyncLocalStorage()

// Стартовый канал устанавливает начальные данные хранилища во что-то
// и сохраняет это значение данных хранилища в объекте контекста трассировки
channels.start.bindStore(myStore, data => {
  const span = new Span(data)
  data.span = span
  return span
})

// Затем asyncStart может восстановить эти данные, которые он сохранил ранее
channels.asyncStart.bindStore(myStore, data => {
  return data.span
})

tracingChannel.hasSubscribers

Добавлено в: v22.0.0, v20.13.0

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

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

  • Возвращает: <boolean> true, если у любого из отдельных каналов есть подписчик, false в противном случае.

Это вспомогательный метод, доступный в экземпляре TracingChannel, для проверки, есть ли подписчики у каких-либо из каналов TracingChannel. Возвращается значение true, если у любого из них есть хотя бы один подписчик, в противном случае возвращается false.

js
import diagnostics_channel from 'node:diagnostics_channel'

const channels = diagnostics_channel.tracingChannel('my-channel')

if (channels.hasSubscribers) {
  // Сделать что-то
}
js
const diagnostics_channel = require('node:diagnostics_channel')

const channels = diagnostics_channel.tracingChannel('my-channel')

if (channels.hasSubscribers) {
  // Сделать что-то
}

Каналы TracingChannel

TracingChannel — это набор из нескольких diagnostics_channels, представляющих конкретные моменты в жизненном цикле выполнения одного отслеживаемого действия. Поведение разделено на пять diagnostics_channels, состоящих из start, end, asyncStart, asyncEnd и error. Одно отслеживаемое действие будет использовать один и тот же объект события для всех событий, что может быть полезно для управления корреляцией через weakmap.

Эти объекты событий будут дополнены значениями result или error, когда задача "завершится". В случае синхронной задачи result будет возвращаемым значением, а error будет любым исключением, возникшим в функции. В случае асинхронных функций на основе обратного вызова result будет вторым аргументом обратного вызова, а error будет либо выброшенной ошибкой, видимой в событии end, либо первым аргументом обратного вызова в любом из событий asyncStart или asyncEnd.

Чтобы гарантировать формирование только корректных графов трассировки, события должны публиковаться только при наличии подписчиков до начала трассировки. Подписки, добавленные после начала трассировки, не должны получать будущие события от этой трассировки, будут видны только будущие трассировки.

Каналы трассировки должны следовать шаблону именования:

  • tracing:module.class.method:start или tracing:module.function:start
  • tracing:module.class.method:end или tracing:module.function:end
  • tracing:module.class.method:asyncStart или tracing:module.function:asyncStart
  • tracing:module.class.method:asyncEnd или tracing:module.function:asyncEnd
  • tracing:module.class.method:error или tracing:module.function:error

start(event)

  • Имя: tracing:${name}:start

Событие start представляет точку, в которой вызывается функция. В этот момент данные события могут содержать аргументы функции или что-либо еще, доступное в самом начале выполнения функции.

end(event)

  • Имя: tracing:${name}:end

Событие end представляет точку, в которой вызов функции возвращает значение. В случае асинхронной функции это происходит, когда возвращается промис, а не когда сама функция делает оператор return внутри. В этот момент, если отслеживаемая функция была синхронной, поле result будет установлено в возвращаемое значение функции. В качестве альтернативы, может присутствовать поле error, представляющее любые возникшие ошибки.

Рекомендуется специально прослушивать событие error для отслеживания ошибок, так как может оказаться, что отслеживаемое действие может вызвать несколько ошибок. Например, асинхронная задача, которая не выполняется, может быть запущена внутри до синхронной части задачи, а затем вызвать ошибку.

asyncStart(event)

  • Имя: tracing:${name}:asyncStart

Событие asyncStart представляет достижение обратного вызова или продолжения отслеживаемой функции. В этот момент могут быть доступны такие вещи, как аргументы обратного вызова, или что-либо еще, выражающее "результат" действия.

Для функций на основе обратных вызовов первый аргумент обратного вызова будет назначен полю error, если он не undefined или null, а второй аргумент будет назначен полю result.

Для промисов аргумент пути resolve будет назначен result, а аргумент пути reject будет назначен error.

Рекомендуется специально прослушивать событие error для отслеживания ошибок, так как может оказаться, что отслеживаемое действие может вызвать несколько ошибок. Например, асинхронная задача, которая не выполняется, может быть запущена внутри до синхронной части задачи, а затем вызвать ошибку.

asyncEnd(event)

  • Имя: tracing:${name}:asyncEnd

Событие asyncEnd представляет собой возврат обратного вызова асинхронной функции. Маловероятно, что данные события изменятся после события asyncStart, однако может быть полезно увидеть точку, в которой завершается обратный вызов.

error(event)

  • Имя: tracing:${name}:error

Событие error представляет любую ошибку, возникшую при выполнении отслеживаемой функции, синхронно или асинхронно. Если ошибка возникает в синхронной части отслеживаемой функции, то ошибка будет присвоена полю error события, и будет запущено событие error. Если ошибка получена асинхронно через обратный вызов или отклонение промиса, она также будет присвоена полю error события и запустит событие error.

Возможно, что вызов одной отслеживаемой функции может вызвать ошибки несколько раз, поэтому это следует учитывать при использовании этого события. Например, если внутренняя асинхронная задача завершится с ошибкой, а затем синхронная часть функции вызовет ошибку, то будут сгенерированы два события error: одно для синхронной ошибки, а другое для асинхронной.

Встроенные каналы

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

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

Хотя API diagnostics_channel теперь считается стабильным, встроенные каналы, доступные в настоящее время, не являются таковыми. Каждый канал должен быть объявлен стабильным независимо.

HTTP

http.client.request.created

Генерируется, когда клиент создает объект запроса. В отличие от http.client.request.start, это событие генерируется до отправки запроса.

http.client.request.start

Генерируется, когда клиент начинает запрос.

http.client.request.error

Генерируется при возникновении ошибки во время клиентского запроса.

http.client.response.finish

Генерируется, когда клиент получает ответ.

http.server.request.start

Генерируется, когда сервер получает запрос.

http.server.response.created

Генерируется, когда сервер создает ответ. Событие генерируется до отправки ответа.

http.server.response.finish

Генерируется, когда сервер отправляет ответ.

Модули

module.require.start

  • event <Object>, содержащий следующие свойства
    • id - Аргумент, переданный в require(). Имя модуля.
    • parentFilename - Имя модуля, который попытался выполнить require(id).

Возникает при выполнении require(). См. событие start.

module.require.end

  • event <Object>, содержащий следующие свойства
    • id - Аргумент, переданный в require(). Имя модуля.
    • parentFilename - Имя модуля, который попытался выполнить require(id).

Возникает, когда вызов require() возвращает результат. См. событие end.

module.require.error

  • event <Object>, содержащий следующие свойства

    • id - Аргумент, переданный в require(). Имя модуля.
    • parentFilename - Имя модуля, который попытался выполнить require(id).
  • error <Error>

Возникает, когда require() вызывает ошибку. См. событие error.

module.import.asyncStart

  • event <Object>, содержащий следующие свойства
    • id - Аргумент, переданный в import(). Имя модуля.
    • parentURL - Объект URL модуля, который попытался выполнить import(id).

Возникает при вызове import(). См. событие asyncStart.

module.import.asyncEnd

  • event <Object>, содержащий следующие свойства
    • id - Аргумент, переданный в import(). Имя модуля.
    • parentURL - Объект URL модуля, который попытался выполнить import(id).

Возникает, когда import() завершен. См. событие asyncEnd.

module.import.error

  • event <Object>, содержащий следующие свойства

    • id - Аргумент, переданный в import(). Имя модуля.
    • parentURL - Объект URL модуля, который попытался выполнить import(id).
  • error <Error>

Возникает, когда import() вызывает ошибку. См. событие error.

NET

net.client.socket

Срабатывает, когда создается новый TCP или пайп клиентский сокет.

net.server.socket

Срабатывает, когда принимается новое TCP или пайп соединение.

tracing:net.server.listen:asyncStart

Срабатывает при вызове net.Server.listen(), до фактической настройки порта или пайпа.

tracing:net.server.listen:asyncEnd

Срабатывает, когда net.Server.listen() завершает работу, и таким образом сервер готов принимать соединения.

tracing:net.server.listen:error

Срабатывает, когда net.Server.listen() возвращает ошибку.

UDP

udp.socket

Срабатывает, когда создается новый UDP сокет.

Process

Добавлено в: v16.18.0

child_process

Срабатывает, когда создается новый процесс.

Worker Thread

Добавлено в: v16.18.0

worker_threads

Срабатывает, когда создается новый поток.