# Recursos

> Adicione detalhes sobre o ambiente das suas aplicações à sua telemetria

---

Site [llms.txt](/pt/llms.txt)

---

Um [recurso](/docs/concepts/resources/) representa a entidade que está gerando
telemetria como atributos do recurso. Por exemplo, um processo que está
gerando telemetria e que está sendo executado em um _container_ no Kubernetes
tem o nome de um processo, um nome de _pod_, um _namespace_ e possivelmente
um nome de _deployment_. Todos esses quatro atributos podem ser incluídos em um
recurso.

No seu _backend_ de observabilidade, você pode usar as informações de um recurso
para refinar a investigação de comportamentos relevantes. Por exemplo, se seus
dados de rastros ou métricas indicarem latência no seu sistema, você pode
restringir a investigação para um determinado _container_, _pod_ ou _deployment_
do Kubernetes.


Abaixo você encontrará introduções sobre como configurar a detecção de recursos
com o SDK do Node.js.

## Configuração {#setup}

Siga as instruções em [Primeiros Passos - Node.js][getting started - node.js]
para ter os arquivos `package.json`, `app.js` (ou `app.ts`) e
`instrumentation.mjs` (ou `instrumentation.ts`).


> [!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).


## Detecção de recursos de processo e ambiente {#process-environment-resource-detection}

Por padrão, o SDK do Node.js detecta [recursos de processo e do _runtime_ de
processo][process and process runtime resources] e obtém atributos da variável
de ambiente `OTEL_RESOURCE_ATTRIBUTES`. É possível verificar o que é detectado
ativando o registro de diagnóstico no arquivo de instrumentação:

```javascript
// Para investigação de problemas, defina o nível de log como DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
```

Execute a aplicação com alguns valores definidos em `OTEL_RESOURCE_ATTRIBUTES`,
por exemplo, definimos o `host.name` para identificar o [Host][host]:

```console
$ env OTEL_RESOURCE_ATTRIBUTES="host.name=localhost" \
  node --import ./instrumentation.mjs app.js
@opentelemetry/api: Registered a global for diag v1.2.0.
...
Listening for requests on http://localhost:8080
EnvDetector found resource. Resource { attributes: { 'host.name': 'localhost' } }
ProcessDetector found resource. Resource {
  attributes: {
    'process.pid': 12345,
    'process.executable.name': 'node',
    'process.command': '/app.js',
    'process.command_line': '/bin/node /app.js',
    'process.runtime.version': '16.17.0',
    'process.runtime.name': 'nodejs',
    'process.runtime.description': 'Node.js'
  }
}
...
```

## Adicionando recursos com variáveis de ambiente {#adding-resources-with-environment-variables}

No exemplo acima, o SDK detectou o processo e também adicionou automaticamente o
atributo `host.name=localhost` definido pela variável de ambiente.

Abaixo estão instruções para que os recursos sejam detectados automaticamente.
No entanto, pode acontecer de não existir um detector para o recurso necessário.
Nesse caso, use a variável de ambiente `OTEL_RESOURCE_ATTRIBUTES` para injetar o
que for preciso. Além disso, é possível usar a variável de ambiente
`OTEL_SERVICE_NAME` para definir o valor do atributo de recurso `service.name`.
Por exemplo, o script a seguir adiciona atributos de recurso de
[Serviço][service], [Host][host] e [Sistema Operacional][os]:

```console
$ env OTEL_SERVICE_NAME="app.js" OTEL_RESOURCE_ATTRIBUTES="service.namespace=tutorial,service.version=1.0,service.instance.id=`uuidgen`,host.name=${HOSTNAME},host.type=`uname -m`,os.name=`uname -s`,os.version=`uname -r`" \
  node --import ./instrumentation.mjs app.js
...
EnvDetector found resource. Resource {
  attributes: {
    'service.name': 'app.js',
    'service.namespace': 'tutorial',
    'service.version': '1.0',
    'service.instance.id': '46D99F44-27AB-4006-9F57-3B7C9032827B',
    'host.name': 'myhost',
    'host.type': 'arm64',
    'os.name': 'linux',
    'os.version': '6.0'
  }
}
...
```

## Adicionando recursos no código {#adding-resources-in-code}

Também é possível configurar recursos personalizados no código. O `NodeSDK`
oferece uma opção de configuração para defini-los. Por exemplo, atualize o
arquivo de instrumentação como no exemplo a seguir para definir os atributos
`service.*`:

```javascript
...
const { resourceFromAttributes } = require('@opentelemetry/resources');
const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } = require('@opentelemetry/semantic-conventions');
...
const sdk = new opentelemetry.NodeSDK({
  ...
  resource: resourceFromAttributes({
    [ ATTR_SERVICE_NAME ]: "yourServiceName",
    [ ATTR_SERVICE_VERSION ]: "1.0",
  })
  ...
});
...
```

> [!NOTE]
>
> Caso os atributos de recurso sejam definidos por variável de ambiente e por
> código, os valores definidos pela variável de ambiente têm precedência.

## Detecção de recursos de contêiner {#container-resource-detection}

Use a mesma configuração (`package.json`, `app.js` e `instrumentation.mjs` com a
depuração ativada) e um `Dockerfile` com o seguinte conteúdo no mesmo diretório:

```Dockerfile
FROM node:latest
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "node", "--import", "./instrumentation.mjs", "app.js" ]
```

Para garantir que o contêiner Docker possa ser interrompido com <kbd>Ctrl +
C</kbd> (`SIGINT`), adicione o seguinte ao final do `app.js`:

```javascript
process.on('SIGINT', function () {
  process.exit();
});
```

Para que o ID do contêiner seja detectado automaticamente, instale a seguinte
dependência adicional:

```sh
npm install @opentelemetry/resource-detector-container
```

Em seguida, atualize o `instrumentation.mjs` como a seguir:

```javascript
const opentelemetry = require('@opentelemetry/sdk-node');
const {
  getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
const {
  containerDetector,
} = require('@opentelemetry/resource-detector-container');

// Para investigação de problemas, defina o nível de log como DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);

const sdk = new opentelemetry.NodeSDK({
  traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(),
  instrumentations: [getNodeAutoInstrumentations()],
  resourceDetectors: [containerDetector],
});

sdk.start();
```

Crie a imagem Docker:

```sh
docker build . -t nodejs-otel-getting-started
```

Execute o contêiner:

```sh
$ docker run --rm -p 8080:8080 nodejs-otel-getting-started
@opentelemetry/api: Registered a global for diag v1.2.0.
...
Listening for requests on http://localhost:8080
DockerCGroupV1Detector found resource. Resource {
  attributes: {
    'container.id': 'fffbeaf682f32ef86916f306ff9a7f88cc58048ab78f7de464da3c3201db5c54'
  }
}
```

O detector extraiu o `container.id`. No entanto, note que, neste exemplo, os
atributos de processo e os atributos definidos por variável de ambiente estão
ausentes! Para resolver isso, ao definir a lista `resourceDetectors`, é
necessário também especificar os detectores `envDetector` e `processDetector`:

```javascript
const opentelemetry = require('@opentelemetry/sdk-node');
const {
  getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
const {
  containerDetector,
} = require('@opentelemetry/resource-detector-container');
const { envDetector, processDetector } = require('@opentelemetry/resources');

// Para investigação de problemas, defina o nível de log como DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);

const sdk = new opentelemetry.NodeSDK({
  traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(),
  instrumentations: [getNodeAutoInstrumentations()],
  // Certifique-se de adicionar aqui todos os detectores necessários!
  resourceDetectors: [envDetector, processDetector, containerDetector],
});

sdk.start();
```

Reconstrua a imagem e execute o contêiner mais uma vez:

```shell
docker run --rm -p 8080:8080 nodejs-otel-getting-started
@opentelemetry/api: Registered a global for diag v1.2.0.
...
Listening for requests on http://localhost:8080
EnvDetector found resource. Resource { attributes: {} }
ProcessDetector found resource. Resource {
  attributes: {
    'process.pid': 1,
    'process.executable.name': 'node',
    'process.command': '/usr/src/app/app.js',
    'process.command_line': '/usr/local/bin/node /usr/src/app/app.js',
    'process.runtime.version': '18.9.0',
    'process.runtime.name': 'nodejs',
    'process.runtime.description': 'Node.js'
  }
}
DockerCGroupV1Detector found resource. Resource {
  attributes: {
    'container.id': '654d0670317b9a2d3fc70cbe021c80ea15339c4711fb8e8b3aa674143148d84e'
  }
}
...
```

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

Existem mais detectores de recursos que podem ser adicionados à configuração,
por exemplo, para obter detalhes sobre o seu ambiente de [Nuvem][cloud] ou
[Implantação][deployment]. Para mais, veja os
[pacotes nomeados `resource-detector-*` no repositório opentelemetry-js-contrib](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages).

[getting started - node.js]: /docs/languages/js/getting-started/nodejs/
[process and process runtime resources]: /docs/specs/semconv/resource/process/
[host]: /docs/specs/semconv/resource/host/
[cloud]: /docs/specs/semconv/resource/cloud/
[deployment]: /docs/specs/semconv/resource/deployment-environment/
[service]: /docs/specs/semconv/resource/#service
[os]: /docs/specs/semconv/resource/os/
