<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://doc.ruscomtech.ru/index.php?action=history&amp;feed=atom&amp;title=JavaScript_%28Node.js%29_OpenTelemetry</id>
	<title>JavaScript (Node.js) OpenTelemetry - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://doc.ruscomtech.ru/index.php?action=history&amp;feed=atom&amp;title=JavaScript_%28Node.js%29_OpenTelemetry"/>
	<link rel="alternate" type="text/html" href="https://doc.ruscomtech.ru/index.php?title=JavaScript_(Node.js)_OpenTelemetry&amp;action=history"/>
	<updated>2026-09-16T12:37:22Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://doc.ruscomtech.ru/index.php?title=JavaScript_(Node.js)_OpenTelemetry&amp;diff=5868&amp;oldid=prev</id>
		<title>IKuznetsov в 15:20, 16 октября 2025</title>
		<link rel="alternate" type="text/html" href="https://doc.ruscomtech.ru/index.php?title=JavaScript_(Node.js)_OpenTelemetry&amp;diff=5868&amp;oldid=prev"/>
		<updated>2025-10-16T15:20:08Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Предыдущая версия&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Версия от 15:20, 16 октября 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l93&quot;&gt;Строка 93:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 93:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;let dtmetadata = emptyResource();&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;let dtmetadata = emptyResource();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;for (let name of [&#039;dt_metadata_e617c525669e072eebe3d0f08212e8f2.json&#039;, &#039;/var/lib/&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;dynatrace&lt;/del&gt;/enrichment/dt_metadata.json&#039;, &#039;/var/lib/&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;dynatrace&lt;/del&gt;/enrichment/dt_host_metadata.json&#039;]) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;for (let name of [&#039;dt_metadata_e617c525669e072eebe3d0f08212e8f2.json&#039;, &#039;/var/lib/&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;astromkey&lt;/ins&gt;/enrichment/dt_metadata.json&#039;, &#039;/var/lib/&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;astromkey&lt;/ins&gt;/enrichment/dt_host_metadata.json&#039;]) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  try {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  try {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key ka_db:diff:1.41:old-5865:rev-5868:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>IKuznetsov</name></author>
	</entry>
	<entry>
		<id>https://doc.ruscomtech.ru/index.php?title=JavaScript_(Node.js)_OpenTelemetry&amp;diff=5865&amp;oldid=prev</id>
		<title>IKuznetsov: Новая страница: «В этом пошаговом руководстве показано, как добавить наблюдаемость в ваше &#039;&#039;&#039;JavaScript&#039;&#039;&#039;-&#039;&#039;&#039;при...»</title>
		<link rel="alternate" type="text/html" href="https://doc.ruscomtech.ru/index.php?title=JavaScript_(Node.js)_OpenTelemetry&amp;diff=5865&amp;oldid=prev"/>
		<updated>2025-10-16T14:35:27Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «В этом пошаговом руководстве показано, как добавить наблюдаемость в ваше &amp;#039;&amp;#039;&amp;#039;JavaScript&amp;#039;&amp;#039;&amp;#039;-&amp;#039;&amp;#039;&amp;#039;при...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;В этом пошаговом руководстве показано, как добавить наблюдаемость в ваше &amp;#039;&amp;#039;&amp;#039;JavaScript&amp;#039;&amp;#039;&amp;#039;-&amp;#039;&amp;#039;&amp;#039;приложение&amp;#039;&amp;#039;&amp;#039; с помощью библиотек и инструментов &amp;#039;&amp;#039;&amp;#039;OpenTelemetry&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;JavaScript&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Особенность&lt;br /&gt;
!Поддержка&lt;br /&gt;
|-&lt;br /&gt;
|Автоматические инструменты&lt;br /&gt;
|Да&lt;br /&gt;
|-&lt;br /&gt;
|Трассировки&lt;br /&gt;
|Да&lt;br /&gt;
|-&lt;br /&gt;
|Метрики&lt;br /&gt;
|Да&lt;br /&gt;
|-&lt;br /&gt;
|Логи&lt;br /&gt;
|Нет&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Предустановка ==&lt;br /&gt;
&lt;br /&gt;
* Ключ-АСТРОМ версии &amp;#039;&amp;#039;&amp;#039;1.222+&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Для трассировки включен контекст трассировки &amp;#039;&amp;#039;&amp;#039;W3C&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
*# Перейдите в &amp;#039;&amp;#039;&amp;#039;Настройки &amp;gt; Предпочтения &amp;gt; Функции ЕдиногоАгента.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
*# Включите опцию &amp;#039;&amp;#039;&amp;#039;Отправлять HTTP-заголовки контекста трассировки W3C&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Получение данных для доступа к Ключ-АСТРОМ ==&lt;br /&gt;
&lt;br /&gt;
=== Определение базового URL API ===&lt;br /&gt;
Подробную информацию о сборке базового &amp;#039;&amp;#039;&amp;#039;URL-адреса&amp;#039;&amp;#039;&amp;#039; конечной точки &amp;#039;&amp;#039;&amp;#039;OTLP&amp;#039;&amp;#039;&amp;#039; см. в разделе [[Экспорт с помощью OTLP]]. &amp;#039;&amp;#039;&amp;#039;URL-адрес&amp;#039;&amp;#039;&amp;#039; должен заканчиваться на &amp;lt;code&amp;gt;/api/v2/otlp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Получение токена доступа API ===&lt;br /&gt;
Токен доступа для сбора трассировок, логов и метрик можно создать в разделе [[Токен доступа|Токены доступа]].&lt;br /&gt;
&lt;br /&gt;
Экспорт с помощью &amp;#039;&amp;#039;&amp;#039;OTLP&amp;#039;&amp;#039;&amp;#039; содержит более подробную информацию о формате и необходимых областях доступа.&lt;br /&gt;
&lt;br /&gt;
== Инициализирование OpenTelemetry ==&lt;br /&gt;
1. Выполните следующую команду &amp;lt;code&amp;gt;npm&amp;lt;/code&amp;gt;, чтобы установить необходимые библиотеки и зависимости.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|npm install \&lt;br /&gt;
&lt;br /&gt;
  @opentelemetry/api \&lt;br /&gt;
&lt;br /&gt;
  @opentelemetry/exporter-metrics-otlp-proto \&lt;br /&gt;
&lt;br /&gt;
  @opentelemetry/exporter-trace-otlp-proto \&lt;br /&gt;
&lt;br /&gt;
  @opentelemetry/instrumentation \&lt;br /&gt;
&lt;br /&gt;
  @opentelemetry/resources \&lt;br /&gt;
&lt;br /&gt;
  @opentelemetry/sdk-metrics \&lt;br /&gt;
&lt;br /&gt;
  @opentelemetry/sdk-trace-node \&lt;br /&gt;
&lt;br /&gt;
  @opentelemetry/semantic-conventions&lt;br /&gt;
|}&lt;br /&gt;
В зависимости от используемых вашим приложением библиотек могут также потребоваться дополнительные библиотеки поддержки инструментирования, которые вы захотите добавить в зависимости. Список библиотек поддержки можно найти [https://www.npmjs.com/search?q=%40opentelemetry%2Finstrumentation здесь]﻿. Примерами типичных библиотек &amp;#039;&amp;#039;&amp;#039;HTTP&amp;#039;&amp;#039;&amp;#039; и сетевых библиотек являются [https://www.npmjs.com/package/@opentelemetry/instrumentation-http @opentelemetry/instrumentation-http]﻿ и [https://www.npmjs.com/package/@opentelemetry/instrumentation-net @opentelemetry/instrumentation-net]﻿.&lt;br /&gt;
&lt;br /&gt;
2. Создайте файл с именем &amp;lt;code&amp;gt;otel.js&amp;lt;/code&amp;gt; в директории вашего приложения и сохраните следующее содержимое.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|const opentelemetry = require(&amp;quot;@opentelemetry/api&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
const { resourceFromAttributes, emptyResource, defaultResource } = require(&amp;quot;@opentelemetry/resources&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } = require(&amp;quot;@opentelemetry/semantic-conventions&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
const { NodeTracerProvider } = require(&amp;quot;@opentelemetry/sdk-trace-node&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
const { registerInstrumentations } = require(&amp;quot;@opentelemetry/instrumentation&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
const { BatchSpanProcessor } = require(&amp;quot;@opentelemetry/sdk-trace-base&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
const { OTLPTraceExporter } = require(&amp;quot;@opentelemetry/exporter-trace-otlp-proto&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
const { OTLPMetricExporter } = require(&amp;quot;@opentelemetry/exporter-metrics-otlp-proto&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
const { MeterProvider, PeriodicExportingMetricReader, AggregationTemporality } = require(&amp;#039;@opentelemetry/sdk-metrics&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
const DT_API_URL = &amp;lt;nowiki&amp;gt;&amp;#039;&amp;#039;&amp;lt;/nowiki&amp;gt;; // TODO: Provide your SaaS/Managed URL here&lt;br /&gt;
&lt;br /&gt;
const DT_API_TOKEN = &amp;lt;nowiki&amp;gt;&amp;#039;&amp;#039;&amp;lt;/nowiki&amp;gt;; // TODO: Provide the OpenTelemetry-scoped access token here&lt;br /&gt;
&lt;br /&gt;
// ===== GENERAL SETUP =====&lt;br /&gt;
&lt;br /&gt;
registerInstrumentations({&lt;br /&gt;
&lt;br /&gt;
  instrumentations: [ /* TODO Register your auto-instrumentation libraries here */ ],&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
const fs = require(&amp;quot;fs&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
let dtmetadata = emptyResource();&lt;br /&gt;
&lt;br /&gt;
for (let name of [&amp;#039;dt_metadata_e617c525669e072eebe3d0f08212e8f2.json&amp;#039;, &amp;#039;/var/lib/dynatrace/enrichment/dt_metadata.json&amp;#039;, &amp;#039;/var/lib/dynatrace/enrichment/dt_host_metadata.json&amp;#039;]) {&lt;br /&gt;
&lt;br /&gt;
  try {&lt;br /&gt;
&lt;br /&gt;
    dtmetadata = dtmetadata.merge(&lt;br /&gt;
&lt;br /&gt;
      resourceFromAttributes(JSON.parse(fs.readFileSync(name.startsWith(&amp;quot;/var&amp;quot;) ?&lt;br /&gt;
&lt;br /&gt;
        name : fs.readFileSync(name).toString(&amp;#039;utf-8&amp;#039;).trim()).toString(&amp;#039;utf-8&amp;#039;))));&lt;br /&gt;
&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  } catch { }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const resource =&lt;br /&gt;
&lt;br /&gt;
  defaultResource().merge(&lt;br /&gt;
&lt;br /&gt;
    resourceFromAttributes({&lt;br /&gt;
&lt;br /&gt;
      [ATTR_SERVICE_NAME]: &amp;quot;js-agent&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
      [ATTR_SERVICE_VERSION]: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
  ).merge(dtmetadata);&lt;br /&gt;
&lt;br /&gt;
// ===== TRACING SETUP =====&lt;br /&gt;
&lt;br /&gt;
const exporter = new OTLPTraceExporter({&lt;br /&gt;
&lt;br /&gt;
    url: DT_API_URL + &amp;#039;/v1/traces&amp;#039;,&lt;br /&gt;
&lt;br /&gt;
    headers: { Authorization: &amp;#039;Api-Token &amp;#039; + DT_API_TOKEN }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
const processor = new BatchSpanProcessor(exporter);&lt;br /&gt;
&lt;br /&gt;
const provider = new NodeTracerProvider({&lt;br /&gt;
&lt;br /&gt;
    resource: resource,&lt;br /&gt;
&lt;br /&gt;
    spanProcessors: [ processor ]&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
provider.register();&lt;br /&gt;
&lt;br /&gt;
// ===== METRIC SETUP =====&lt;br /&gt;
&lt;br /&gt;
const metricExporter = new OTLPMetricExporter({&lt;br /&gt;
&lt;br /&gt;
    url: DT_API_URL + &amp;#039;/v1/metrics&amp;#039;,&lt;br /&gt;
&lt;br /&gt;
    headers: { Authorization: &amp;#039;Api-Token &amp;#039; + DT_API_TOKEN },&lt;br /&gt;
&lt;br /&gt;
    temporalityPreference: AggregationTemporality.DELTA&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
const metricReader = new PeriodicExportingMetricReader({&lt;br /&gt;
&lt;br /&gt;
    exporter: metricExporter,&lt;br /&gt;
&lt;br /&gt;
    exportIntervalMillis: 3000&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
const meterProvider = new MeterProvider({&lt;br /&gt;
&lt;br /&gt;
    resource: resource,&lt;br /&gt;
&lt;br /&gt;
    readers: [ metricReader ]&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Set this MeterProvider to be global to the app being instrumented.&lt;br /&gt;
&lt;br /&gt;
opentelemetry.metrics.setGlobalMeterProvider(meterProvider);&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;u&amp;gt;Расширение данных Ключ-АСТРОМ&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Операции чтения файлов, анализирующие файлы &amp;lt;code&amp;gt;dt_metadata&amp;lt;/code&amp;gt; в примере кода, пытаются прочитать файлы данных ЕдиногоАгента, чтобы расширить запрос &amp;#039;&amp;#039;&amp;#039;OTLP&amp;#039;&amp;#039;&amp;#039; и гарантировать, что вся соответствующая информация о топологии доступна в Ключ-АСТРОМ.&lt;br /&gt;
&lt;br /&gt;
3. Если вы экспортируете с помощью &amp;#039;&amp;#039;&amp;#039;OTLP&amp;#039;&amp;#039;&amp;#039;, настройте две переменные &amp;lt;code&amp;gt;DT_API_URL&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;DT_API_TOKEN&amp;lt;/code&amp;gt;с их соответствующими значениями &amp;lt;code&amp;gt;otel.js&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
4. Измените вызов &amp;#039;&amp;#039;&amp;#039;Node.js&amp;#039;&amp;#039;&amp;#039; для вашего приложения, включив параметр командной строки [https://nodejs.org/api/cli.html#-r---require-module –require]﻿ и указав его на &amp;lt;code&amp;gt;otel.js&amp;lt;/code&amp;gt;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|node --require ./otel.js ./myapplication.js&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Инструментирование приложения вручную ==&lt;br /&gt;
&lt;br /&gt;
=== Добавление трассировки ===&lt;br /&gt;
1. Получите ссылку на &amp;#039;&amp;#039;&amp;#039;API OpenTelemetry&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|const opentelemetry = require(&amp;quot;@opentelemetry/api&amp;quot;);&lt;br /&gt;
|}&lt;br /&gt;
2. Теперь мы можем получить объект трассировки.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|const tracer = opentelemetry.trace.getTracer(&amp;#039;my-tracer&amp;#039;);&lt;br /&gt;
|}&lt;br /&gt;
3. С помощью &amp;lt;code&amp;gt;tracer&amp;lt;/code&amp;gt;, мы можем использовать конструктор интервалов для создания и запуска новых интервалов.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|const span = tracer.startSpan(&amp;#039;Call to /myendpoint&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
span.setAttribute(&amp;#039;http.method&amp;#039;, &amp;#039;GET&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
span.setAttribute(&amp;#039;net.protocol.version&amp;#039;,&amp;#039;1.1&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
// TODO your code goes here&lt;br /&gt;
&lt;br /&gt;
span.end();&lt;br /&gt;
|}&lt;br /&gt;
В приведенном выше коде мы:&lt;br /&gt;
&lt;br /&gt;
* Создали новый диапазон и назвали его «&amp;#039;&amp;#039;&amp;#039;Call to /myendpoint&amp;#039;&amp;#039;&amp;#039;».&lt;br /&gt;
* Добавили два атрибута, следуя [https://opentelemetry.io/docs/specs/semconv/general/trace/ семантическому соглашению об именовании]﻿, специфичные для действия этого диапазона: информацию о методе &amp;#039;&amp;#039;&amp;#039;HTTP&amp;#039;&amp;#039;&amp;#039; и версии.&lt;br /&gt;
* Добавили &amp;lt;code&amp;gt;TODO&amp;lt;/code&amp;gt; вместо конечной бизнес-логики&lt;br /&gt;
* Вызвали метод span &amp;lt;code&amp;gt;end()&amp;lt;/code&amp;gt; для завершения span.&lt;br /&gt;
&lt;br /&gt;
=== Сбор метрик ===&lt;br /&gt;
1. Как и в случае с трассировкой, нам сначала нужно получить ссылку на &amp;#039;&amp;#039;&amp;#039;API OpenTelemetry&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|const opentelemetry = require(&amp;quot;@opentelemetry/api&amp;quot;);&lt;br /&gt;
|}&lt;br /&gt;
2. Далее нам необходимо получить объект метрики.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|const meter = opentelemetry.metrics.getMeter(&amp;#039;my-meter&amp;#039;);&lt;br /&gt;
|}&lt;br /&gt;
3. С помощью &amp;lt;code&amp;gt;meter&amp;lt;/code&amp;gt; мы теперь можем создавать отдельные инструменты, например, метрики.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|const requestCounter = meter.createCounter(&amp;#039;request_counter&amp;#039;, {&lt;br /&gt;
&lt;br /&gt;
  description: &amp;#039;The number of requests we received&amp;#039;&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
|}&lt;br /&gt;
4. Теперь мы можем вызвать метод &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; для записи новых значений &amp;lt;code&amp;gt;requestCounter&amp;lt;/code&amp;gt; с помощью метрики и сохранения дополнительных атрибутов (например, &amp;lt;code&amp;gt;action.type&amp;lt;/code&amp;gt;).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|requestCounter.add(1, { &amp;#039;action.type&amp;#039;: &amp;#039;create&amp;#039; });&lt;br /&gt;
|}&lt;br /&gt;
Вы также можете создать асинхронный датчик, для которого потребуется функция обратного вызова, которая будет вызываться &amp;#039;&amp;#039;&amp;#039;OpenTelemetry&amp;#039;&amp;#039;&amp;#039; при сборе данных.&lt;br /&gt;
&lt;br /&gt;
В следующем примере при каждом вызове записывается доступная память:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|const gauge = meter.createObservableGauge(&amp;#039;free_memory&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
gauge.addCallback(r =&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
    r.observe(require(&amp;#039;os&amp;#039;).freemem());&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Подключение логов ===&lt;br /&gt;
Примера пока нет, поскольку &amp;#039;&amp;#039;&amp;#039;OpenTelemetry&amp;#039;&amp;#039;&amp;#039; для &amp;#039;&amp;#039;&amp;#039;Node.js&amp;#039;&amp;#039;&amp;#039; пока не имеет стабильной поддержки логов.&lt;br /&gt;
&lt;br /&gt;
В зависимости от статуса &amp;#039;&amp;#039;&amp;#039;OpenTelemetry SDK&amp;#039;&amp;#039;&amp;#039; предварительная версия может уже разрешать прием ваших логов.&lt;br /&gt;
&lt;br /&gt;
=== Обеспечение распространения контекста (необязательно) ===&lt;br /&gt;
Распространение контекста особенно важно, когда задействованы сетевые вызовы (например, &amp;#039;&amp;#039;&amp;#039;REST&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Если вы используете автоматическое инструментирование и ваши сетевые библиотеки также им охватываются, то это будет автоматически реализовано библиотеками инструментирования. В противном случае ваш код должен это учитывать.&lt;br /&gt;
&lt;br /&gt;
==== Извлечение контекста при получении запроса ====&lt;br /&gt;
В следующих примерах предполагается, что мы получили сетевой вызов через &amp;lt;code&amp;gt;[https://nodejs.org/api/http.html#class-httpclientrequest ClientRequest]&amp;lt;/code&amp;gt; и используем &amp;lt;code&amp;gt;extract()&amp;lt;/code&amp;gt; для создания объекта контекста &amp;lt;code&amp;gt;remoteCtx&amp;lt;/code&amp;gt; на основе контекстной информации, полученной из &amp;#039;&amp;#039;&amp;#039;HTTP-заголовков&amp;#039;&amp;#039;&amp;#039;. Это позволяет нам продолжить предыдущую трассировку с нашими интервалами. ﻿&lt;br /&gt;
&lt;br /&gt;
==== Внедрение контекста при отправке запросов ====&lt;br /&gt;
В следующем примере мы используем &amp;#039;&amp;#039;&amp;#039;HTTP&amp;#039;&amp;#039;&amp;#039;-клиент &amp;#039;&amp;#039;&amp;#039;[https://www.npmjs.com/package/axios axios]&amp;#039;&amp;#039;&amp;#039;﻿ для отправки &amp;#039;&amp;#039;&amp;#039;REST&amp;#039;&amp;#039;&amp;#039;-запроса другой службе и предоставляем наш существующий контекст как часть &amp;#039;&amp;#039;&amp;#039;HTTP&amp;#039;&amp;#039;&amp;#039;-заголовков нашего запроса.&lt;br /&gt;
&lt;br /&gt;
Для этого мы создаём объект &amp;lt;code&amp;gt;ctx&amp;lt;/code&amp;gt;, передаём ему текущий диапазон и помечаем его как активный. Затем мы передаём этот объект контекста и пустой объект &amp;lt;code&amp;gt;my_headers&amp;lt;/code&amp;gt; в &amp;lt;code&amp;gt;inject()&amp;lt;/code&amp;gt;, и после возврата вызова в находятся соответствующие заголовки &amp;lt;code&amp;gt;my_headers&amp;lt;/code&amp;gt;, которые мы можем в конечном итоге передать в наш &amp;#039;&amp;#039;&amp;#039;HTTP&amp;#039;&amp;#039;&amp;#039;-вызов.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|const ctx = opentelemetry.trace.setSpan(&lt;br /&gt;
&lt;br /&gt;
    opentelemetry.context.active(),&lt;br /&gt;
&lt;br /&gt;
    serverSpan&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
const my_headers = {};&lt;br /&gt;
&lt;br /&gt;
opentelemetry.propagation.inject(ctx, my_headers);&lt;br /&gt;
&lt;br /&gt;
await axios.get(URL, {headers: my_headers});&lt;br /&gt;
&lt;br /&gt;
serverSpan.end();&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Настройте сбор данных в соответствии с требованиями конфиденциальности (необязательно) ==&lt;br /&gt;
Хотя Ключ-АСТРОМ автоматически собирает все атрибуты &amp;#039;&amp;#039;&amp;#039;OpenTelemetry&amp;#039;&amp;#039;&amp;#039;, в веб-интерфейсе Ключ-АСТРОМ сохраняются и отображаются только значения атрибутов, указанные в списке разрешенных. Это предотвращает случайное сохранение персональных данных, позволяя вам соблюдать требования к конфиденциальности и контролировать объем хранимых данных мониторинга.&lt;br /&gt;
&lt;br /&gt;
Чтобы просматривать пользовательские атрибуты, необходимо сначала разрешить их использование в веб-интерфейсе Ключ-АСТРОМ.&lt;br /&gt;
&lt;br /&gt;
== Проверка загрузки данных в Ключ-АСТРОМ ==&lt;br /&gt;
После завершения инструментирования вашего приложения выполните несколько тестовых действий для создания и отправки демонстрационных трассировок, метрик и логов, а также проверьте, что они были правильно загружены в Ключ-АСТРОМ.&lt;br /&gt;
&lt;br /&gt;
Чтобы сделать это для трассировок, перейдите в раздел &amp;#039;&amp;#039;&amp;#039;Трассировки&amp;#039;&amp;#039;&amp;#039; и выберите вкладку &amp;#039;&amp;#039;&amp;#039;Распределенные трассировки&amp;#039;&amp;#039;&amp;#039;. Если вы используете ЕдиныйАгент, выберите &amp;#039;&amp;#039;&amp;#039;PurePaths&amp;#039;&amp;#039;&amp;#039; .&lt;br /&gt;
&lt;br /&gt;
Для просмотра метрик и логов перейдите в раздел &amp;#039;&amp;#039;&amp;#039;Метрики&amp;#039;&amp;#039;&amp;#039; или &amp;#039;&amp;#039;&amp;#039;Логов&amp;#039;&amp;#039;&amp;#039; или &amp;#039;&amp;#039;&amp;#039;Логи и события&amp;#039;&amp;#039;&amp;#039;.&lt;/div&gt;</summary>
		<author><name>IKuznetsov</name></author>
	</entry>
</feed>