Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(node-sdk): add serviceName config option #2867

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
* feat(opentelemetry-exporter-prometheus): export PrometheusSerializer #3034 @matschaffer

### :bug: (Bug Fix)
Expand Down
4 changes: 4 additions & 0 deletions experimental/packages/opentelemetry-sdk-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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: <https://opentelemetry.io/>
Expand Down
30 changes: 22 additions & 8 deletions experimental/packages/opentelemetry-sdk-node/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -50,13 +53,16 @@ export class NodeSDK {

private _tracerProvider?: NodeTracerProvider;
private _meterProvider?: MeterProvider;
private _serviceName?: string;

/**
* Create a new NodeJS SDK instance
*/
public constructor(configuration: Partial<NodeSDKConfiguration> = {}) {
this._resource = configuration.resource ?? new Resource({});

this._serviceName = configuration.serviceName;

this._autoDetectResources = configuration.autoDetectResources ?? true;

if (configuration.spanProcessor || configuration.traceExporter) {
Expand Down Expand Up @@ -113,7 +119,9 @@ export class NodeSDK {
}

/** Detect resource attributes */
public async detectResources(config?: ResourceDetectionConfig): Promise<void> {
public async detectResources(
config?: ResourceDetectionConfig
): Promise<void> {
const internalConfig: ResourceDetectionConfig = {
detectors: [ envDetector, processDetector],
...config,
Expand All @@ -135,6 +143,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,
Expand Down
9 changes: 5 additions & 4 deletions experimental/packages/opentelemetry-sdk-node/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -34,6 +34,7 @@ export interface NodeSDKConfiguration {
instrumentations: InstrumentationOption[];
resource: Resource;
sampler: Sampler;
serviceName?: string;
spanProcessor: SpanProcessor;
traceExporter: SpanExporter;
spanLimits: SpanLimits;
Expand Down
72 changes: 72 additions & 0 deletions experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export const assertServiceResource = (
resource: Resource,
validations: {
name: string;
instanceId: string;
instanceId?: string;
namespace?: string;
version?: string;
}
Expand Down