From a95577cc9c22f737b4a13ad09eacfb9b9a4a9e73 Mon Sep 17 00:00:00 2001
From: Naseem Ullah <24660299+naseemkullah@users.noreply.github.com>
Date: Mon, 23 May 2022 20:25:29 -0400
Subject: [PATCH] feat(node-sdk): add serviceName config option
---
experimental/CHANGELOG.md | 1 +
.../packages/opentelemetry-sdk-node/README.md | 4 ++
.../opentelemetry-sdk-node/src/sdk.ts | 31 +++++---
.../opentelemetry-sdk-node/src/types.ts | 9 +--
.../opentelemetry-sdk-node/test/sdk.test.ts | 72 +++++++++++++++++++
.../test/util/resource-assertions.ts | 2 +-
6 files changed, 106 insertions(+), 13 deletions(-)
diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md
index 205dd3123c3..4d57f6d2143 100644
--- a/experimental/CHANGELOG.md
+++ b/experimental/CHANGELOG.md
@@ -12,6 +12,7 @@ All notable changes to experimental packages in this project will be documented
* feat(opentelemetry-instrumentation-fetch): optionally ignore network events #3028 @gregolsen
* feat(http-instrumentation): record exceptions in http instrumentation #3008 @luismiramirez
+* feat(node-sdk): add serviceName config option #2867 @naseemkullah
### :bug: (Bug Fix)
diff --git a/experimental/packages/opentelemetry-sdk-node/README.md b/experimental/packages/opentelemetry-sdk-node/README.md
index 841bff28247..a21de3c7411 100644
--- a/experimental/packages/opentelemetry-sdk-node/README.md
+++ b/experimental/packages/opentelemetry-sdk-node/README.md
@@ -128,6 +128,10 @@ Configure a trace exporter. If an exporter OR span processor is not configured,
Configure tracing parameters. These are the same trace parameters used to [configure a tracer](../../../packages/opentelemetry-sdk-trace-base/src/types.ts#L71).
+### serviceName
+
+Configure the [service name](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md#service).
+
## Useful links
- For more information on OpenTelemetry, visit:
diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts
index 6f9ddb1d23c..126d0437dc2 100644
--- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts
+++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts
@@ -14,23 +14,26 @@
* limitations under the License.
*/
-import { TextMapPropagator } from '@opentelemetry/api';
+import { ContextManager, TextMapPropagator } from '@opentelemetry/api';
import { metrics } from '@opentelemetry/api-metrics';
-import { ContextManager } from '@opentelemetry/api';
-import { MeterProvider, MetricReader } from '@opentelemetry/sdk-metrics-base';
import {
InstrumentationOption,
- registerInstrumentations,
+ registerInstrumentations
} from '@opentelemetry/instrumentation';
-import { NodeTracerConfig, NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import {
detectResources,
envDetector,
processDetector,
Resource,
- ResourceDetectionConfig,
+ ResourceDetectionConfig
} from '@opentelemetry/resources';
-import { BatchSpanProcessor, SpanProcessor } from '@opentelemetry/sdk-trace-base';
+import { MeterProvider, MetricReader } from '@opentelemetry/sdk-metrics-base';
+import {
+ BatchSpanProcessor,
+ SpanProcessor
+} from '@opentelemetry/sdk-trace-base';
+import { NodeTracerConfig, NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
+import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { NodeSDKConfiguration } from './types';
/** This class represents everything needed to register a fully configured OpenTelemetry Node.js SDK */
@@ -50,6 +53,7 @@ export class NodeSDK {
private _tracerProvider?: NodeTracerProvider;
private _meterProvider?: MeterProvider;
+ private _serviceName?: string;
/**
* Create a new NodeJS SDK instance
@@ -57,6 +61,9 @@ export class NodeSDK {
public constructor(configuration: Partial = {}) {
this._resource = configuration.resource ?? new Resource({});
+
+ this._serviceName = configuration.serviceName;
+
this._autoDetectResources = configuration.autoDetectResources ?? true;
if (configuration.spanProcessor || configuration.traceExporter) {
@@ -113,7 +120,9 @@ export class NodeSDK {
}
/** Detect resource attributes */
- public async detectResources(config?: ResourceDetectionConfig): Promise {
+ public async detectResources(
+ config?: ResourceDetectionConfig
+ ): Promise {
const internalConfig: ResourceDetectionConfig = {
detectors: [ envDetector, processDetector],
...config,
@@ -135,6 +144,12 @@ export class NodeSDK {
await this.detectResources();
}
+ this._resource = this._serviceName === undefined
+ ? this._resource
+ : this._resource.merge(new Resource(
+ {[SemanticResourceAttributes.SERVICE_NAME]: this._serviceName}
+ ));
+
if (this._tracerProviderConfig) {
const tracerProvider = new NodeTracerProvider({
...this._tracerProviderConfig.tracerConfig,
diff --git a/experimental/packages/opentelemetry-sdk-node/src/types.ts b/experimental/packages/opentelemetry-sdk-node/src/types.ts
index ea93ddae167..90c1e08401d 100644
--- a/experimental/packages/opentelemetry-sdk-node/src/types.ts
+++ b/experimental/packages/opentelemetry-sdk-node/src/types.ts
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-import { SpanAttributes, TextMapPropagator, Sampler } from '@opentelemetry/api';
-import type { ContextManager } from '@opentelemetry/api';
+import type { ContextManager, SpanAttributes } from '@opentelemetry/api';
+import { Sampler, TextMapPropagator } from '@opentelemetry/api';
import { InstrumentationOption } from '@opentelemetry/instrumentation';
-import { MetricReader } from '@opentelemetry/sdk-metrics-base';
import { Resource } from '@opentelemetry/resources';
+import { MetricReader } from '@opentelemetry/sdk-metrics-base';
import {
SpanExporter,
- SpanProcessor,
SpanLimits,
+ SpanProcessor
} from '@opentelemetry/sdk-trace-base';
export interface NodeSDKConfiguration {
@@ -34,6 +34,7 @@ export interface NodeSDKConfiguration {
instrumentations: InstrumentationOption[];
resource: Resource;
sampler: Sampler;
+ serviceName?: string;
spanProcessor: SpanProcessor;
traceExporter: SpanExporter;
spanLimits: SpanLimits;
diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts
index 14b362209c0..217800c9c05 100644
--- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts
+++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts
@@ -261,4 +261,76 @@ describe('Node SDK', () => {
});
});
});
+
+ describe('configureServiceName', async () => {
+ it('should configure service name via config', async () => {
+ const sdk = new NodeSDK({
+ serviceName: 'config-set-name',
+ });
+
+ await sdk.start();
+ const resource = sdk['_resource'];
+
+ assertServiceResource(resource, {
+ name: 'config-set-name',
+ });
+ });
+
+ it('should configure service name via OTEL_SERVICE_NAME env var', async () => {
+ process.env.OTEL_SERVICE_NAME='env-set-name';
+ const sdk = new NodeSDK();
+
+ await sdk.start();
+ const resource = sdk['_resource'];
+
+ assertServiceResource(resource, {
+ name: 'env-set-name',
+ });
+ delete process.env.OTEL_SERVICE_NAME;
+ });
+
+ it('should favor config set service name over OTEL_SERVICE_NAME env set service name', async () => {
+ process.env.OTEL_SERVICE_NAME='env-set-name';
+ const sdk = new NodeSDK({
+ serviceName: 'config-set-name',
+ });
+
+ await sdk.start();
+ const resource = sdk['_resource'];
+
+ assertServiceResource(resource, {
+ name: 'config-set-name',
+ });
+ delete process.env.OTEL_SERVICE_NAME;
+ });
+
+
+ it('should configure service name via OTEL_RESOURCE_ATTRIBUTES env var', async () => {
+ process.env.OTEL_RESOURCE_ATTRIBUTES = 'service.name=resource-env-set-name';
+ const sdk = new NodeSDK();
+
+ await sdk.start();
+ const resource = sdk['_resource'];
+
+ assertServiceResource(resource, {
+ name: 'resource-env-set-name',
+ });
+ delete process.env.OTEL_RESOURCE_ATTRIBUTES;
+ });
+
+ 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';
+ const sdk = new NodeSDK({
+ serviceName: 'config-set-name',
+ });
+
+ await sdk.start();
+ const resource = sdk['_resource'];
+
+ assertServiceResource(resource, {
+ name: 'config-set-name',
+ });
+ delete process.env.OTEL_RESOURCE_ATTRIBUTES;
+ });
+ });
});
diff --git a/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts b/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts
index 206c9bcf86a..331fed6e8ec 100644
--- a/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts
+++ b/experimental/packages/opentelemetry-sdk-node/test/util/resource-assertions.ts
@@ -232,7 +232,7 @@ export const assertServiceResource = (
resource: Resource,
validations: {
name: string;
- instanceId: string;
+ instanceId?: string;
namespace?: string;
version?: string;
}