Skip to content

Commit

Permalink
feat(sdk-node): configure trace exporter with environment variables (o…
Browse files Browse the repository at this point in the history
…pen-telemetry#3143)

* feat(sdk-node): wip add functionality to retrieve list of exporters

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): wip add functionality to configure otlp

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): wip add otlp protocol retrieval

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): wip configure span processor

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): wip create node tracer providers

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add otlp exporter tests

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): refactor otlp protocol logic

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): refactor configure exporter function

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add zipkin and jaeger exporters and tests

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add console exporter and tests

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add console exporter and tests

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): handle invalid exporters case

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix tests failing due to newly added feature

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add more unit tests

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add changelog

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add documentation to readme

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add comments to public methods

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add integration tests

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix lint

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix lint in readme

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix lint in readme

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): refactor to use class for tracer with env exporters

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix lint

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): refactor sdk class and tests

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix typo

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix typo

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix metric test

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix lint and refactor

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix lint

Signed-off-by: Svetlana Brennan <[email protected]>

* Rename tracerProviderWithEnvExporter.ts to TracerProviderWithEnvExporter.ts

* feat(sdk-node): move adding span processors to different class

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add more tests and reconfigure some tests

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add missing env value deletion after test

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): fix lint

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): override register method and upate logic and tests

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): add override for addspanprocessor method

Signed-off-by: Svetlana Brennan <[email protected]>

* feat(sdk-node): undo accidental changelog removal

Signed-off-by: Svetlana Brennan <[email protected]>

* Undo accidental empty change heading

Signed-off-by: Svetlana Brennan <[email protected]>
Co-authored-by: Valentin Marchaud <[email protected]>
  • Loading branch information
svetlanabrennan and vmarchaud authored Sep 29, 2022
1 parent afe0657 commit 6b8bb15
Show file tree
Hide file tree
Showing 9 changed files with 672 additions and 19 deletions.
2 changes: 2 additions & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ All notable changes to experimental packages in this project will be documented

### :rocket: (Enhancement)

* feat(sdk-node): configure trace exporter with environment variables [#3143](https://github.com/open-telemetry/opentelemetry-js/pull/3143) @svetlanabrennan

### :bug: (Bug Fix)

### :books: (Refine Doc)
Expand Down
26 changes: 25 additions & 1 deletion experimental/packages/opentelemetry-sdk-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Configure a custom sampler. By default, all traces will be sampled.

### traceExporter

Configure a trace exporter. If an exporter OR span processor is not configured, the tracing SDK will not be initialized and registered. If an exporter is configured, it will be used with a [BatchSpanProcessor](../../../packages/opentelemetry-sdk-trace-base/src/platform/node/export/BatchSpanProcessor.ts).
Configure a trace exporter. If an exporter is configured, it will be used with a [BatchSpanProcessor](../../../packages/opentelemetry-sdk-trace-base/src/platform/node/export/BatchSpanProcessor.ts). If an exporter OR span processor is not configured programatically, this package will auto setup the default `otlp` exporter with `http/protobuf` protocol with a `BatchSpanProcessor`.

### spanLimits

Expand All @@ -139,6 +139,30 @@ Configure tracing parameters. These are the same trace parameters used to [confi

Configure the [service name](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md#service).

## Configure Trace Exporter from Environment

This is an alternative to programmatically configuring an exporter or span processor. This package will auto setup the default `otlp` exporter with `http/protobuf` protocol if `traceExporter` or `spanProcessor` hasn't been passed into the `NodeSDK` constructor.

### Exporters

| Environment variable | Description |
|----------------------|-------------|
| OTEL_TRACES_EXPORTER | List of exporters to be used for tracing, separated by commas. Options include `otlp`, `jaeger`, `zipkin`, and `none`. Default is `otlp`. `none` means no autoconfigured exporter.

### OTLP Exporter

| Environment variable | Description |
|----------------------|-------------|
| OTEL_EXPORTER_OTLP_PROTOCOL | The transport protocol to use on OTLP trace, metric, and log requests. Options include `grpc`, `http/protobuf`, and `http/json`. Default is `http/protobuf`. |
| OTEL_EXPORTER_OTLP_TRACES_PROTOCOL | The transport protocol to use on OTLP trace requests. Options include `grpc`, `http/protobuf`, and `http/json`. Default is `http/protobuf`. |
| OTEL_EXPORTER_OTLP_METRICS_PROTOCOL | The transport protocol to use on OTLP metric requests. Options include `grpc`, `http/protobuf`, and `http/json`. Default is `http/protobuf`. |

Additionally, you can specify other applicable environment variables that apply to each exporter such as the following:

- [OTLP exporter environment configuration](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options)
- [Zipkin exporter environment configuration](https://github.com/open-telemetry/opentelemetry-specification/blob/6ce62202e5407518e19c56c445c13682ef51a51d/specification/sdk-environment-variables.md#zipkin-exporter)
- [Jaeger exporter environment configuration](https://github.com/open-telemetry/opentelemetry-specification/blob/6ce62202e5407518e19c56c445c13682ef51a51d/specification/sdk-environment-variables.md#jaeger-exporter)

## Useful links

- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
Expand Down
5 changes: 5 additions & 0 deletions experimental/packages/opentelemetry-sdk-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
"access": "public"
},
"dependencies": {
"@opentelemetry/exporter-jaeger": "1.7.0",
"@opentelemetry/exporter-trace-otlp-grpc": "0.33.0",
"@opentelemetry/exporter-trace-otlp-http": "0.33.0",
"@opentelemetry/exporter-trace-otlp-proto": "0.33.0",
"@opentelemetry/exporter-zipkin": "1.7.0",
"@opentelemetry/api-metrics": "0.33.0",
"@opentelemetry/core": "1.7.0",
"@opentelemetry/instrumentation": "0.33.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* 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 { diag } from '@opentelemetry/api';
import { getEnv, getEnvWithoutDefaults } from '@opentelemetry/core';
import { ConsoleSpanExporter, SpanExporter, BatchSpanProcessor, SimpleSpanProcessor, SDKRegistrationConfig, SpanProcessor } from '@opentelemetry/sdk-trace-base';
import { NodeTracerConfig, NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { OTLPTraceExporter as OTLPProtoTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { OTLPTraceExporter as OTLPHttpTraceExporter} from '@opentelemetry/exporter-trace-otlp-http';
import { OTLPTraceExporter as OTLPGrpcTraceExporter} from '@opentelemetry/exporter-trace-otlp-grpc';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';

export class TracerProviderWithEnvExporters extends NodeTracerProvider {
private _configuredExporters: SpanExporter[] = [];
private _spanProcessors: SpanProcessor[] | undefined;
private _hasSpanProcessors: boolean = false;

static configureOtlp(): SpanExporter {
const protocol = this.getOtlpProtocol();

switch (protocol) {
case 'grpc':
return new OTLPGrpcTraceExporter;
case 'http/json':
return new OTLPHttpTraceExporter;
case 'http/protobuf':
return new OTLPProtoTraceExporter;
default:
diag.warn(`Unsupported OTLP traces protocol: ${protocol}. Using http/protobuf.`);
return new OTLPProtoTraceExporter;
}
}

static getOtlpProtocol(): string {
const parsedEnvValues = getEnvWithoutDefaults();

return parsedEnvValues.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL ??
parsedEnvValues.OTEL_EXPORTER_OTLP_PROTOCOL ??
getEnv().OTEL_EXPORTER_OTLP_TRACES_PROTOCOL ??
getEnv().OTEL_EXPORTER_OTLP_PROTOCOL;
}

protected static override _registeredExporters = new Map<
string,
() => SpanExporter
>([
['otlp', () => this.configureOtlp()],
['zipkin', () => new ZipkinExporter],
['jaeger', () => new JaegerExporter],
['console', () => new ConsoleSpanExporter]
]);

public constructor(config: NodeTracerConfig = {}) {
super(config);
let traceExportersList = this.filterBlanksAndNulls(Array.from(new Set(getEnv().OTEL_TRACES_EXPORTER.split(','))));

if (traceExportersList.length === 0 || traceExportersList[0] === 'none') {
diag.warn('OTEL_TRACES_EXPORTER contains "none" or is empty. SDK will not be initialized.');
} else {
if (traceExportersList.length > 1 && traceExportersList.includes('none')) {
diag.warn('OTEL_TRACES_EXPORTER contains "none" along with other exporters. Using default otlp exporter.');
traceExportersList = ['otlp'];
}

traceExportersList.forEach(exporterName => {
const exporter = this._getSpanExporter(exporterName);
if (exporter) {
this._configuredExporters.push(exporter);
} else {
diag.warn(`Unrecognized OTEL_TRACES_EXPORTER value: ${exporterName}.`);
}
});

if (this._configuredExporters.length > 0) {
this._spanProcessors = this.configureSpanProcessors(this._configuredExporters);
this._spanProcessors.forEach(processor => {
this.addSpanProcessor(processor);
});
} else {
diag.warn('Unable to set up trace exporter(s) due to invalid exporter and/or protocol values.');
}
}
}

override addSpanProcessor(spanProcessor: SpanProcessor) {
super.addSpanProcessor(spanProcessor);
this._hasSpanProcessors = true;
}

override register(config?: SDKRegistrationConfig) {
if (this._hasSpanProcessors) {
super.register(config);
}
}

private configureSpanProcessors(exporters: SpanExporter[]): (BatchSpanProcessor | SimpleSpanProcessor)[] {
return exporters.map(exporter => {
if (exporter instanceof ConsoleSpanExporter) {
return new SimpleSpanProcessor(exporter);
} else {
return new BatchSpanProcessor(exporter);
}
});
}

private filterBlanksAndNulls(list: string[]): string[] {
return list.map(item => item.trim())
.filter(s => s !== 'null' && s !== '');
}
}
29 changes: 17 additions & 12 deletions experimental/packages/opentelemetry-sdk-node/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ import {
import { MeterProvider, MetricReader, View } from '@opentelemetry/sdk-metrics';
import {
BatchSpanProcessor,
SpanProcessor
SpanProcessor,
} from '@opentelemetry/sdk-trace-base';
import { NodeTracerConfig, NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { NodeSDKConfiguration } from './types';
import { TracerProviderWithEnvExporters } from './TracerProviderWithEnvExporter';

/** This class represents everything needed to register a fully configured OpenTelemetry Node.js SDK */

Expand Down Expand Up @@ -64,7 +65,7 @@ export class NodeSDK {

private _autoDetectResources: boolean;

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

Expand Down Expand Up @@ -193,21 +194,25 @@ export class NodeSDK {
{ [SemanticResourceAttributes.SERVICE_NAME]: this._serviceName }
));

if (this._tracerProviderConfig) {
const tracerProvider = new NodeTracerProvider({
...this._tracerProviderConfig.tracerConfig,
resource: this._resource,
});
const Provider =
this._tracerProviderConfig ? NodeTracerProvider : TracerProviderWithEnvExporters;

const tracerProvider = new Provider ({
...this._tracerProviderConfig?.tracerConfig,
resource: this._resource,
});

this._tracerProvider = tracerProvider;
this._tracerProvider = tracerProvider;

if (this._tracerProviderConfig) {
tracerProvider.addSpanProcessor(this._tracerProviderConfig.spanProcessor);
tracerProvider.register({
contextManager: this._tracerProviderConfig.contextManager,
propagator: this._tracerProviderConfig.textMapPropagator,
});
}

tracerProvider.register({
contextManager: this._tracerProviderConfig?.contextManager,
propagator: this._tracerProviderConfig?.textMapPropagator,
});

if (this._meterProviderConfig) {
const meterProvider = new MeterProvider({
resource: this._resource,
Expand Down
Loading

0 comments on commit 6b8bb15

Please sign in to comment.