Skip to content

Commit e96cfed

Browse files
committed
feat(node-sdk): implements service.instance.id
Implements `service.instance.id` Signed-off-by: maryliag <[email protected]>
1 parent c046867 commit e96cfed

File tree

12 files changed

+188
-45
lines changed

12 files changed

+188
-45
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/
1111

1212
### :rocket: (Enhancement)
1313

14+
feat(sdk-node): set value for `service.instance.id` as random UUID as default. The value can still be overwritten by environment variable or cloud provider.
15+
1416
### :bug: (Bug Fix)
1517

1618
* fix(sdk-trace-web): fix invalid timings in span events [#4486](https://github.com/open-telemetry/opentelemetry-js/pull/4486) @Abinet18

experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import {
7070
import {
7171
SEMRESATTRS_HOST_NAME,
7272
SEMRESATTRS_PROCESS_PID,
73+
SEMRESATTRS_SERVICE_INSTANCE_ID,
7374
} from '@opentelemetry/semantic-conventions';
7475

7576
const DefaultContextManager = semver.gte(process.version, '14.8.0')
@@ -126,6 +127,7 @@ describe('Node SDK', () => {
126127
assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider));
127128
assert.ok(!(logs.getLoggerProvider() instanceof LoggerProvider));
128129
delete env.OTEL_TRACES_EXPORTER;
130+
await sdk.shutdown();
129131
});
130132

131133
it('should register a diag logger with OTEL_LOG_LEVEL', () => {
@@ -145,6 +147,7 @@ describe('Node SDK', () => {
145147
});
146148

147149
delete env.OTEL_LOG_LEVEL;
150+
sdk.shutdown();
148151
});
149152

150153
it('should not register a diag logger with OTEL_LOG_LEVEL unset', () => {
@@ -158,6 +161,7 @@ describe('Node SDK', () => {
158161
sdk.start();
159162

160163
assert.strictEqual(spy.callCount, 0);
164+
sdk.shutdown();
161165
});
162166

163167
it('should register a tracer provider if an exporter is provided', async () => {
@@ -180,6 +184,7 @@ describe('Node SDK', () => {
180184
const apiTracerProvider =
181185
trace.getTracerProvider() as ProxyTracerProvider;
182186
assert.ok(apiTracerProvider.getDelegate() instanceof NodeTracerProvider);
187+
await sdk.shutdown();
183188
});
184189

185190
it('should register a tracer provider if an exporter is provided via env', async () => {
@@ -203,6 +208,7 @@ describe('Node SDK', () => {
203208
trace.getTracerProvider() as ProxyTracerProvider;
204209
assert.ok(apiTracerProvider.getDelegate() instanceof NodeTracerProvider);
205210
delete env.OTEL_TRACES_EXPORTER;
211+
await sdk.shutdown();
206212
});
207213

208214
it('should register a tracer provider if span processors are provided', async () => {
@@ -240,6 +246,7 @@ describe('Node SDK', () => {
240246
assert(listOfProcessors[0] instanceof NoopSpanProcessor);
241247
assert(listOfProcessors[1] instanceof SimpleSpanProcessor);
242248
assert(listOfProcessors[2] instanceof BatchSpanProcessor);
249+
await sdk.shutdown();
243250
});
244251

245252
it('should register a meter provider if a reader is provided', async () => {
@@ -547,6 +554,7 @@ describe('Node SDK', () => {
547554
namespace: 'default',
548555
version: '0.0.1',
549556
});
557+
await sdk.shutdown();
550558
});
551559
});
552560

@@ -598,6 +606,7 @@ describe('Node SDK', () => {
598606
namespace: 'default',
599607
version: '0.0.1',
600608
});
609+
await sdk.shutdown();
601610
});
602611
});
603612

@@ -652,6 +661,7 @@ describe('Node SDK', () => {
652661
/{\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
653662
)
654663
);
664+
await sdk.shutdown();
655665
});
656666

657667
describe('with a faulty environment variable', () => {
@@ -679,6 +689,7 @@ describe('Node SDK', () => {
679689
'EnvDetector failed: Attribute value should be a ASCII string with a length not exceed 255 characters.'
680690
)
681691
);
692+
await sdk.shutdown();
682693
});
683694
});
684695
});
@@ -696,6 +707,7 @@ describe('Node SDK', () => {
696707
assertServiceResource(resource, {
697708
name: 'config-set-name',
698709
});
710+
await sdk.shutdown();
699711
});
700712

701713
it('should configure service name via OTEL_SERVICE_NAME env var', async () => {
@@ -710,6 +722,7 @@ describe('Node SDK', () => {
710722
name: 'env-set-name',
711723
});
712724
delete process.env.OTEL_SERVICE_NAME;
725+
await sdk.shutdown();
713726
});
714727

715728
it('should favor config set service name over OTEL_SERVICE_NAME env set service name', async () => {
@@ -726,11 +739,12 @@ describe('Node SDK', () => {
726739
name: 'config-set-name',
727740
});
728741
delete process.env.OTEL_SERVICE_NAME;
742+
await sdk.shutdown();
729743
});
730744

731745
it('should configure service name via OTEL_RESOURCE_ATTRIBUTES env var', async () => {
732746
process.env.OTEL_RESOURCE_ATTRIBUTES =
733-
'service.name=resource-env-set-name';
747+
'service.name=resource-env-set-name,service.instance.id=my-instance-id';
734748
const sdk = new NodeSDK();
735749

736750
sdk.start();
@@ -739,13 +753,15 @@ describe('Node SDK', () => {
739753

740754
assertServiceResource(resource, {
741755
name: 'resource-env-set-name',
756+
instanceId: 'my-instance-id',
742757
});
743758
delete process.env.OTEL_RESOURCE_ATTRIBUTES;
759+
await sdk.shutdown();
744760
});
745761

746762
it('should favor config set service name over OTEL_RESOURCE_ATTRIBUTES env set service name', async () => {
747763
process.env.OTEL_RESOURCE_ATTRIBUTES =
748-
'service.name=resource-env-set-name';
764+
'service.name=resource-env-set-name,service.instance.id=my-instance-id';
749765
const sdk = new NodeSDK({
750766
serviceName: 'config-set-name',
751767
});
@@ -756,8 +772,45 @@ describe('Node SDK', () => {
756772

757773
assertServiceResource(resource, {
758774
name: 'config-set-name',
775+
instanceId: 'my-instance-id',
776+
});
777+
delete process.env.OTEL_RESOURCE_ATTRIBUTES;
778+
await sdk.shutdown();
779+
});
780+
});
781+
782+
describe('configureServiceInstanceId', async () => {
783+
it('should configure service instance id via OTEL_RESOURCE_ATTRIBUTES env var', async () => {
784+
process.env.OTEL_RESOURCE_ATTRIBUTES =
785+
'service.instance.id=627cc493,service.name=my-service';
786+
const sdk = new NodeSDK();
787+
788+
sdk.start();
789+
const resource = sdk['_resource'];
790+
await resource.waitForAsyncAttributes?.();
791+
792+
assertServiceResource(resource, {
793+
name: 'my-service',
794+
instanceId: '627cc493',
759795
});
760796
delete process.env.OTEL_RESOURCE_ATTRIBUTES;
797+
sdk.shutdown();
798+
});
799+
800+
it('should configure service instance id with random UUID', async () => {
801+
process.env.OTEL_RESOURCE_ATTRIBUTES = 'service.name=my-service';
802+
const sdk = new NodeSDK();
803+
804+
sdk.start();
805+
const resource = sdk['_resource'];
806+
await resource.waitForAsyncAttributes?.();
807+
808+
assert.equal(
809+
resource.attributes[SEMRESATTRS_SERVICE_INSTANCE_ID]?.toString().length,
810+
36
811+
);
812+
delete process.env.OTEL_RESOURCE_ATTRIBUTES;
813+
await sdk.shutdown();
761814
});
762815
});
763816

@@ -772,7 +825,7 @@ describe('Node SDK', () => {
772825

773826
it('should not register a trace provider', async () => {
774827
const sdk = new NodeSDK({});
775-
await sdk.start();
828+
sdk.start();
776829

777830
assert.strictEqual(
778831
(trace.getTracerProvider() as ProxyTracerProvider).getDelegate(),
@@ -795,7 +848,7 @@ describe('Node SDK', () => {
795848
metricReader: metricReader,
796849
autoDetectResources: false,
797850
});
798-
await sdk.start();
851+
sdk.start();
799852

800853
assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider));
801854

@@ -831,6 +884,7 @@ describe('Node SDK', () => {
831884
await resource.waitForAsyncAttributes?.();
832885

833886
assert.deepStrictEqual(resource, Resource.empty());
887+
await sdk.shutdown();
834888
});
835889
});
836890
});
@@ -859,6 +913,7 @@ describe('Node SDK', () => {
859913

860914
assert.strictEqual(span.spanContext().spanId, 'constant-test-span-id');
861915
assert.strictEqual(span.spanContext().traceId, 'constant-test-trace-id');
916+
await sdk.shutdown();
862917
});
863918
});
864919
});
@@ -887,6 +942,7 @@ describe('setup exporter from env', () => {
887942
assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters);
888943
assert(listOfProcessors.length === 1);
889944
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
945+
await sdk.shutdown();
890946
});
891947
it('ignore env exporter when user provides exporter to sdk config', async () => {
892948
const traceExporter = new ConsoleSpanExporter();
@@ -903,6 +959,7 @@ describe('setup exporter from env', () => {
903959
assert(listOfProcessors.length === 1);
904960
assert(listOfProcessors[0] instanceof SimpleSpanProcessor === false);
905961
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
962+
await sdk.shutdown();
906963
});
907964
it('ignores default env exporter when user provides span processor to sdk config', async () => {
908965
const traceExporter = new ConsoleSpanExporter();
@@ -920,6 +977,7 @@ describe('setup exporter from env', () => {
920977
assert(listOfProcessors.length === 1);
921978
assert(listOfProcessors[0] instanceof SimpleSpanProcessor);
922979
assert(listOfProcessors[0] instanceof BatchSpanProcessor === false);
980+
await sdk.shutdown();
923981
});
924982
it('ignores env exporter when user provides tracer exporter to sdk config and sets exporter via env', async () => {
925983
env.OTEL_TRACES_EXPORTER = 'console';
@@ -938,6 +996,7 @@ describe('setup exporter from env', () => {
938996
assert(listOfProcessors[0] instanceof SimpleSpanProcessor === false);
939997
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
940998
delete env.OTEL_TRACES_EXPORTER;
999+
await sdk.shutdown();
9411000
});
9421001
it('should only create one span processor when configured using env vars and config', async () => {
9431002
env.OTEL_TRACES_EXPORTER = 'console';
@@ -953,6 +1012,7 @@ describe('setup exporter from env', () => {
9531012
);
9541013
assert.strictEqual(listOfProcessors.length, 1);
9551014
delete env.OTEL_TRACES_EXPORTER;
1015+
await sdk.shutdown();
9561016
});
9571017
it('use otlp exporter and defined exporter protocol env value', async () => {
9581018
env.OTEL_TRACES_EXPORTER = 'otlp';
@@ -967,6 +1027,7 @@ describe('setup exporter from env', () => {
9671027
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
9681028
delete env.OTEL_TRACES_EXPORTER;
9691029
delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL;
1030+
await sdk.shutdown();
9701031
});
9711032
it('use noop span processor when user sets env exporter to none', async () => {
9721033
env.OTEL_TRACES_EXPORTER = 'none';
@@ -980,6 +1041,7 @@ describe('setup exporter from env', () => {
9801041
assert(listOfProcessors.length === 0);
9811042
assert(activeProcessor instanceof NoopSpanProcessor);
9821043
delete env.OTEL_TRACES_EXPORTER;
1044+
await sdk.shutdown();
9831045
});
9841046
it('log warning that sdk will not be initialized when exporter is set to none', async () => {
9851047
env.OTEL_TRACES_EXPORTER = 'none';
@@ -991,16 +1053,18 @@ describe('setup exporter from env', () => {
9911053
'OTEL_TRACES_EXPORTER contains "none". SDK will not be initialized.'
9921054
);
9931055
delete env.OTEL_TRACES_EXPORTER;
1056+
await sdk.shutdown();
9941057
});
9951058
it('use default otlp exporter when user does not set exporter via env or config', async () => {
9961059
const sdk = new NodeSDK();
997-
await sdk.start();
1060+
sdk.start();
9981061

9991062
const listOfProcessors =
10001063
sdk['_tracerProvider']!['_registeredSpanProcessors']!;
10011064
assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters);
10021065
assert(listOfProcessors.length === 1);
10031066
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
1067+
await sdk.shutdown();
10041068
});
10051069
it('use default otlp exporter when empty value is provided for exporter via env', async () => {
10061070
env.OTEL_TRACES_EXPORTER = '';
@@ -1013,6 +1077,7 @@ describe('setup exporter from env', () => {
10131077
assert(listOfProcessors.length === 1);
10141078
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
10151079
env.OTEL_TRACES_EXPORTER = '';
1080+
await sdk.shutdown();
10161081
});
10171082

10181083
it('use only default exporter when none value is provided with other exporters', async () => {
@@ -1027,6 +1092,7 @@ describe('setup exporter from env', () => {
10271092
assert(listOfProcessors[0] instanceof BatchSpanProcessor);
10281093

10291094
delete env.OTEL_TRACES_EXPORTER;
1095+
await sdk.shutdown();
10301096
});
10311097
it('log warning that only default exporter will be used since exporter list contains none with other exports ', async () => {
10321098
env.OTEL_TRACES_EXPORTER = 'otlp,zipkin,none';
@@ -1038,6 +1104,7 @@ describe('setup exporter from env', () => {
10381104
'OTEL_TRACES_EXPORTER contains "none" along with other exporters. Using default otlp exporter.'
10391105
);
10401106
delete env.OTEL_TRACES_EXPORTER;
1107+
await sdk.shutdown();
10411108
});
10421109
it('should warn that provided exporter value is unrecognized and not able to be set up', async () => {
10431110
env.OTEL_TRACES_EXPORTER = 'invalid';
@@ -1055,6 +1122,7 @@ describe('setup exporter from env', () => {
10551122
);
10561123

10571124
delete env.OTEL_TRACES_EXPORTER;
1125+
await sdk.shutdown();
10581126
});
10591127
it('setup zipkin, jaeger and otlp exporters', async () => {
10601128
env.OTEL_TRACES_EXPORTER = 'zipkin, otlp, jaeger';
@@ -1072,6 +1140,7 @@ describe('setup exporter from env', () => {
10721140

10731141
delete env.OTEL_TRACES_EXPORTER;
10741142
delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL;
1143+
await sdk.shutdown();
10751144
});
10761145
it('use the console exporter', async () => {
10771146
env.OTEL_TRACES_EXPORTER = 'console, otlp';
@@ -1084,5 +1153,6 @@ describe('setup exporter from env', () => {
10841153
assert(listOfProcessors[0] instanceof SimpleSpanProcessor);
10851154
assert(listOfProcessors[1] instanceof BatchSpanProcessor);
10861155
delete env.OTEL_TRACES_EXPORTER;
1156+
await sdk.shutdown();
10871157
});
10881158
});

experimental/packages/sdk-logs/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
},
103103
"dependencies": {
104104
"@opentelemetry/core": "1.23.0",
105-
"@opentelemetry/resources": "1.23.0"
105+
"@opentelemetry/resources": "1.23.0",
106+
"@opentelemetry/semantic-conventions": "1.23.0"
106107
}
107108
}

experimental/packages/sdk-logs/test/common/LoggerProvider.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { loadDefaultConfig } from '../../src/config';
2424
import { DEFAULT_LOGGER_NAME } from './../../src/LoggerProvider';
2525
import { MultiLogRecordProcessor } from '../../src/MultiLogRecordProcessor';
2626
import { Logger } from '../../src/Logger';
27+
import { assertServiceResource } from './utils';
2728

2829
describe('LoggerProvider', () => {
2930
let envSource: Record<string, any>;
@@ -60,14 +61,14 @@ describe('LoggerProvider', () => {
6061
it('should have default resource if not pass', () => {
6162
const provider = new LoggerProvider();
6263
const { resource } = provider['_sharedState'];
63-
assert.deepStrictEqual(resource, Resource.default());
64+
assertServiceResource(resource, Resource.default());
6465
});
6566

6667
it('should fallback to default resource attrs', () => {
6768
const passedInResource = new Resource({ foo: 'bar' });
6869
const provider = new LoggerProvider({ resource: passedInResource });
6970
const { resource } = provider['_sharedState'];
70-
assert.deepStrictEqual(
71+
assertServiceResource(
7172
resource,
7273
Resource.default().merge(passedInResource)
7374
);

0 commit comments

Comments
 (0)