资源
A resource represents the entity producing telemetry as resource attributes. For example, a process producing telemetry that is running in a container on Kubernetes has a process name, a pod name, a namespace, and possibly a deployment name. All four of these attributes can be included in the resource.
In your observability backend, you can use resource information to better investigate interesting behavior. For example, if your trace or metrics data indicate latency in your system, you can narrow it down to a specific container, pod, or Kubernetes deployment.
下面将介绍如何使用 Node.js SDK 设置资源检测。
设置
按照入门指南 - Node.js中的说明进行操作,以便你拥有以下文件 package.json
、app.js
和 tracing.js
。
进程和环境资源检测
Node.js SDK 已经默认支持 进程和进程运行时资源
的检测,并从环境变量 OTEL_RESOURCE_ATTRIBUTES
中获取属性。你可以通过在 tracing.js
中启动诊断日志来验证它所检测到的内容:
// 用于故障排除,将日志级别设置为 DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
运行应用程序时,将一些值设置给 OTEL_RESOURCE_ATTRIBUTES
,例如我们将 host.name
设置为标识符 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'
}
}
...
使用环境变量添加资源
在上述示例中,SDK 检测了进程,并自动通过环境变量添加了 host.name=localhost
属性。
以下是自动检测资源的详细说明。但是,你可能会遇到所需资源的检测器不存在的情况。在这种情况下,可使用环境变量
OTEL_RESOURCE_ATTRIBUTES
来注入你所需的任何内容。此外,你还可以使用环境变量 OTEL_SERVICE_NAME
来设置 service.name
资源属性的值。例如,以下脚本添加了 Service, Host 和 OS 资源属性:
$ 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'
}
}
...
在代码中添加资源
你还可以在代码中配置自定义资源。NodeSDK
提供了一个配置选项,可以在其中设置这些资源。例如,你可以更新 tracing.js
,如下所示,设置 service.*
属性:
...
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
...
const sdk = new opentelemetry.NodeSDK({
...
resource: new Resource({
[ SemanticResourceAttributes.SERVICE_NAME ]: "yourServiceName",
[ SemanticResourceAttributes.SERVICE_NAMESPACE ]: "yourNameSpace",
[ SemanticResourceAttributes.SERVICE_VERSION ]: "1.0",
[ SemanticResourceAttributes.SERVICE_INSTANCE_ID ]: "my-instance-id-1",
})
...
});
...
注意
如果你通过环境变量和代码设置了资源属性,则以环境变量设置的值优先。容器资源检测
使用相同的设置(在相同的目录中准备 package.json
、app.js
和 tracing.js
,并打开调试信息),以及包含以下内容的 Dockerfile
:
FROM node:latest
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "node", "--require", "./tracing.js", "app.js" ]
为了确保你可以通过 Ctrl + C(SIGINT
)停止 docker 容器,请在 app.js
的末尾添加以下内容:
process.on('SIGINT', function () {
process.exit();
});
为了让你的容器被自动检测出来,请安装以下附加依赖项:
npm install @opentelemetry/resource-detector-docker
接下来,更新你的 tracing.js
如下:
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');
// 用于故障排除,将日志级别设置为 DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
const sdk = new opentelemetry.NodeSDK({
traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(),
instrumentations: [getNodeAutoInstrumentations()],
resourceDetectors: [dockerCGroupV1Detector],
});
sdk.start();
构建 docker 镜像:
docker build . -t nodejs-otel-getting-started
运行 docker 容器:
$ 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': 'fffbeaf682f32ef86916f306ff9a7f88cc58048ab78f7de464da3c320ldb5c54'
}
}
可检测器已为你提取了 container.id
。但是,你可能会注意到在此示例中,缺少了进程属性和通过环境变量设置的属性!为了解决这个问题,当你设置 resourceDetectors
列表时,还需要指定 envDetector
和 processDetector
检测器:
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');
// 用于故障排除,将日志级别设置为 DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
const sdk = new opentelemetry.NodeSDK({
traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(),
instrumentations: [getNodeAutoInstrumentations()],
// 确保在这里添加所有你需要的检测器!
resourceDetectors: [envDetector, processDetector, dockerCGroupV1Detector],
});
sdk.start();
重新构建你的镜像,并再次运行容器:
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'
}
}
...
下一步
你可以为配置添加更多的资源检测器,例如获取有关你的 Cloud 环境或 Deployment 的详细信息。你可以在此处找到一个列表。