From 583cc7c23d4a95eccdd1bdedc5ed5ab018f6b7e4 Mon Sep 17 00:00:00 2001 From: Marylia Gutierrez Date: Mon, 15 Apr 2024 04:28:48 -0400 Subject: [PATCH] feat(resources): implements `service.instance.id` (#4608) * feat(node-sdk): implements `service.instance.id` Implements `service.instance.id` Signed-off-by: maryliag * implement service instance id by default with env var use an experimental environment variable to set the default value of `service.instance.id` as default * Update CHANGELOG.md Co-authored-by: Marc Pichler * create separate add experimental for browser and node create a function to add experimental default values (currently only service instance id, but others can be added in the future), with the value being set on the node case, but not on the browser case. Signed-off-by: maryliag * use resource detector for service instance id use a resource detector for service instance id * remove references to env variables * remove Detector and use DetectorSync remove the Detector and use the DetectorSync instead. Also mark things as experimental. Signed-off-by: maryliag * Update packages/opentelemetry-resources/src/platform/node/ServiceInstanceIDDetectorSync.ts Co-authored-by: Marc Pichler * rename ServiceInstanceIDDetector to ServiceInstanceIDDetectorSync * change ID to Id * renaming something temp so git will pick up the name change it was not picking up the case change on previous commit * update to final name using Id --------- Signed-off-by: maryliag Co-authored-by: Marc Pichler --- CHANGELOG.md | 3 +- .../opentelemetry-sdk-node/test/sdk.test.ts | 91 ++++++++++++++++++- package-lock.json | 15 --- .../opentelemetry-resources/src/Resource.ts | 21 +++-- .../src/detectors/EnvDetectorSync.ts | 4 +- .../browser/ServiceInstanceIdDetectorSync.ts | 22 +++++ .../src/platform/browser/index.ts | 1 + .../node/ServiceInstanceIdDetectorSync.ts | 40 ++++++++ .../src/platform/node/index.ts | 1 + 9 files changed, 167 insertions(+), 31 deletions(-) create mode 100644 packages/opentelemetry-resources/src/platform/browser/ServiceInstanceIdDetectorSync.ts create mode 100644 packages/opentelemetry-resources/src/platform/node/ServiceInstanceIdDetectorSync.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e1ec010f15..286a23dba3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/ ### :rocket: (Enhancement) -feat(sdk-trace-base): log resource attributes in ConsoleSpanExporter [#4605](https://github.com/open-telemetry/opentelemetry-js/pull/4605) @pichlermarc +* feat(sdk-trace-base): log resource attributes in ConsoleSpanExporter [#4605](https://github.com/open-telemetry/opentelemetry-js/pull/4605) @pichlermarc +* feat(resources): new experimental detector ServiceInstanceIdDetectorSync that sets the value for `service.instance.id` as random UUID. ### :bug: (Bug Fix) diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index d76534450fd..078a33d9cc7 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -59,6 +59,7 @@ import { processDetector, hostDetector, Resource, + serviceInstanceIdDetectorSync, } from '@opentelemetry/resources'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { logs } from '@opentelemetry/api-logs'; @@ -70,6 +71,7 @@ import { import { SEMRESATTRS_HOST_NAME, SEMRESATTRS_PROCESS_PID, + SEMRESATTRS_SERVICE_INSTANCE_ID, } from '@opentelemetry/semantic-conventions'; const DefaultContextManager = semver.gte(process.version, '14.8.0') @@ -126,6 +128,7 @@ describe('Node SDK', () => { assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider)); assert.ok(!(logs.getLoggerProvider() instanceof LoggerProvider)); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); it('should register a diag logger with OTEL_LOG_LEVEL', () => { @@ -145,6 +148,7 @@ describe('Node SDK', () => { }); delete env.OTEL_LOG_LEVEL; + sdk.shutdown(); }); it('should not register a diag logger with OTEL_LOG_LEVEL unset', () => { @@ -158,6 +162,7 @@ describe('Node SDK', () => { sdk.start(); assert.strictEqual(spy.callCount, 0); + sdk.shutdown(); }); it('should register a tracer provider if an exporter is provided', async () => { @@ -180,6 +185,7 @@ describe('Node SDK', () => { const apiTracerProvider = trace.getTracerProvider() as ProxyTracerProvider; assert.ok(apiTracerProvider.getDelegate() instanceof NodeTracerProvider); + await sdk.shutdown(); }); it('should register a tracer provider if an exporter is provided via env', async () => { @@ -203,6 +209,7 @@ describe('Node SDK', () => { trace.getTracerProvider() as ProxyTracerProvider; assert.ok(apiTracerProvider.getDelegate() instanceof NodeTracerProvider); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); it('should register a tracer provider if span processors are provided', async () => { @@ -240,6 +247,7 @@ describe('Node SDK', () => { assert(listOfProcessors[0] instanceof NoopSpanProcessor); assert(listOfProcessors[1] instanceof SimpleSpanProcessor); assert(listOfProcessors[2] instanceof BatchSpanProcessor); + await sdk.shutdown(); }); it('should register a meter provider if a reader is provided', async () => { @@ -446,6 +454,7 @@ describe('Node SDK', () => { namespace: 'default', version: '0.0.1', }); + await sdk.shutdown(); }); }); @@ -497,6 +506,7 @@ describe('Node SDK', () => { namespace: 'default', version: '0.0.1', }); + await sdk.shutdown(); }); }); @@ -551,6 +561,7 @@ describe('Node SDK', () => { /{\s+"service\.instance\.id":\s+"627cc493",\s+"service\.name":\s+"my-service",\s+"service\.namespace":\s+"default",\s+"service\.version":\s+"0.0.1"\s+}\s*/gm ) ); + await sdk.shutdown(); }); describe('with a faulty environment variable', () => { @@ -578,6 +589,7 @@ describe('Node SDK', () => { 'EnvDetector failed: Attribute value should be a ASCII string with a length not exceed 255 characters.' ) ); + await sdk.shutdown(); }); }); }); @@ -595,6 +607,7 @@ describe('Node SDK', () => { assertServiceResource(resource, { name: 'config-set-name', }); + await sdk.shutdown(); }); it('should configure service name via OTEL_SERVICE_NAME env var', async () => { @@ -609,6 +622,7 @@ describe('Node SDK', () => { name: 'env-set-name', }); delete process.env.OTEL_SERVICE_NAME; + await sdk.shutdown(); }); it('should favor config set service name over OTEL_SERVICE_NAME env set service name', async () => { @@ -625,11 +639,12 @@ describe('Node SDK', () => { name: 'config-set-name', }); delete process.env.OTEL_SERVICE_NAME; + await sdk.shutdown(); }); it('should configure service name via OTEL_RESOURCE_ATTRIBUTES env var', async () => { process.env.OTEL_RESOURCE_ATTRIBUTES = - 'service.name=resource-env-set-name'; + 'service.name=resource-env-set-name,service.instance.id=my-instance-id'; const sdk = new NodeSDK(); sdk.start(); @@ -638,13 +653,15 @@ describe('Node SDK', () => { assertServiceResource(resource, { name: 'resource-env-set-name', + instanceId: 'my-instance-id', }); delete process.env.OTEL_RESOURCE_ATTRIBUTES; + await sdk.shutdown(); }); it('should favor config set service name over OTEL_RESOURCE_ATTRIBUTES env set service name', async () => { process.env.OTEL_RESOURCE_ATTRIBUTES = - 'service.name=resource-env-set-name'; + 'service.name=resource-env-set-name,service.instance.id=my-instance-id'; const sdk = new NodeSDK({ serviceName: 'config-set-name', }); @@ -655,8 +672,55 @@ describe('Node SDK', () => { assertServiceResource(resource, { name: 'config-set-name', + instanceId: 'my-instance-id', }); delete process.env.OTEL_RESOURCE_ATTRIBUTES; + await sdk.shutdown(); + }); + }); + + describe('configureServiceInstanceId', async () => { + it('should configure service instance id via OTEL_RESOURCE_ATTRIBUTES env var', async () => { + process.env.OTEL_RESOURCE_ATTRIBUTES = + 'service.instance.id=627cc493,service.name=my-service'; + const sdk = new NodeSDK(); + + sdk.start(); + const resource = sdk['_resource']; + await resource.waitForAsyncAttributes?.(); + + assertServiceResource(resource, { + name: 'my-service', + instanceId: '627cc493', + }); + delete process.env.OTEL_RESOURCE_ATTRIBUTES; + sdk.shutdown(); + }); + + it('should configure service instance id with random UUID', async () => { + const sdk = new NodeSDK({ + autoDetectResources: true, + resourceDetectors: [ + processDetector, + envDetector, + hostDetector, + serviceInstanceIdDetectorSync, + ], + }); + + sdk.start(); + const resource = sdk['_resource']; + await resource.waitForAsyncAttributes?.(); + + const UUID_REGEX = + /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + assert.equal( + UUID_REGEX.test( + resource.attributes[SEMRESATTRS_SERVICE_INSTANCE_ID]?.toString() || '' + ), + true + ); + await sdk.shutdown(); }); }); @@ -671,7 +735,7 @@ describe('Node SDK', () => { it('should not register a trace provider', async () => { const sdk = new NodeSDK({}); - await sdk.start(); + sdk.start(); assert.strictEqual( (trace.getTracerProvider() as ProxyTracerProvider).getDelegate(), @@ -694,7 +758,7 @@ describe('Node SDK', () => { metricReader: metricReader, autoDetectResources: false, }); - await sdk.start(); + sdk.start(); assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider)); @@ -730,6 +794,7 @@ describe('Node SDK', () => { await resource.waitForAsyncAttributes?.(); assert.deepStrictEqual(resource, Resource.empty()); + await sdk.shutdown(); }); }); }); @@ -758,6 +823,7 @@ describe('Node SDK', () => { assert.strictEqual(span.spanContext().spanId, 'constant-test-span-id'); assert.strictEqual(span.spanContext().traceId, 'constant-test-trace-id'); + await sdk.shutdown(); }); }); }); @@ -786,6 +852,7 @@ describe('setup exporter from env', () => { assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters); assert(listOfProcessors.length === 1); assert(listOfProcessors[0] instanceof BatchSpanProcessor); + await sdk.shutdown(); }); it('ignore env exporter when user provides exporter to sdk config', async () => { const traceExporter = new ConsoleSpanExporter(); @@ -802,6 +869,7 @@ describe('setup exporter from env', () => { assert(listOfProcessors.length === 1); assert(listOfProcessors[0] instanceof SimpleSpanProcessor === false); assert(listOfProcessors[0] instanceof BatchSpanProcessor); + await sdk.shutdown(); }); it('ignores default env exporter when user provides span processor to sdk config', async () => { const traceExporter = new ConsoleSpanExporter(); @@ -819,6 +887,7 @@ describe('setup exporter from env', () => { assert(listOfProcessors.length === 1); assert(listOfProcessors[0] instanceof SimpleSpanProcessor); assert(listOfProcessors[0] instanceof BatchSpanProcessor === false); + await sdk.shutdown(); }); it('ignores env exporter when user provides tracer exporter to sdk config and sets exporter via env', async () => { env.OTEL_TRACES_EXPORTER = 'console'; @@ -837,6 +906,7 @@ describe('setup exporter from env', () => { assert(listOfProcessors[0] instanceof SimpleSpanProcessor === false); assert(listOfProcessors[0] instanceof BatchSpanProcessor); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); it('should only create one span processor when configured using env vars and config', async () => { env.OTEL_TRACES_EXPORTER = 'console'; @@ -852,6 +922,7 @@ describe('setup exporter from env', () => { ); assert.strictEqual(listOfProcessors.length, 1); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); it('use otlp exporter and defined exporter protocol env value', async () => { env.OTEL_TRACES_EXPORTER = 'otlp'; @@ -866,6 +937,7 @@ describe('setup exporter from env', () => { assert(listOfProcessors[0] instanceof BatchSpanProcessor); delete env.OTEL_TRACES_EXPORTER; delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + await sdk.shutdown(); }); it('use noop span processor when user sets env exporter to none', async () => { env.OTEL_TRACES_EXPORTER = 'none'; @@ -879,6 +951,7 @@ describe('setup exporter from env', () => { assert(listOfProcessors.length === 0); assert(activeProcessor instanceof NoopSpanProcessor); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); it('log warning that sdk will not be initialized when exporter is set to none', async () => { env.OTEL_TRACES_EXPORTER = 'none'; @@ -890,16 +963,18 @@ describe('setup exporter from env', () => { 'OTEL_TRACES_EXPORTER contains "none". SDK will not be initialized.' ); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); it('use default otlp exporter when user does not set exporter via env or config', async () => { const sdk = new NodeSDK(); - await sdk.start(); + sdk.start(); const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters); assert(listOfProcessors.length === 1); assert(listOfProcessors[0] instanceof BatchSpanProcessor); + await sdk.shutdown(); }); it('use default otlp exporter when empty value is provided for exporter via env', async () => { env.OTEL_TRACES_EXPORTER = ''; @@ -912,6 +987,7 @@ describe('setup exporter from env', () => { assert(listOfProcessors.length === 1); assert(listOfProcessors[0] instanceof BatchSpanProcessor); env.OTEL_TRACES_EXPORTER = ''; + await sdk.shutdown(); }); it('use only default exporter when none value is provided with other exporters', async () => { @@ -926,6 +1002,7 @@ describe('setup exporter from env', () => { assert(listOfProcessors[0] instanceof BatchSpanProcessor); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); it('log warning that only default exporter will be used since exporter list contains none with other exports ', async () => { env.OTEL_TRACES_EXPORTER = 'otlp,zipkin,none'; @@ -937,6 +1014,7 @@ describe('setup exporter from env', () => { 'OTEL_TRACES_EXPORTER contains "none" along with other exporters. Using default otlp exporter.' ); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); it('should warn that provided exporter value is unrecognized and not able to be set up', async () => { env.OTEL_TRACES_EXPORTER = 'invalid'; @@ -954,6 +1032,7 @@ describe('setup exporter from env', () => { ); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); it('setup zipkin, jaeger and otlp exporters', async () => { env.OTEL_TRACES_EXPORTER = 'zipkin, otlp, jaeger'; @@ -971,6 +1050,7 @@ describe('setup exporter from env', () => { delete env.OTEL_TRACES_EXPORTER; delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + await sdk.shutdown(); }); it('use the console exporter', async () => { env.OTEL_TRACES_EXPORTER = 'console, otlp'; @@ -983,5 +1063,6 @@ describe('setup exporter from env', () => { assert(listOfProcessors[0] instanceof SimpleSpanProcessor); assert(listOfProcessors[1] instanceof BatchSpanProcessor); delete env.OTEL_TRACES_EXPORTER; + await sdk.shutdown(); }); }); diff --git a/package-lock.json b/package-lock.json index bbae633a5d8..73a66d070e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4807,15 +4807,6 @@ "@opentelemetry/api": ">=1.0.0 <1.5.0" } }, - "experimental/packages/sdk-logs/node_modules/@opentelemetry/semantic-conventions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.9.0.tgz", - "integrity": "sha512-po7penSfQ/Z8352lRVDpaBrd9znwA5mHGqXR7nDEiVnxkDFkBIhVf/tKeAJDIq/erFpcRowKFeCsr5eqqcSyFQ==", - "dev": true, - "engines": { - "node": ">=14" - } - }, "experimental/packages/sdk-logs/node_modules/@webpack-cli/configtest": { "version": "2.1.1", "dev": true, @@ -43543,12 +43534,6 @@ } } }, - "@opentelemetry/semantic-conventions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.9.0.tgz", - "integrity": "sha512-po7penSfQ/Z8352lRVDpaBrd9znwA5mHGqXR7nDEiVnxkDFkBIhVf/tKeAJDIq/erFpcRowKFeCsr5eqqcSyFQ==", - "dev": true - }, "@webpack-cli/configtest": { "version": "2.1.1", "dev": true, diff --git a/packages/opentelemetry-resources/src/Resource.ts b/packages/opentelemetry-resources/src/Resource.ts index dfddda8ae1a..d44dbacc4df 100644 --- a/packages/opentelemetry-resources/src/Resource.ts +++ b/packages/opentelemetry-resources/src/Resource.ts @@ -15,7 +15,12 @@ */ import { diag } from '@opentelemetry/api'; -import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; +import { + SEMRESATTRS_SERVICE_NAME, + SEMRESATTRS_TELEMETRY_SDK_LANGUAGE, + SEMRESATTRS_TELEMETRY_SDK_NAME, + SEMRESATTRS_TELEMETRY_SDK_VERSION, +} from '@opentelemetry/semantic-conventions'; import { SDK_INFO } from '@opentelemetry/core'; import { ResourceAttributes } from './types'; import { defaultServiceName } from './platform'; @@ -51,13 +56,13 @@ export class Resource implements IResource { */ static default(): IResource { return new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: defaultServiceName(), - [SemanticResourceAttributes.TELEMETRY_SDK_LANGUAGE]: - SDK_INFO[SemanticResourceAttributes.TELEMETRY_SDK_LANGUAGE], - [SemanticResourceAttributes.TELEMETRY_SDK_NAME]: - SDK_INFO[SemanticResourceAttributes.TELEMETRY_SDK_NAME], - [SemanticResourceAttributes.TELEMETRY_SDK_VERSION]: - SDK_INFO[SemanticResourceAttributes.TELEMETRY_SDK_VERSION], + [SEMRESATTRS_SERVICE_NAME]: defaultServiceName(), + [SEMRESATTRS_TELEMETRY_SDK_LANGUAGE]: + SDK_INFO[SEMRESATTRS_TELEMETRY_SDK_LANGUAGE], + [SEMRESATTRS_TELEMETRY_SDK_NAME]: + SDK_INFO[SEMRESATTRS_TELEMETRY_SDK_NAME], + [SEMRESATTRS_TELEMETRY_SDK_VERSION]: + SDK_INFO[SEMRESATTRS_TELEMETRY_SDK_VERSION], }); } diff --git a/packages/opentelemetry-resources/src/detectors/EnvDetectorSync.ts b/packages/opentelemetry-resources/src/detectors/EnvDetectorSync.ts index 8572323a09d..329d489ec4d 100644 --- a/packages/opentelemetry-resources/src/detectors/EnvDetectorSync.ts +++ b/packages/opentelemetry-resources/src/detectors/EnvDetectorSync.ts @@ -16,7 +16,7 @@ import { diag } from '@opentelemetry/api'; import { getEnv } from '@opentelemetry/core'; -import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; +import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; import { Resource } from '../Resource'; import { DetectorSync, ResourceAttributes } from '../types'; import { ResourceDetectionConfig } from '../config'; @@ -70,7 +70,7 @@ class EnvDetectorSync implements DetectorSync { } if (serviceName) { - attributes[SemanticResourceAttributes.SERVICE_NAME] = serviceName; + attributes[SEMRESATTRS_SERVICE_NAME] = serviceName; } return new Resource(attributes); diff --git a/packages/opentelemetry-resources/src/platform/browser/ServiceInstanceIdDetectorSync.ts b/packages/opentelemetry-resources/src/platform/browser/ServiceInstanceIdDetectorSync.ts new file mode 100644 index 00000000000..d79fa1f4eaf --- /dev/null +++ b/packages/opentelemetry-resources/src/platform/browser/ServiceInstanceIdDetectorSync.ts @@ -0,0 +1,22 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { noopDetectorSync } from '../../detectors/NoopDetectorSync'; + +/** + * @experimental + */ +export const serviceInstanceIdDetectorSync = noopDetectorSync; diff --git a/packages/opentelemetry-resources/src/platform/browser/index.ts b/packages/opentelemetry-resources/src/platform/browser/index.ts index 9ed1b0151b1..47f5cf301ef 100644 --- a/packages/opentelemetry-resources/src/platform/browser/index.ts +++ b/packages/opentelemetry-resources/src/platform/browser/index.ts @@ -21,3 +21,4 @@ export * from './HostDetectorSync'; export * from './OSDetectorSync'; export * from './ProcessDetector'; export * from './ProcessDetectorSync'; +export * from './ServiceInstanceIdDetectorSync'; diff --git a/packages/opentelemetry-resources/src/platform/node/ServiceInstanceIdDetectorSync.ts b/packages/opentelemetry-resources/src/platform/node/ServiceInstanceIdDetectorSync.ts new file mode 100644 index 00000000000..9196bcba51e --- /dev/null +++ b/packages/opentelemetry-resources/src/platform/node/ServiceInstanceIdDetectorSync.ts @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SEMRESATTRS_SERVICE_INSTANCE_ID } from '@opentelemetry/semantic-conventions'; +import { Resource } from '../../Resource'; +import { DetectorSync, ResourceAttributes } from '../../types'; +import { ResourceDetectionConfig } from '../../config'; +import { randomUUID } from 'crypto'; + +/** + * ServiceInstanceIdDetectorSync detects the resources related to the service instance ID. + */ +class ServiceInstanceIdDetectorSync implements DetectorSync { + detect(_config?: ResourceDetectionConfig): Resource { + const attributes: ResourceAttributes = { + [SEMRESATTRS_SERVICE_INSTANCE_ID]: randomUUID(), + }; + + return new Resource(attributes); + } +} + +/** + * @experimental + */ +export const serviceInstanceIdDetectorSync = + new ServiceInstanceIdDetectorSync(); diff --git a/packages/opentelemetry-resources/src/platform/node/index.ts b/packages/opentelemetry-resources/src/platform/node/index.ts index 9ed1b0151b1..47f5cf301ef 100644 --- a/packages/opentelemetry-resources/src/platform/node/index.ts +++ b/packages/opentelemetry-resources/src/platform/node/index.ts @@ -21,3 +21,4 @@ export * from './HostDetectorSync'; export * from './OSDetectorSync'; export * from './ProcessDetector'; export * from './ProcessDetectorSync'; +export * from './ServiceInstanceIdDetectorSync';