From 89544cb66da7a2060b9e865f53c54e923ab9b336 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Thu, 26 Jan 2023 17:26:16 -0800 Subject: [PATCH] feat: detect host id for non-cloud environments --- CHANGELOG.md | 2 ++ packages/opentelemetry-resources/package.json | 3 +- .../src/platform/node/HostDetector.ts | 9 ++++++ .../test/detectors/node/HostDetector.test.ts | 30 +++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91960a3c5b7..38490b339d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/ ## Unreleased +* feat: collect host id for non-cloud environments [#3575](/~https://github.com/open-telemetry/opentelemetry-js/pull/3575) @mwear + ### :boom: Breaking Change ### :rocket: (Enhancement) diff --git a/packages/opentelemetry-resources/package.json b/packages/opentelemetry-resources/package.json index c6177a592d0..789371e5525 100644 --- a/packages/opentelemetry-resources/package.json +++ b/packages/opentelemetry-resources/package.json @@ -90,7 +90,8 @@ }, "dependencies": { "@opentelemetry/core": "1.9.0", - "@opentelemetry/semantic-conventions": "1.9.0" + "@opentelemetry/semantic-conventions": "1.9.0", + "node-machine-id": "^1.1.12" }, "homepage": "/~https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-resources", "sideEffects": false diff --git a/packages/opentelemetry-resources/src/platform/node/HostDetector.ts b/packages/opentelemetry-resources/src/platform/node/HostDetector.ts index c27766bb925..7c6589ff085 100644 --- a/packages/opentelemetry-resources/src/platform/node/HostDetector.ts +++ b/packages/opentelemetry-resources/src/platform/node/HostDetector.ts @@ -14,11 +14,13 @@ * limitations under the License. */ +import { diag } from '@opentelemetry/api'; import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; import { Resource } from '../../Resource'; import { Detector, ResourceAttributes } from '../../types'; import { ResourceDetectionConfig } from '../../config'; import { arch, hostname } from 'os'; +import { machineId } from 'node-machine-id'; /** * HostDetector detects the resources related to the host current process is @@ -30,6 +32,13 @@ class HostDetector implements Detector { [SemanticResourceAttributes.HOST_NAME]: hostname(), [SemanticResourceAttributes.HOST_ARCH]: this._normalizeArch(arch()), }; + + try { + attributes[SemanticResourceAttributes.HOST_ID] = await machineId(true); + } catch (err) { + diag.warn(`error reading machine id: ${err}`); + } + return new Resource(attributes); } diff --git a/packages/opentelemetry-resources/test/detectors/node/HostDetector.test.ts b/packages/opentelemetry-resources/test/detectors/node/HostDetector.test.ts index 3c809d500d1..6d2ce853a92 100644 --- a/packages/opentelemetry-resources/test/detectors/node/HostDetector.test.ts +++ b/packages/opentelemetry-resources/test/detectors/node/HostDetector.test.ts @@ -27,9 +27,11 @@ describeNode('hostDetector() on Node.js', () => { it('should return resource information about the host', async () => { const os = require('os'); + const mach = require('node-machine-id'); sinon.stub(os, 'arch').returns('x64'); sinon.stub(os, 'hostname').returns('opentelemetry-test'); + sinon.stub(mach, 'machineId').returns(Promise.resolve('123-abc')); const resource: Resource = await hostDetector.detect(); @@ -41,6 +43,10 @@ describeNode('hostDetector() on Node.js', () => { resource.attributes[SemanticResourceAttributes.HOST_ARCH], 'amd64' ); + assert.strictEqual( + resource.attributes[SemanticResourceAttributes.HOST_ID], + '123-abc' + ); }); it('should pass through arch string if unknown', async () => { @@ -55,4 +61,28 @@ describeNode('hostDetector() on Node.js', () => { 'some-unknown-arch' ); }); + + it('should handle errors reading machine id', async () => { + const os = require('os'); + const mach = require('node-machine-id'); + + sinon.stub(os, 'arch').returns('x64'); + sinon.stub(os, 'hostname').returns('opentelemetry-test'); + sinon.stub(mach, 'machineId').rejects(new Error('id not found')); + + const resource: Resource = await hostDetector.detect(); + + assert.strictEqual( + resource.attributes[SemanticResourceAttributes.HOST_NAME], + 'opentelemetry-test' + ); + assert.strictEqual( + resource.attributes[SemanticResourceAttributes.HOST_ARCH], + 'amd64' + ); + assert.strictEqual( + false, + SemanticResourceAttributes.HOST_ID in resource.attributes + ); + }); });