JavaScript (Node.js) OpenTelemetry

Материал из Документация Ключ-АСТРОМ
Версия от 14:35, 16 октября 2025; IKuznetsov (обсуждение | вклад) (Новая страница: «В этом пошаговом руководстве показано, как добавить наблюдаемость в ваше '''JavaScript'''-'''при...»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)

В этом пошаговом руководстве показано, как добавить наблюдаемость в ваше JavaScript-приложение с помощью библиотек и инструментов OpenTelemetry JavaScript.

Особенность Поддержка
Автоматические инструменты Да
Трассировки Да
Метрики Да
Логи Нет

Предустановка

  • Ключ-АСТРОМ версии 1.222+
  • Для трассировки включен контекст трассировки W3C.
    1. Перейдите в Настройки > Предпочтения > Функции ЕдиногоАгента.
    2. Включите опцию Отправлять HTTP-заголовки контекста трассировки W3C.

Получение данных для доступа к Ключ-АСТРОМ

Определение базового URL API

Подробную информацию о сборке базового URL-адреса конечной точки OTLP см. в разделе Экспорт с помощью OTLP. URL-адрес должен заканчиваться на /api/v2/otlp.

Получение токена доступа API

Токен доступа для сбора трассировок, логов и метрик можно создать в разделе Токены доступа.

Экспорт с помощью OTLP содержит более подробную информацию о формате и необходимых областях доступа.

Инициализирование OpenTelemetry

1. Выполните следующую команду npm, чтобы установить необходимые библиотеки и зависимости.

npm install \

  @opentelemetry/api \

  @opentelemetry/exporter-metrics-otlp-proto \

  @opentelemetry/exporter-trace-otlp-proto \

  @opentelemetry/instrumentation \

  @opentelemetry/resources \

  @opentelemetry/sdk-metrics \

  @opentelemetry/sdk-trace-node \

  @opentelemetry/semantic-conventions

В зависимости от используемых вашим приложением библиотек могут также потребоваться дополнительные библиотеки поддержки инструментирования, которые вы захотите добавить в зависимости. Список библиотек поддержки можно найти здесь. Примерами типичных библиотек HTTP и сетевых библиотек являются @opentelemetry/instrumentation-http и @opentelemetry/instrumentation-net.

2. Создайте файл с именем otel.js в директории вашего приложения и сохраните следующее содержимое.

const opentelemetry = require("@opentelemetry/api");

const { resourceFromAttributes, emptyResource, defaultResource } = require("@opentelemetry/resources");

const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } = require("@opentelemetry/semantic-conventions");

const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");

const { registerInstrumentations } = require("@opentelemetry/instrumentation");

const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base");

const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-proto");

const { OTLPMetricExporter } = require("@opentelemetry/exporter-metrics-otlp-proto");

const { MeterProvider, PeriodicExportingMetricReader, AggregationTemporality } = require('@opentelemetry/sdk-metrics');

const DT_API_URL = ''; // TODO: Provide your SaaS/Managed URL here

const DT_API_TOKEN = ''; // TODO: Provide the OpenTelemetry-scoped access token here

// ===== GENERAL SETUP =====

registerInstrumentations({

  instrumentations: [ /* TODO Register your auto-instrumentation libraries here */ ],

});

const fs = require("fs");

let dtmetadata = emptyResource();

for (let name of ['dt_metadata_e617c525669e072eebe3d0f08212e8f2.json', '/var/lib/dynatrace/enrichment/dt_metadata.json', '/var/lib/dynatrace/enrichment/dt_host_metadata.json']) {

  try {

    dtmetadata = dtmetadata.merge(

      resourceFromAttributes(JSON.parse(fs.readFileSync(name.startsWith("/var") ?

        name : fs.readFileSync(name).toString('utf-8').trim()).toString('utf-8'))));

    break

  } catch { }

}

const resource =

  defaultResource().merge(

    resourceFromAttributes({

      [ATTR_SERVICE_NAME]: "js-agent",

      [ATTR_SERVICE_VERSION]: "0.1.0",

    })

  ).merge(dtmetadata);

// ===== TRACING SETUP =====

const exporter = new OTLPTraceExporter({

    url: DT_API_URL + '/v1/traces',

    headers: { Authorization: 'Api-Token ' + DT_API_TOKEN }

});

const processor = new BatchSpanProcessor(exporter);

const provider = new NodeTracerProvider({

    resource: resource,

    spanProcessors: [ processor ]

});

provider.register();

// ===== METRIC SETUP =====

const metricExporter = new OTLPMetricExporter({

    url: DT_API_URL + '/v1/metrics',

    headers: { Authorization: 'Api-Token ' + DT_API_TOKEN },

    temporalityPreference: AggregationTemporality.DELTA

});

const metricReader = new PeriodicExportingMetricReader({

    exporter: metricExporter,

    exportIntervalMillis: 3000

});

const meterProvider = new MeterProvider({

    resource: resource,

    readers: [ metricReader ]

});

// Set this MeterProvider to be global to the app being instrumented.

opentelemetry.metrics.setGlobalMeterProvider(meterProvider);

Расширение данных Ключ-АСТРОМ

Операции чтения файлов, анализирующие файлы dt_metadata в примере кода, пытаются прочитать файлы данных ЕдиногоАгента, чтобы расширить запрос OTLP и гарантировать, что вся соответствующая информация о топологии доступна в Ключ-АСТРОМ.

3. Если вы экспортируете с помощью OTLP, настройте две переменные DT_API_URL и DT_API_TOKENс их соответствующими значениями otel.js.

4. Измените вызов Node.js для вашего приложения, включив параметр командной строки –require и указав его на otel.js.

node --require ./otel.js ./myapplication.js

Инструментирование приложения вручную

Добавление трассировки

1. Получите ссылку на API OpenTelemetry.

const opentelemetry = require("@opentelemetry/api");

2. Теперь мы можем получить объект трассировки.

const tracer = opentelemetry.trace.getTracer('my-tracer');

3. С помощью tracer, мы можем использовать конструктор интервалов для создания и запуска новых интервалов.

const span = tracer.startSpan('Call to /myendpoint');

span.setAttribute('http.method', 'GET');

span.setAttribute('net.protocol.version','1.1');

// TODO your code goes here

span.end();

В приведенном выше коде мы:

  • Создали новый диапазон и назвали его «Call to /myendpoint».
  • Добавили два атрибута, следуя семантическому соглашению об именовании, специфичные для действия этого диапазона: информацию о методе HTTP и версии.
  • Добавили TODO вместо конечной бизнес-логики
  • Вызвали метод span end() для завершения span.

Сбор метрик

1. Как и в случае с трассировкой, нам сначала нужно получить ссылку на API OpenTelemetry.

const opentelemetry = require("@opentelemetry/api");

2. Далее нам необходимо получить объект метрики.

const meter = opentelemetry.metrics.getMeter('my-meter');

3. С помощью meter мы теперь можем создавать отдельные инструменты, например, метрики.

const requestCounter = meter.createCounter('request_counter', {

  description: 'The number of requests we received'

});

4. Теперь мы можем вызвать метод add() для записи новых значений requestCounter с помощью метрики и сохранения дополнительных атрибутов (например, action.type).

requestCounter.add(1, { 'action.type': 'create' });

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

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

const gauge = meter.createObservableGauge('free_memory');

gauge.addCallback(r => {

    r.observe(require('os').freemem());

});

Подключение логов

Примера пока нет, поскольку OpenTelemetry для Node.js пока не имеет стабильной поддержки логов.

В зависимости от статуса OpenTelemetry SDK предварительная версия может уже разрешать прием ваших логов.

Обеспечение распространения контекста (необязательно)

Распространение контекста особенно важно, когда задействованы сетевые вызовы (например, REST).

Если вы используете автоматическое инструментирование и ваши сетевые библиотеки также им охватываются, то это будет автоматически реализовано библиотеками инструментирования. В противном случае ваш код должен это учитывать.

Извлечение контекста при получении запроса

В следующих примерах предполагается, что мы получили сетевой вызов через ClientRequest и используем extract() для создания объекта контекста remoteCtx на основе контекстной информации, полученной из HTTP-заголовков. Это позволяет нам продолжить предыдущую трассировку с нашими интервалами. 

Внедрение контекста при отправке запросов

В следующем примере мы используем HTTP-клиент axios для отправки REST-запроса другой службе и предоставляем наш существующий контекст как часть HTTP-заголовков нашего запроса.

Для этого мы создаём объект ctx, передаём ему текущий диапазон и помечаем его как активный. Затем мы передаём этот объект контекста и пустой объект my_headers в inject(), и после возврата вызова в находятся соответствующие заголовки my_headers, которые мы можем в конечном итоге передать в наш HTTP-вызов.

const ctx = opentelemetry.trace.setSpan(

    opentelemetry.context.active(),

    serverSpan

);

const my_headers = {};

opentelemetry.propagation.inject(ctx, my_headers);

await axios.get(URL, {headers: my_headers});

serverSpan.end();

Настройте сбор данных в соответствии с требованиями конфиденциальности (необязательно)

Хотя Ключ-АСТРОМ автоматически собирает все атрибуты OpenTelemetry, в веб-интерфейсе Ключ-АСТРОМ сохраняются и отображаются только значения атрибутов, указанные в списке разрешенных. Это предотвращает случайное сохранение персональных данных, позволяя вам соблюдать требования к конфиденциальности и контролировать объем хранимых данных мониторинга.

Чтобы просматривать пользовательские атрибуты, необходимо сначала разрешить их использование в веб-интерфейсе Ключ-АСТРОМ.

Проверка загрузки данных в Ключ-АСТРОМ

После завершения инструментирования вашего приложения выполните несколько тестовых действий для создания и отправки демонстрационных трассировок, метрик и логов, а также проверьте, что они были правильно загружены в Ключ-АСТРОМ.

Чтобы сделать это для трассировок, перейдите в раздел Трассировки и выберите вкладку Распределенные трассировки. Если вы используете ЕдиныйАгент, выберите PurePaths .

Для просмотра метрик и логов перейдите в раздел Метрики или Логов или Логи и события.