Resources
You are viewing the English version of this page because it has not yet been fully translated. Interested in helping out? See Contributing.
资源以资源属性的形式表示产生遥测数据的实体。例如, 进程 产生的遥测数据运行在 Kubernetes 的容器中,那么它会具有 进程 的名称、Pod 名称、命名空间,可能还有部署名称。这四个属性都可以包含在资源中。
在你的可观测性后端中,你可以使用资源信息来更好地调查异常行为。例如, 如果你的追踪或指标数据表明系统中存在延迟,你可以将问题定位到特定的容器、Pod 或 Kubernetes 部署上。
Below you will find introductions on how to set up resource detection with the Node.js SDK.
Setup
Follow the instructions in the Getting Started - Node.js, so that you have the files package.json
, app.js
and tracing.js
.
Process & Environment Resource Detection
Out of the box, the Node.js SDK detects process and process runtime resources and takes attributes from the environment variable OTEL_RESOURCE_ATTRIBUTES
. You can verify what it detects by turning on diagnostic logging in tracing.js
:
// For troubleshooting, set the log level to DiagLogLevel.DEBUG diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
Run the application with some values set to OTEL_RESOURCE_ATTRIBUTES
, e.g. we set the host.name
to identify the Host:
$ env OTEL_RESOURCE_ATTRIBUTES="host.name=localhost" \ node --require ./tracing.js 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' } } ...
Adding resources with environment variables
In the above example, the SDK detected the process and also added the host.name=localhost
attribute set via the environment variable automatically.
Below you will find instructions to get resources detected automatically for you. However, you might run into the situation that no detector exists for the resource you need. In that case, use the environment variable OTEL_RESOURCE_ATTRIBUTES
to inject whatever you need. Additionally, you can use the environment variable OTEL_SERVICE_NAME
to set value of the service.name
resource attribute. For example, the following script adds Service, Host and OS resource attributes:
$ 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 --require ./tracing.js 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' } } ...
Adding resources in code
Custom resources can also be configured in your code. The NodeSDK
provides a configuration option, where you can set them. For example you can update the tracing.js
like the following to have service.*
attributes set:
... 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", }) ... }); ...
If you set your resource attributes via environment variable and code, the values set via the environment variable take precedence.
Container Resource Detection
Use the same setup (package.json
, app.js
and tracing.js
with debugging turned on) and Dockerfile
with the following content in the same directory:
FROM node:latest WORKDIR /usr/src/app COPY package.json ./ RUN npm install COPY . . EXPOSE 8080 CMD [ "node", "--require", "./tracing.js", "app.js" ]
To make sure that you can stop your docker container with Ctrl + C (SIGINT
) add the following to the bottom of app.js
:
process.on('SIGINT', function () { process.exit(); });
To get the ID of your container detected automatically for you, install the following additional dependency:
npm install @opentelemetry/resource-detector-docker
Next, update your tracing.js
like the following:
const opentelemetry = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node'); const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api'); const { dockerCGroupV1Detector, } = require('@opentelemetry/resource-detector-docker'); // For troubleshooting, set the log level to DiagLogLevel.DEBUG diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); const sdk = new opentelemetry.NodeSDK({ traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(), instrumentations: [getNodeAutoInstrumentations()], resourceDetectors: [dockerCGroupV1Detector], }); sdk.start();
Build your docker image:
docker build . -t nodejs-otel-getting-started
Run your docker container:
$ 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' } }
The detector has extracted the container.id
for you. However you might recognize that in this example, the process attributes and the attributes set via an environment variable are missing! To resolve this, when you set the resourceDetectors
list you also need to specify the envDetector
and processDetector
detectors:
const opentelemetry = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node'); const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api'); const { dockerCGroupV1Detector, } = require('@opentelemetry/resource-detector-docker'); const { envDetector, processDetector } = require('@opentelemetry/resources'); // For troubleshooting, set the log level to DiagLogLevel.DEBUG diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); const sdk = new opentelemetry.NodeSDK({ traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(), instrumentations: [getNodeAutoInstrumentations()], // Make sure to add all detectors you need here! resourceDetectors: [envDetector, processDetector, dockerCGroupV1Detector], }); sdk.start();
Rebuild your image and run your container once again:
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' } } ...
Next steps
There are more resource detectors you can add to your configuration, for example to get details about your Cloud environment or Deployment. For more, see the complete list of detectors.
Feedback
Was this page helpful?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!