# Node.js

> Отримайте телеметрію для вашого застосунку менш ніж за 5 хвилин!

---

LLMS index: [llms.txt](/llms.txt)

---

Ця сторінка покаже вам, як почати роботу з OpenTelemetry у Node.js.

Ви дізнаєтеся, як інструментувати як [трейси][], так і [метрики][] та як логувати їх у консоль.

> [!NOTE]
>
> Бібліотека логування OpenTelemetry для Node.js все ще знаходиться в розробці, тому приклад для неї не надається нижче. Докладні відомості про статус див. у розділі [Статус і релізи](/docs/languages/js/#status-and-releases).

## Попередні вимоги {#prerequisites}

Переконайтеся, що у вас встановлено наступне локально:

- [Node.js](https://nodejs.org/en/download/)
- [TypeScript](https://www.typescriptlang.org/download), якщо ви будете використовувати TypeScript.

## Приклад застосунку {#example-application}

Наступний приклад використовує базовий застосунок [Express](https://expressjs.com/). Якщо ви не використовуєте Express, це нормально — ви можете використовувати OpenTelemetry JavaScript з іншими веб-фреймворками, такими як Koa та Nest.JS. Для повного списку бібліотек для підтримуваних фреймворків дивіться [реєстр](/ecosystem/registry/?component=instrumentation&language=js).

Для складніших прикладів дивіться [приклади](/docs/languages/js/examples/).

### Залежності {#dependencies}

Для початку створіть порожній `package.json` у новій теці:

```shell
npm init -y
```

Далі встановіть залежності Express.

   <ul class="nav nav-tabs" id="tabs-0" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-00-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-00-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-00-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-00-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-0-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-00-00" role="tabpanel" aria-labelled-by="tabs-00-00-tab" tabindex="0">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">npm install express @types/express
</span></span><span class="line"><span class="cl">npm install -D tsx  <span class="c1"># інструмент для безпосереднього запуску файлів TypeScript (.ts) за допомогою node</span>
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-00-01" role="tabpanel" aria-labelled-by="tabs-00-01-tab" tabindex="0">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">npm install express
</span></span></code></pre></div>
    </div>
</div>


### Створення та запуск HTTP сервера {#create-and-launch-an-http-server}

Створіть файл з назвою `app.ts` (або `app.js`, якщо не використовуєте TypeScript) та додайте до нього наступний код:

   <ul class="nav nav-tabs" id="tabs-1" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-01-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-01-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-01-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-01-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-01-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-01-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-1-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-01-00" role="tabpanel" aria-labelled-by="tabs-01-00-tab" tabindex="1">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="cm">/*app.ts*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">express</span><span class="p">,</span> <span class="p">{</span> <span class="nx">Express</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;express&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">PORT</span>: <span class="kt">number</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">PORT</span> <span class="o">||</span> <span class="s1">&#39;8080&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">app</span>: <span class="kt">Express</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">getRandomNumber</span><span class="p">(</span><span class="nx">min</span>: <span class="kt">number</span><span class="p">,</span> <span class="nx">max</span>: <span class="kt">number</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="p">(</span><span class="nx">max</span> <span class="o">-</span> <span class="nx">min</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="nx">min</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="s1">&#39;/rolldice&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">getRandomNumber</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">6</span><span class="p">).</span><span class="nx">toString</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">PORT</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`Слухаємо запити на http://localhost:</span><span class="si">${</span><span class="nx">PORT</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-01-01" role="tabpanel" aria-labelled-by="tabs-01-01-tab" tabindex="1">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/*app.js*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">PORT</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">PORT</span> <span class="o">||</span> <span class="s1">&#39;8080&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">getRandomNumber</span><span class="p">(</span><span class="nx">min</span><span class="p">,</span> <span class="nx">max</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="p">(</span><span class="nx">max</span> <span class="o">-</span> <span class="nx">min</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="nx">min</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/rolldice&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">getRandomNumber</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">6</span><span class="p">).</span><span class="nx">toString</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">PORT</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`Слухаємо запити на http://localhost:</span><span class="si">${</span><span class="nx">PORT</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div>
    </div>
</div>


(Примітка: Якщо ваш застосунок написаний на JavaScript як ECMAScript Modules (ESM) або скомпільований у ESM з TypeScript, тоді для правильного підтримання інструментування потрібен хук завантажувача. Використовуйте `node --experimental-loader=@opentelemetry/instrumentation/hook.mjs --require ./instrumentation.js app.js`. Детальніше див. у [документації щодо підтримки ESM](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md).)

Запустіть застосунок за допомогою наступної команди та відкрийте <http://localhost:8080/rolldice> у вашому вебоглядачі, щоб переконатися, що він працює.

   <ul class="nav nav-tabs" id="tabs-2" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-02-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-02-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-02-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-02-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-2-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-02-00" role="tabpanel" aria-labelled-by="tabs-02-00-tab" tabindex="2">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">$</span> npx tsx app.ts
</span></span><span class="line"><span class="cl"><span class="go">Слухаємо запити на http://localhost:8080
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-02-01" role="tabpanel" aria-labelled-by="tabs-02-01-tab" tabindex="2">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">$</span> node app.js
</span></span><span class="line"><span class="cl"><span class="go">Слухаємо запити на http://localhost:8080
</span></span></span></code></pre></div>
    </div>
</div>


## Інструментування {#instrumentation}

Нижче показано, як встановити, ініціалізувати та запустити застосунок, інструментований за допомогою OpenTelemetry.

### Додаткові залежності {#additional-dependencies}

Спочатку встановіть Node SDK та пакунок автоінструментування.

Node SDK дозволяє ініціалізувати OpenTelemetry з кількома стандартними конфігураціями, які підходять для більшості випадків використання.

Пакунок `auto-instrumentations-node` встановлює бібліотеки інструментування, які автоматично створюватимуть відрізки, що відповідають викликам коду в бібліотеках. У цьому випадку він надає інструментування для Express, дозволяючи демонстраційному застосунку автоматично створювати відрізки для кожного вхідного запиту.

```shell
npm install @opentelemetry/sdk-node \
  @opentelemetry/api \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/sdk-metrics \
  @opentelemetry/sdk-trace-node
```

Щоб знайти всі модулі автоінструментування, ви можете подивитися [реєстр](/ecosystem/registry/?language=js&component=instrumentation).

### Налаштування {#setup}

Налаштування та конфігурація інструментування повинні бути виконані _до_ вашого коду застосунку. Один з інструментів, який часто використовується для цього завдання, це прапорець [--import](https://nodejs.org/api/cli.html#--importmodule).

Створіть файл з назвою `instrumentation.ts` (або `instrumentation.mjs`, якщо не використовуєте TypeScript), який міститиме ваш код налаштування інструментування.

> [!NOTE]
>
> Наступні приклади використання `--import instrumentation.ts` (TypeScript) вимагають Node.js v.20 або новішої версії. Якщо ви використовуєте Node.js v.18, будь ласка, скористайтеся прикладом JavaScript.

   <ul class="nav nav-tabs" id="tabs-3" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-03-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-03-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-03-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-03-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-03-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-03-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-3-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-03-00" role="tabpanel" aria-labelled-by="tabs-03-00-tab" tabindex="3">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="cm">/*instrumentation.ts*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">NodeSDK</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">ConsoleSpanExporter</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/sdk-trace-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">getNodeAutoInstrumentations</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">PeriodicExportingMetricReader</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">ConsoleMetricExporter</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/sdk-metrics&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">traceExporter</span>: <span class="kt">new</span> <span class="nx">ConsoleSpanExporter</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">metricReader</span>: <span class="kt">new</span> <span class="nx">PeriodicExportingMetricReader</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">exporter</span>: <span class="kt">new</span> <span class="nx">ConsoleMetricExporter</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">  <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-03-01" role="tabpanel" aria-labelled-by="tabs-03-01-tab" tabindex="3">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/*instrumentation.mjs*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">NodeSDK</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@opentelemetry/sdk-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">ConsoleSpanExporter</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@opentelemetry/sdk-trace-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">getNodeAutoInstrumentations</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@opentelemetry/auto-instrumentations-node&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">PeriodicExportingMetricReader</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">ConsoleMetricExporter</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@opentelemetry/sdk-metrics&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">sdk</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">NodeSDK</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">traceExporter</span><span class="o">:</span> <span class="k">new</span> <span class="nx">ConsoleSpanExporter</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">metricReader</span><span class="o">:</span> <span class="k">new</span> <span class="nx">PeriodicExportingMetricReader</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">exporter</span><span class="o">:</span> <span class="k">new</span> <span class="nx">ConsoleMetricExporter</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">  <span class="p">}),</span>
</span></span><span class="line"><span class="cl">  <span class="nx">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="nx">getNodeAutoInstrumentations</span><span class="p">()],</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span></code></pre></div>
    </div>
</div>


## Запуск інструментованого застосунку {#run-the-instrumented-application}

Тепер ви можете запустити ваш застосунок, як зазвичай, але ви можете використовувати прапорець `--import`, щоб завантажити інструментування перед кодом застосунку. Переконайтеся, що у вас немає інших прапорців `--import` або `--require`, що викликають конфлікти, таких як `--require @opentelemetry/auto-instrumentations-node/register` у вашій змінній середовища `NODE_OPTIONS`.

   <ul class="nav nav-tabs" id="tabs-4" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-04-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-04-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-04-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-04-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-04-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-04-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-4-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-04-00" role="tabpanel" aria-labelled-by="tabs-04-00-tab" tabindex="4">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">$</span> npx tsx --import ./instrumentation.ts app.ts
</span></span><span class="line"><span class="cl"><span class="go">Слухаємо запити на http://localhost:8080
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-04-01" role="tabpanel" aria-labelled-by="tabs-04-01-tab" tabindex="4">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">$</span> node --import ./instrumentation.mjs app.js
</span></span><span class="line"><span class="cl"><span class="go">Слухаємо запити на http://localhost:8080
</span></span></span></code></pre></div>
    </div>
</div>


Відкрийте <http://localhost:8080/rolldice> у вашому вебоглядачі та перезавантажте сторінку кілька разів. Через деякий час ви повинні побачити відрізки, надруковані в консолі за допомогою `ConsoleSpanExporter`.

<details>
<summary>Переглянути приклад виводу</summary>

```js
{
  resource: {
    attributes: {
      'host.arch': 'arm64',
      'host.id': '8FEBBC33-D6DA-57FC-8EF0-1A9C14B919F8',
      'process.pid': 12460,
      // ... some resource attributes elided ...
      'process.runtime.version': '22.17.1',
      'process.runtime.name': 'nodejs',
      'process.runtime.description': 'Node.js',
      'telemetry.sdk.language': 'nodejs',
      'telemetry.sdk.name': 'opentelemetry',
      'telemetry.sdk.version': '2.0.1'
    }
  },
  instrumentationScope: {
    name: '@opentelemetry/instrumentation-express',
    version: '0.52.0',
    schemaUrl: undefined
  },
  traceId: '61e8960c349ca2a3a51289e050fd3b82',
  parentSpanContext: {
    traceId: '61e8960c349ca2a3a51289e050fd3b82',
    spanId: '631b666604f933bc',
    traceFlags: 1,
    traceState: undefined
  },
  traceState: undefined,
  name: 'request handler - /rolldice',
  id: 'd8fcc05ac4f60c99',
  kind: 0,
  timestamp: 1755719307779000,
  duration: 2801.5,
  attributes: {
    'http.route': '/rolldice',
    'express.name': '/rolldice',
    'express.type': 'request_handler'
  },
  status: { code: 0 },
  events: [],
  links: []
}
{
  resource: {
    attributes: {
      'host.arch': 'arm64',
      'host.id': '8FEBBC33-D6DA-57FC-8EF0-1A9C14B919F8',
      'process.pid': 12460,
      // ... some resource attributes elided ...
      'process.runtime.version': '22.17.1',
      'process.runtime.name': 'nodejs',
      'process.runtime.description': 'Node.js',
      'telemetry.sdk.language': 'nodejs',
      'telemetry.sdk.name': 'opentelemetry',
      'telemetry.sdk.version': '2.0.1'
    }
  },
  instrumentationScope: {
    name: '@opentelemetry/instrumentation-http',
    version: '0.203.0',
    schemaUrl: undefined
  },
  traceId: '61e8960c349ca2a3a51289e050fd3b82',
  parentSpanContext: undefined,
  traceState: undefined,
  name: 'GET /rolldice',
  id: '631b666604f933bc',
  kind: 1,
  timestamp: 1755719307777000,
  duration: 4705.75,
  attributes: {
    'http.url': 'http://localhost:8080/rolldice',
    'http.host': 'localhost:8080',
    'net.host.name': 'localhost',
    'http.method': 'GET',
    'http.scheme': 'http',
    'http.target': '/rolldice',
    'http.user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:141.0) Gecko/20100101 Firefox/141.0',
    'http.flavor': '1.1',
    'net.transport': 'ip_tcp',
    'net.host.ip': '::ffff:127.0.0.1',
    'net.host.port': 8080,
    'net.peer.ip': '::ffff:127.0.0.1',
    'net.peer.port': 63067,
    'http.status_code': 200,
    'http.status_text': 'OK',
    'http.route': '/rolldice'
  },
  status: { code: 0 },
  events: [],
  links: []
}
```

</details>

Згенерований відрізок відстежує тривалість запиту до маршруту `/rolldice`.

Надішліть ще кілька запитів до точки доступу. Через деякий час ви побачите метрики у виводі консолі, такі як наступні:

<details>
<summary>Переглянути приклад виводу</summary>

```yaml
{
  descriptor: {
    name: 'http.server.duration',
    type: 'HISTOGRAM',
    description: 'Вимірює тривалість вхідних HTTP-запитів.',
    unit: 'ms',
    valueType: 1,
    advice: {}
  },
  dataPointType: 0,
  dataPoints: [
    {
      attributes: {
        'http.scheme': 'http',
        'http.method': 'GET',
        'net.host.name': 'localhost',
        'http.flavor': '1.1',
        'http.status_code': 200,
        'net.host.port': 8080,
        'http.route': '/rolldice'
      },
      startTime: [ 1755719307, 782000000 ],
      endTime: [ 1755719482, 940000000 ],
      value: {
        min: 1.439792,
        max: 5.775,
        sum: 15.370167,
        buckets: {
          boundaries: [
               0,    5,    10,   25,
              50,   75,   100,  250,
             500,  750,  1000, 2500,
            5000, 7500, 10000
          ],
          counts: [
            0, 5, 1, 0, 0, 0,
            0, 0, 0, 0, 0, 0,
            0, 0, 0, 0
          ]
        },
        count: 6
      }
    },
    {
      attributes: {
        'http.scheme': 'http',
        'http.method': 'GET',
        'net.host.name': 'localhost',
        'http.flavor': '1.1',
        'http.status_code': 304,
        'net.host.port': 8080,
        'http.route': '/rolldice'
      },
      startTime: [ 1755719433, 609000000 ],
      endTime: [ 1755719482, 940000000 ],
      value: {
        min: 1.39575,
        max: 1.39575,
        sum: 1.39575,
        buckets: {
          boundaries: [
               0,    5,    10,   25,
              50,   75,   100,  250,
             500,  750,  1000, 2500,
            5000, 7500, 10000
          ],
          counts: [
            0, 1, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0,
            0, 0, 0, 0
          ]
        },
        count: 1
      }
    }
  ]
}
{
  descriptor: {
    name: 'nodejs.eventloop.utilization',
    type: 'OBSERVABLE_GAUGE',
    description: 'Використання циклу подій',
    unit: '1',
    valueType: 1,
    advice: {}
  },
  dataPointType: 2,
  dataPoints: [
    {
      attributes: {},
      startTime: [ 1755719362, 939000000 ],
      endTime: [ 1755719482, 940000000 ],
      value: 0.00843049454565211
    }
  ]
}
{
  descriptor: {
    name: 'v8js.gc.duration',
    type: 'HISTOGRAM',
    description: 'Вимірює тривалість збору сміття за типом, один з major, minor, incremental або weakcb.',
    unit: 's',
    valueType: 1,
    advice: { explicitBucketBoundaries: [ 0.01, 0.1, 1, 10 ] }
  },
  dataPointType: 0,
  dataPoints: [
    {
      attributes: { 'v8js.gc.type': 'minor' },
      startTime: [ 1755719303, 5000000 ],
      endTime: [ 1755719482, 940000000 ],
      value: {
        min: 0.0005120840072631835,
        max: 0.0022552499771118163,
        sum: 0.006526499509811401,
        buckets: { boundaries: [ 0.01, 0.1, 1, 10 ], counts: [ 6, 0, 0, 0, 0 ] },
        count: 6
      }
    },
    {
      attributes: { 'v8js.gc.type': 'incremental' },
      startTime: [ 1755719310, 812000000 ],
      endTime: [ 1755719482, 940000000 ],
      value: {
        min: 0.0003403329849243164,
        max: 0.0012867081165313721,
        sum: 0.0016270411014556885,
        buckets: { boundaries: [ 0.01, 0.1, 1, 10 ], counts: [ 2, 0, 0, 0, 0 ] },
        count: 2
      }
    },
    {
      attributes: { 'v8js.gc.type': 'major' },
      startTime: [ 1755719310, 830000000 ],
      endTime: [ 1755719482, 940000000 ],
      value: {
        min: 0.0025888750553131105,
        max: 0.005744750022888183,
        sum: 0.008333625078201293,
        buckets: { boundaries: [ 0.01, 0.1, 1, 10 ], counts: [ 2, 0, 0, 0, 0 ] },
        count: 2
      }
    }
  ]
}
```

</details>

## Наступні кроки {#next-steps}

Збагачуйте ваше інструментування, згенероване автоматично, [ручним інструментуванням](/docs/languages/js/instrumentation) вашого власного коду. Це дозволить вам отримати налаштовані дані спостереження.

Вам також потрібно буде налаштувати відповідний експортер для [експорту ваших телеметричних даних](/docs/languages/js/exporters) до одного або кількох бекендів телеметрії.

Якщо ви хочете дослідити складніший приклад, подивіться на [Демо OpenTelemetry](/docs/demo/), яке включає основану на JavaScript [службу оплати](/docs/demo/services/payment/) та основану на TypeScript [службу фронтенду](/docs/demo/services/frontend/).

## Розвʼязання проблем {#troubleshooting}

Щось пішло не так? Ви можете увімкнути діагностичне логування, щоб перевірити, чи OpenTelemetry ініціалізовано правильно:

   <ul class="nav nav-tabs" id="tabs-5" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-05-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-05-00" role="tab"
          data-td-tp-persist="typescript" aria-controls="tabs-05-00" aria-selected="true">
        TypeScript
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-05-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-05-01" role="tab"
          data-td-tp-persist="javascript" aria-controls="tabs-05-01" aria-selected="false">
        JavaScript
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-5-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-05-00" role="tabpanel" aria-labelled-by="tabs-05-00-tab" tabindex="5">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="cm">/*instrumentation.ts*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">diag</span><span class="p">,</span> <span class="nx">DiagConsoleLogger</span><span class="p">,</span> <span class="nx">DiagLogLevel</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/api&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Для розвʼязання проблем встановіть рівень логування на DiagLogLevel.DEBUG
</span></span></span><span class="line"><span class="cl"><span class="nx">diag</span><span class="p">.</span><span class="nx">setLogger</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiagConsoleLogger</span><span class="p">(),</span> <span class="nx">DiagLogLevel</span><span class="p">.</span><span class="nx">INFO</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// const sdk = new NodeSDK({...
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-05-01" role="tabpanel" aria-labelled-by="tabs-05-01-tab" tabindex="5">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/*instrumentation.mjs*/</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">diag</span><span class="p">,</span> <span class="nx">DiagConsoleLogger</span><span class="p">,</span> <span class="nx">DiagLogLevel</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@opentelemetry/api&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Для розвʼязання проблем встановіть рівень логування на DiagLogLevel.DEBUG
</span></span></span><span class="line"><span class="cl"><span class="nx">diag</span><span class="p">.</span><span class="nx">setLogger</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiagConsoleLogger</span><span class="p">(),</span> <span class="nx">DiagLogLevel</span><span class="p">.</span><span class="nx">INFO</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// const sdk = new NodeSDK({...
</span></span></span></code></pre></div>
    </div>
</div>



> [!NOTE]
>
> У документації OpenTelemetry передбачається, що скомпільований застосунок працює у форматі [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs-modules). Якщо застосунок працює як ESM, додайте хук завантажувача, як зазначено в [документації щодо підтримки ESM](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md).
{{__hugo_ctx/}}


[трейси]: /docs/concepts/signals/traces/
[метрики]: /docs/concepts/signals/metrics/
