资源
一个 资源 代表产生遥测数据的实体,并以资源属性的形式表示。例如,一个在 Kubernetes 容器中运行并产生遥测数据的进程,会拥有进程名、Pod 名、命名空间,以及可能的部署名。这四个属性都可以包含在资源中。
在您的可观测性后端,您可以使用资源信息更好地调查有趣的现象。例如,如果您的跟踪或指标数据表明系统中存在延迟,您可以将其缩小到特定的容器、Pod 或 Kubernetes 部署。
下面您将找到有关如何使用 Node.js SDK 设置资源检测的介绍。
设置
请按照入门 - Node.js中的说明进行操作,以便您拥有 package.json、app.js 和 tracing.js 文件。
进程 & 环境资源检测
开箱即用,Node.js SDK 会检测进程和进程运行时资源,并从环境变量 OTEL_RESOURCE_ATTRIBUTES 中获取属性。您可以通过在 tracing.js 中启用诊断日志来验证其检测到的内容。
// For troubleshooting, set the log level to DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
运行应用程序并设置一些 OTEL_RESOURCE_ATTRIBUTES 值,例如,我们设置 host.name 来标识主机。
$ 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 https://: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 资源属性的值。例如,以下脚本添加了服务、主机和操作系统资源属性。
$ 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 { 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",
})
...
});
...
如果您通过环境变量和代码设置资源属性,则通过环境变量设置的值具有优先权。
容器资源检测
使用相同的设置(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();
});
为了自动为您检测容器 ID,请安装以下附加依赖项。
npm install @opentelemetry/resource-detector-container
接下来,像下面一样更新您的 tracing.js。
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');
// 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: [containerDetector],
});
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 https://:8080
DockerCGroupV1Detector found resource. Resource {
attributes: {
'container.id': 'fffbeaf682f32ef86916f306ff9a7f88cc58048ab78f7de464da3c3201db5c54'
}
}
检测器已为您提取了 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 {
containerDetector,
} = require('@opentelemetry/resource-detector-container');
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, containerDetector],
});
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 https://: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'
}
}
...
下一步
您可以在配置中添加更多资源检测器,例如获取有关您的云环境或部署的详细信息。有关更多信息,请参阅 opentelemetry-js-contrib 仓库中名为 resource-detector-* 的包。