Skip to content

Commit

Permalink
feat: otlp-grpc exporter uses headers environment variables (#2304)
Browse files Browse the repository at this point in the history
* feat: otlp-grpc exporter uses headers environment variables

* chore: smaller import radius

Co-authored-by: Valentin Marchaud <contact@vmarchaud.fr>
Co-authored-by: Daniel Dyla <dyladan@users.noreply.github.com>
  • Loading branch information
3 people committed Jun 30, 2021
1 parent 8f2209f commit 2276e4f
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 4 deletions.
Expand Up @@ -19,13 +19,14 @@ import {
CollectorExporterBase,
collectorTypes,
} from '@opentelemetry/exporter-collector';
import type { Metadata } from '@grpc/grpc-js';
import { Metadata } from '@grpc/grpc-js';
import {
CollectorExporterConfigNode,
GRPCQueueItem,
ServiceClientType,
} from './types';
import { ServiceClient } from './types';
import { getEnv, baggageUtils } from "@opentelemetry/core";

/**
* Collector Metric Exporter abstract base class
Expand All @@ -48,8 +49,13 @@ export abstract class CollectorExporterNodeBase<
if (config.headers) {
diag.warn('Headers cannot be set when using grpc');
}
this.metadata = config.metadata;
const headers = baggageUtils.parseKeyPairsIntoRecord(getEnv().OTEL_EXPORTER_OTLP_HEADERS);
this.metadata = config.metadata || new Metadata();
for (const [k, v] of Object.entries(headers)) {
this.metadata.set(k, v)
}
}

private _sendPromise(
objects: ExportItem[],
onSuccess: () => void,
Expand Down
Expand Up @@ -21,8 +21,9 @@ import {
import { MetricRecord, MetricExporter } from '@opentelemetry/metrics';
import { CollectorExporterConfigNode, ServiceClientType } from './types';
import { CollectorExporterNodeBase } from './CollectorExporterNodeBase';
import { getEnv } from '@opentelemetry/core';
import { baggageUtils, getEnv } from '@opentelemetry/core';
import { validateAndNormalizeUrl } from './util';
import { Metadata } from "@grpc/grpc-js";

const DEFAULT_COLLECTOR_URL = 'localhost:4317';

Expand All @@ -38,6 +39,15 @@ export class CollectorMetricExporter
// Converts time to nanoseconds
protected readonly _startTime = new Date().getTime() * 1000000;

constructor(config: CollectorExporterConfigNode = {}) {
super(config);
const headers = baggageUtils.parseKeyPairsIntoRecord(getEnv().OTEL_EXPORTER_OTLP_METRICS_HEADERS);
this.metadata ||= new Metadata();
for (const [k, v] of Object.entries(headers)) {
this.metadata.set(k, v)
}
}

convert(
metrics: MetricRecord[]
): collectorTypes.opentelemetryProto.collector.metrics.v1.ExportMetricsServiceRequest {
Expand Down
Expand Up @@ -21,8 +21,9 @@ import {
toCollectorExportTraceServiceRequest,
} from '@opentelemetry/exporter-collector';
import { CollectorExporterConfigNode, ServiceClientType } from './types';
import { getEnv } from '@opentelemetry/core';
import { baggageUtils, getEnv } from '@opentelemetry/core';
import { validateAndNormalizeUrl } from './util';
import { Metadata } from "@grpc/grpc-js";

const DEFAULT_COLLECTOR_URL = 'localhost:4317';

Expand All @@ -35,6 +36,16 @@ export class CollectorTraceExporter
collectorTypes.opentelemetryProto.collector.trace.v1.ExportTraceServiceRequest
>
implements SpanExporter {

constructor(config: CollectorExporterConfigNode = {}) {
super(config);
const headers = baggageUtils.parseKeyPairsIntoRecord(getEnv().OTEL_EXPORTER_OTLP_TRACES_HEADERS);
this.metadata ||= new Metadata();
for (const [k, v] of Object.entries(headers)) {
this.metadata.set(k, v)
}
}

convert(
spans: ReadableSpan[]
): collectorTypes.opentelemetryProto.collector.trace.v1.ExportTraceServiceRequest {
Expand Down
Expand Up @@ -278,6 +278,25 @@ describe('when configuring via environment', () => {
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = '';
envSource.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = '';
});
it('should use headers defined via env', () => {
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar';
const collectorExporter = new CollectorMetricExporter();
assert.deepStrictEqual(collectorExporter.metadata?.get('foo'), ['bar']);
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
});
it('should override global headers config with signal headers defined via env', () => {
const metadata = new grpc.Metadata();
metadata.set('foo', 'bar');
metadata.set('goo', 'lol');
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=jar,bar=foo';
envSource.OTEL_EXPORTER_OTLP_METRICS_HEADERS = 'foo=boo';
const collectorExporter = new CollectorMetricExporter({ metadata });
assert.deepStrictEqual(collectorExporter.metadata?.get('foo'), ['boo']);
assert.deepStrictEqual(collectorExporter.metadata?.get('bar'), ['foo']);
assert.deepStrictEqual(collectorExporter.metadata?.get('goo'), ['lol']);
envSource.OTEL_EXPORTER_OTLP_METRICS_HEADERS = '';
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
});
});

testCollectorMetricExporter({ useTLS: true });
Expand Down
Expand Up @@ -240,6 +240,25 @@ describe('when configuring via environment', () => {
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = '';
envSource.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = '';
});
it('should use headers defined via env', () => {
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar';
const collectorExporter = new CollectorTraceExporter();
assert.deepStrictEqual(collectorExporter.metadata?.get('foo'), ['bar']);
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
});
it('should override global headers config with signal headers defined via env', () => {
const metadata = new grpc.Metadata();
metadata.set('foo', 'bar');
metadata.set('goo', 'lol');
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=jar,bar=foo';
envSource.OTEL_EXPORTER_OTLP_TRACES_HEADERS = 'foo=boo';
const collectorExporter = new CollectorTraceExporter({ metadata });
assert.deepStrictEqual(collectorExporter.metadata?.get('foo'), ['boo']);
assert.deepStrictEqual(collectorExporter.metadata?.get('bar'), ['foo']);
assert.deepStrictEqual(collectorExporter.metadata?.get('goo'), ['lol']);
envSource.OTEL_EXPORTER_OTLP_TRACES_HEADERS = '';
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
});
});

testCollectorExporter({ useTLS: true });
Expand Down

0 comments on commit 2276e4f

Please sign in to comment.