# Propagação

> Propagação de contexto para o SDK JS

---

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

---

With context propagation, [Signals](/docs/concepts/signals/) can be correlated
with each other, regardless of where they are generated. Although not limited to
tracing, context propagation allows [traces](/docs/concepts/signals/traces/) to
build causal information about a system across services that are arbitrarily
distributed across process and network boundaries.

For the vast majority of use cases, libraries that natively support
OpenTelemetry or [instrumentation libraries](../libraries/) will automatically
propagate trace context across services for you. It is only in rare cases that
you will need to propagate context manually.



To learn more, see [Context propagation](/docs/concepts/context-propagation).








> [!NOTE]
>
> A documentação do OpenTelemetry assume que a aplicação compilada é executada
> como [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs-modules).
> Caso a aplicação seja executada como ESM, adicione o _loader hook_ conforme
> especificado na
> [Documentação de Suporte ao ESM](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md).


## Propagação automática de contexto {#automatic-context-propagation}

[Bibliotecas de instrumentação](../libraries/) como
[`@opentelemetry/instrumentation-http`](https://www.npmjs.com/package/@opentelemetry/instrumentation-http)
ou
[`@opentelemetry/instrumentation-express`](https://www.npmjs.com/package/@opentelemetry/instrumentation-express)
propagam o contexto entre serviços por você.

Se você seguiu o [Guia de Primeiros Passos](../getting-started/nodejs), você
pode criar uma aplicação cliente que consulta o _endpoint_ `/rolldice`.

> [!NOTE]
>
> Você também pode combinar este exemplo com a aplicação de exemplo do guia de
> Primeiros Passos de qualquer outra linguagem. A correlação funciona entre
> aplicações escritas em linguagens diferentes sem nenhuma diferença.

Comece criando uma nova pasta chamada `dice-client` e instale as dependências
necessárias:

   <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-sh" data-lang="sh"><span class="line"><span class="cl">npm init -y
</span></span><span class="line"><span class="cl">npm install undici <span class="se">\
</span></span></span><span class="line"><span class="cl">  @opentelemetry/instrumentation-undici <span class="se">\
</span></span></span><span class="line"><span class="cl">  @opentelemetry/sdk-node
</span></span><span class="line"><span class="cl">npm install -D tsx  <span class="c1"># uma ferramenta para executar arquivos TypeScript (.ts) diretamente com node</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-sh" data-lang="sh"><span class="line"><span class="cl">npm init -y
</span></span><span class="line"><span class="cl">npm install undici <span class="se">\
</span></span></span><span class="line"><span class="cl">  @opentelemetry/instrumentation-undici <span class="se">\
</span></span></span><span class="line"><span class="cl">  @opentelemetry/sdk-node
</span></span></code></pre></div>
    </div>
</div>


Em seguida, crie um novo arquivo chamado `client.ts` (ou `client.js`) com o
seguinte conteúdo:

   <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">/* client.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></span><span class="line"><span class="cl">  <span class="nx">SimpleSpanProcessor</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">ConsoleSpanExporter</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-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">UndiciInstrumentation</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;@opentelemetry/instrumentation-undici&#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">spanProcessors</span><span class="o">:</span> <span class="p">[</span><span class="k">new</span> <span class="nx">SimpleSpanProcessor</span><span class="p">(</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">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="k">new</span> <span class="nx">UndiciInstrumentation</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">sdk</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">request</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">&#39;undici&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">request</span><span class="p">(</span><span class="s1">&#39;http://localhost:8080/rolldice&#39;</span><span class="p">).</span><span class="nx">then</span><span class="p">((</span><span class="nx">response</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">response</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">json</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">json</span>: <span class="kt">any</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">json</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-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></span><span class="line"><span class="cl">  <span class="nx">SimpleSpanProcessor</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">ConsoleSpanExporter</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-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">UndiciInstrumentation</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@opentelemetry/instrumentation-undici&#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">spanProcessors</span><span class="o">:</span> <span class="p">[</span><span class="k">new</span> <span class="nx">SimpleSpanProcessor</span><span class="p">(</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">instrumentations</span><span class="o">:</span> <span class="p">[</span><span class="k">new</span> <span class="nx">UndiciInstrumentation</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">sdk</span><span class="p">.</span><span class="nx">start</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="p">{</span> <span class="nx">request</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;undici&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">request</span><span class="p">(</span><span class="s1">&#39;http://localhost:8080/rolldice&#39;</span><span class="p">).</span><span class="nx">then</span><span class="p">((</span><span class="nx">response</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">response</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">json</span><span class="p">().</span><span class="nx">then</span><span class="p">((</span><span class="nx">json</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">json</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div>
    </div>
</div>


Certifique-se de que a versão instrumentada de `app.ts` (ou `app.js`) do
[Primeiros Passos](../getting-started/nodejs) esteja em execução em um terminal:

   <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">Listening for requests on 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">Listening for requests on http://localhost:8080
</span></span></span></code></pre></div>
    </div>
</div>


Abra um segundo terminal e execute o `client.ts` (ou `client.js`):

   <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-shell" data-lang="shell"><span class="line"><span class="cl">npx tsx client.ts
</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-shell" data-lang="shell"><span class="line"><span class="cl">node client.js
</span></span></code></pre></div>
    </div>
</div>


Ambos os terminais devem emitir detalhes dos trechos no console. A saída do
cliente é semelhante à seguinte:

```javascript {hl_lines=[7,11]}
{
  resource: {
    attributes: {
      // ...
    }
  },
  traceId: 'cccd19c3a2d10e589f01bfe2dc896dc2',
  parentSpanContext: undefined,
  traceState: undefined,
  name: 'GET',
  id: '6f64ce484217a7bf',
  kind: 2,
  timestamp: 1718875320295000,
  duration: 19836.833,
  attributes: {
    'url.full': 'http://localhost:8080/rolldice',
    // ...
  },
  status: { code: 0 },
  events: [],
  links: []
}
```

Anote o traceId (`cccd19c3a2d10e589f01bfe2dc896dc2`) e o ID
(`6f64ce484217a7bf`). Ambos também podem ser encontrados na saída do cliente:

```javascript {hl_lines=[6,9]}
{
  resource: {
    attributes: {
      // ...
    }
  },
  traceId: 'cccd19c3a2d10e589f01bfe2dc896dc2',
  parentSpanContext: {
    traceId: 'cccd19c3a2d10e589f01bfe2dc896dc2',
    spanId: '6f64ce484217a7bf',
    traceFlags: 1,
    isRemote: true
  },
  traceState: undefined,
  name: 'GET /rolldice',
  id: '027c5c8b916d29da',
  kind: 1,
  timestamp: 1718875320310000,
  duration: 3894.792,
  attributes: {
    'http.url': 'http://localhost:8080/rolldice',
    // ...
  },
  status: { code: 0 },
  events: [],
  links: []
}
```

Suas aplicações cliente e servidora relatam com sucesso trechos conectados. Se
você enviar ambas para um _backend_ agora, a visualização mostrará essa
dependência para você.

## Propagação manual de contexto {#manual-context-propagation}

Em alguns casos, não é possível propagar o contexto automaticamente como
descrito na seção anterior. Pode não existir uma biblioteca de instrumentação
correspondente à biblioteca que você usa para fazer os serviços se comunicarem
entre si. Ou você pode ter requisitos que essas bibliotecas não conseguem
atender, mesmo que existissem.

Quando você precisa propagar o contexto manualmente, pode usar a
[API de Contexto](/docs/languages/js/context).

### Exemplo genérico {#generic-example}

O exemplo genérico a seguir demonstra como você pode propagar o contexto do
rastro manualmente.

Primeiro, no serviço de envio, você precisa injetar o `context` atual:

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

<div class="tab-content" id="tabs-6-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-06-00" role="tabpanel" aria-labelled-by="tabs-06-00-tab" tabindex="6">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// Serviço de envio
</span></span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">propagation</span><span class="p">,</span> <span class="nx">trace</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">// Define uma interface para o objeto de saída que conterá as informações do rastro.
</span></span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">Carrier</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">traceparent?</span>: <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">tracestate?</span>: <span class="kt">string</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="c1">// Cria um objeto de saída que segue essa interface.
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">output</span>: <span class="kt">Carrier</span> <span class="o">=</span> <span class="p">{};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Serializa o traceparent e o tracestate do contexto para
</span></span></span><span class="line"><span class="cl"><span class="c1">// um objeto de saída.
</span></span></span><span class="line"><span class="cl"><span class="c1">//
</span></span></span><span class="line"><span class="cl"><span class="c1">// Este exemplo usa o contexto ativo de rastro, mas você pode
</span></span></span><span class="line"><span class="cl"><span class="c1">// usar o contexto que for apropriado ao seu cenário.
</span></span></span><span class="line"><span class="cl"><span class="nx">propagation</span><span class="p">.</span><span class="nx">inject</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nx">active</span><span class="p">(),</span> <span class="nx">output</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Extrai os valores de traceparent e tracestate do objeto de saída.
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">traceparent</span><span class="p">,</span> <span class="nx">tracestate</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">output</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Em seguida, você pode passar os dados de traceparent e
</span></span></span><span class="line"><span class="cl"><span class="c1">// tracestate para o mecanismo que você usa para propagar
</span></span></span><span class="line"><span class="cl"><span class="c1">// entre serviços.
</span></span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-06-01" role="tabpanel" aria-labelled-by="tabs-06-01-tab" tabindex="6">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// Serviço de envio
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">propagation</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;@opentelemetry/api&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">output</span> <span class="o">=</span> <span class="p">{};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Serializa o traceparent e o tracestate do contexto para
</span></span></span><span class="line"><span class="cl"><span class="c1">// um objeto de saída.
</span></span></span><span class="line"><span class="cl"><span class="c1">//
</span></span></span><span class="line"><span class="cl"><span class="c1">// Este exemplo usa o contexto ativo de rastro, mas você pode
</span></span></span><span class="line"><span class="cl"><span class="c1">// usar o contexto que for apropriado ao seu cenário.
</span></span></span><span class="line"><span class="cl"><span class="nx">propagation</span><span class="p">.</span><span class="nx">inject</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nx">active</span><span class="p">(),</span> <span class="nx">output</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="p">{</span> <span class="nx">traceparent</span><span class="p">,</span> <span class="nx">tracestate</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">output</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Em seguida, você pode passar os dados de traceparent e
</span></span></span><span class="line"><span class="cl"><span class="c1">// tracestate para o mecanismo que você usa para propagar
</span></span></span><span class="line"><span class="cl"><span class="c1">// entre serviços.
</span></span></span></code></pre></div>
    </div>
</div>


No serviço de recebimento, você precisa extrair o `context` (por exemplo, de
cabeçalhos HTTP analisados) e defini-lo como o contexto atual de rastro.

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

<div class="tab-content" id="tabs-7-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-07-00" role="tabpanel" aria-labelled-by="tabs-07-00-tab" tabindex="7">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="c1">// Serviço de recebimento
</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="kr">type</span> <span class="nx">Context</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">propagation</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">trace</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Span</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">context</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/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">// Define uma interface para o objeto de entrada que inclui &#39;traceparent&#39; e &#39;tracestate&#39;.
</span></span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">Carrier</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">traceparent?</span>: <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">tracestate?</span>: <span class="kt">string</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="c1">// Suponha que &#34;input&#34; seja um objeto com as chaves &#39;traceparent&#39; e &#39;tracestate&#39;.
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">input</span>: <span class="kt">Carrier</span> <span class="o">=</span> <span class="p">{};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Extrai os dados de &#39;traceparent&#39; e &#39;tracestate&#39; para um objeto de contexto.
</span></span></span><span class="line"><span class="cl"><span class="c1">//
</span></span></span><span class="line"><span class="cl"><span class="c1">// Em seguida, você pode tratar este contexto como o contexto ativo para os
</span></span></span><span class="line"><span class="cl"><span class="c1">// seus rastros.
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">activeContext</span>: <span class="kt">Context</span> <span class="o">=</span> <span class="nx">propagation</span><span class="p">.</span><span class="nx">extract</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nx">active</span><span class="p">(),</span> <span class="nx">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">tracer</span> <span class="o">=</span> <span class="nx">trace</span><span class="p">.</span><span class="nx">getTracer</span><span class="p">(</span><span class="s1">&#39;app-name&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">span</span>: <span class="kt">Span</span> <span class="o">=</span> <span class="nx">tracer</span><span class="p">.</span><span class="nx">startSpan</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="nx">spanName</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">attributes</span><span class="o">:</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">activeContext</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="c1">// Define o trecho criado como ativo no contexto desserializado.
</span></span></span><span class="line"><span class="cl"><span class="nx">trace</span><span class="p">.</span><span class="nx">setSpan</span><span class="p">(</span><span class="nx">activeContext</span><span class="p">,</span> <span class="nx">span</span><span class="p">);</span>
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-07-01" role="tabpanel" aria-labelled-by="tabs-07-01-tab" tabindex="7">
        <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// Serviço de recebimento
</span></span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">propagation</span><span class="p">,</span> <span class="nx">trace</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">// Suponha que &#34;input&#34; seja um objeto com as chaves &#39;traceparent&#39; e &#39;tracestate&#39;
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">input</span> <span class="o">=</span> <span class="p">{};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Extrai os dados de &#39;traceparent&#39; e &#39;tracestate&#39; para um objeto de contexto.
</span></span></span><span class="line"><span class="cl"><span class="c1">//
</span></span></span><span class="line"><span class="cl"><span class="c1">// Em seguida, você pode tratar este contexto como o contexto ativo para os
</span></span></span><span class="line"><span class="cl"><span class="c1">// seus rastros.
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">activeContext</span> <span class="o">=</span> <span class="nx">propagation</span><span class="p">.</span><span class="nx">extract</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nx">active</span><span class="p">(),</span> <span class="nx">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">tracer</span> <span class="o">=</span> <span class="nx">trace</span><span class="p">.</span><span class="nx">getTracer</span><span class="p">(</span><span class="s1">&#39;app-name&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">span</span> <span class="o">=</span> <span class="nx">tracer</span><span class="p">.</span><span class="nx">startSpan</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="nx">spanName</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">attributes</span><span class="o">:</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">activeContext</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="c1">// Define o trecho criado como ativo no contexto desserializado.
</span></span></span><span class="line"><span class="cl"><span class="nx">trace</span><span class="p">.</span><span class="nx">setSpan</span><span class="p">(</span><span class="nx">activeContext</span><span class="p">,</span> <span class="nx">span</span><span class="p">);</span>
</span></span></code></pre></div>
    </div>
</div>


A partir daí, quando você tem um contexto ativo desserializado, você pode criar
trechos que farão parte do mesmo rastro do outro serviço.

Você também pode usar a [API de Contexto](/docs/languages/js/context) para
modificar ou definir o contexto desserializado de outras formas.

### Exemplo de protocolo personalizado {#custom-protocol-example}

Um caso de uso comum para quando você precisa propagar o contexto manualmente é
quando você usa um protocolo personalizado de comunicação entre serviços. O
exemplo a seguir usa um protocolo TCP básico baseado em texto para enviar um
objeto serializado de um serviço para outro.

Comece criando uma nova pasta chamada `propagation-example` e inicialize-a com
as dependências da seguinte forma:

```shell
npm init -y
npm install @opentelemetry/api @opentelemetry/sdk-node
```

Em seguida, crie os arquivos `client.js` e `server.js` com o seguinte conteúdo:

```javascript
// client.js
const net = require('net');
const { context, propagation, trace } = require('@opentelemetry/api');

let tracer = trace.getTracer('client');

// Conecta ao servidor
const client = net.createConnection({ port: 8124 }, () => {
  // Envia o objeto serializado para o servidor
  let span = tracer.startActiveSpan('send', { kind: 1 }, (span) => {
    const output = {};
    propagation.inject(context.active(), output);
    const { traceparent, tracestate } = output;

    const objToSend = { key: 'value' };

    if (traceparent) {
      objToSend._meta = { traceparent, tracestate };
    }

    client.write(JSON.stringify(objToSend), () => {
      client.end();
      span.end();
    });
  });
});
```

```javascript
// server.js
const net = require('net');
const { context, propagation, trace } = require('@opentelemetry/api');

let tracer = trace.getTracer('server');

const server = net.createServer((socket) => {
  socket.on('data', (data) => {
    const message = data.toString();
    // Analisa o objeto JSON recebido do cliente
    try {
      const json = JSON.parse(message);
      let activeContext = context.active();
      if (json._meta) {
        activeContext = propagation.extract(context.active(), json._meta);
        delete json._meta;
      }
      span = tracer.startSpan('receive', { kind: 1 }, activeContext);
      trace.setSpan(activeContext, span);
      console.log('Parsed JSON:', json);
    } catch (e) {
      console.error('Error parsing JSON:', e.message);
    } finally {
      span.end();
    }
  });
});

// Escuta na porta 8124
server.listen(8124, () => {
  console.log('Server listening on port 8124');
});
```

Abra um primeiro terminal para executar o servidor:

```console
$ node server.js
Server listening on port 8124
```

Depois, em um segundo terminal, execute o cliente:

```shell
node client.js
```

O cliente deve encerrar imediatamente e o servidor deve exibir o seguinte:

```text
Parsed JSON: { key: 'value' }
```

Como o exemplo até aqui dependeu apenas da API do OpenTelemetry, todas as
chamadas a ela são
[instruções sem operação (_no-op_)](https://pt.wikipedia.org/wiki/NOP) e o
cliente e o servidor se comportam como se o OpenTelemetry não estivesse sendo
usado.

> [!IMPORTANT]
>
> Isto é especialmente importante se o código do seu servidor e cliente forem
> bibliotecas, já que elas devem usar apenas a API do OpenTelemetry. Para
> entender o porquê, leia a
> [página de conceito sobre como adicionar instrumentação à sua biblioteca](/docs/concepts/instrumentation/libraries/).

Para habilitar o OpenTelemetry e ver a propagação de contexto em ação, crie um
arquivo adicional chamado `instrumentation.js` com o seguinte conteúdo:

```javascript
// instrumentation.mjs
import { NodeSDK } from '@opentelemetry/sdk-node';
import {
  ConsoleSpanExporter,
  SimpleSpanProcessor,
} from '@opentelemetry/sdk-trace-node';

const sdk = new NodeSDK({
  spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())],
});

sdk.start();
```

Use este arquivo para executar tanto o servidor quanto o cliente com a
instrumentação habilitada:

```console
$ node --import ./instrumentation.mjs server.js
Server listening on port 8124
```

e

```shell
node --import ./instrumentation.mjs client.js
```

Depois que o cliente enviar os dados para o servidor e encerrar, você verá
trechos na saída do console de ambos os terminais.

A saída do cliente é semelhante à seguinte:

```javascript {hl_lines=[7,11]}
{
  resource: {
    attributes: {
      // ...
    }
  },
  traceId: '4b5367d540726a70afdbaf49240e6597',
  parentId: undefined,
  traceState: undefined,
  name: 'send',
  id: '92f125fa335505ec',
  kind: 1,
  timestamp: 1718879823424000,
  duration: 1054.583,
  // ...
}
```

A saída do servidor é semelhante à seguinte:

```javascript {hl_lines=[7,8]}
{
  resource: {
    attributes: {
      // ...
    }
  },
  traceId: '4b5367d540726a70afdbaf49240e6597',
  parentId: '92f125fa335505ec',
  traceState: undefined,
  name: 'receive',
  id: '53da0c5f03cb36e5',
  kind: 1,
  timestamp: 1718879823426000,
  duration: 959.541,
  // ...
}
```

Assim como no [exemplo manual](#manual-context-propagation), os trechos são
conectados usando o `traceId` e o `id`/`parentId`.

## Próximos passos {#next-steps}

Para saber mais sobre propagação, leia a
[especificação da API de Propagadores](/docs/specs/otel/context/api-propagators/).
