资源
资源以资源属性的形式表示产生遥测数据的实体。例如, 进程 产生的遥测数据运行在 Kubernetes 的容器中,那么它会具有 进程 的名称、Pod 名称、命名空间,可能还有部署名称。这四个属性都可以包含在资源中。
在你的可观测性后端中,你可以使用资源信息来更好地调查异常行为。例如, 如果你的追踪或指标数据表明系统中存在延迟,你可以将问题定位到特定的容器、Pod 或 Kubernetes 部署上。
下面你将了解如何通过 Node.js SDK 设置资源探测。
设置
请按照 Node.js 快速入门中的说明进行操作,这样你就会拥有package.json、app.js(或app.ts)和instrumentation.mjs(或instrumentation.ts)这些文件。
进程和环境资源探测
开箱即用,Node.js SDK 会探测进程和进程运行时资源,
并从环境变量OTEL_RESOURCE_ATTRIBUTES中获取属性。
你可以通过在插桩文件中启用诊断日志,来验证它探测到的内容:
// 要进行故障排查,请将日志级别设置为 DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
运行应用程序时设置一些OTEL_RESOURCE_ATTRIBUTES的值,例如我们设置host.name来标识主机:
$ 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'
}
}
...
通过环境变量添加资源
在上面的示例中,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 --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'
}
}
...
在代码中添加资源
自定义资源也可以在你的代码中配置。NodeSDK提供了一个配置选项,你可以在其中设置它们。
例如,你可以像下面这样更新你的插桩文件,以设置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和instrumentation.mjs),
并在同一目录下使用以下内容的Dockerfile:
FROM node:latest
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "node", "--import", "./instrumentation.mjs", "app.js" ]
为了确保你可以通过 Ctrl + C(SIGINT)停止你的 Docker 容器,请将以下内容添加到app.js的末尾:
process.on('SIGINT', function () {
process.exit();
});
要自动探测容器的 ID,请安装以下附加依赖项:
npm install @opentelemetry/resource-detector-container
接下来,像下面这样更新你的instrumentation.mjs:
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');
// 要进行故障排除,请将日志级别设置为 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 http://localhost: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');
// 要进行故障排除,请将日志级别设置为 DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
const sdk = new opentelemetry.NodeSDK({
traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(),
instrumentations: [getNodeAutoInstrumentations()],
// 请确保在这里添加所有你需要的探测器!
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 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'
}
}
...
下一步
你可以在配置中添加更多资源探测器,例如获取有关你的云环境或部署的详细信息。
更多信息,请参阅opentelemetry-js-contrib 仓库中名为 resource-detector-* 的包。
意见反馈
这个页面对您有帮助吗?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!