Skip to content

Commit e7ed31f

Browse files
authored
Merge branch 'main' into trace-exporter-configuration
2 parents 6f63e57 + 02239b5 commit e7ed31f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+777
-148
lines changed

examples/collector-exporter-node/docker/collector-config.yaml

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ exporters:
1515

1616
processors:
1717
batch:
18-
queued_retry:
1918

2019
service:
2120
pipelines:
2221
traces:
2322
receivers: [otlp]
2423
exporters: [zipkin]
25-
processors: [batch, queued_retry]
24+
processors: [batch]
2625
metrics:
2726
receivers: [otlp]
2827
exporters: [prometheus]
29-
processors: [batch, queued_retry]
28+
processors: [batch]

examples/collector-exporter-node/docker/docker-compose.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: "3"
22
services:
33
# Collector
44
collector:
5-
image: otel/opentelemetry-collector:0.16.0
5+
image: otel/opentelemetry-collector:0.25.0
66
# image: otel/opentelemetry-collector:latest
77
command: ["--config=/conf/collector-config.yaml", "--log-level=DEBUG"]
88
volumes:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
export const BAGGAGE_KEY_PAIR_SEPARATOR = '=';
18+
export const BAGGAGE_PROPERTIES_SEPARATOR = ';';
19+
export const BAGGAGE_ITEMS_SEPARATOR = ',';
20+
21+
// Name of the http header used to propagate the baggage
22+
export const BAGGAGE_HEADER = 'baggage';
23+
// Maximum number of name-value pairs allowed by w3c spec
24+
export const BAGGAGE_MAX_NAME_VALUE_PAIRS = 180;
25+
// Maximum number of bytes per a single name-value pair allowed by w3c spec
26+
export const BAGGAGE_MAX_PER_NAME_VALUE_PAIRS = 4096;
27+
// Maximum total length of all name-value pairs allowed by w3c spec
28+
export const BAGGAGE_MAX_TOTAL_LENGTH = 8192;

packages/opentelemetry-core/src/baggage/propagation/HttpBaggagePropagator.ts

+13-57
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717
import {
18-
Baggage,
1918
Context,
2019
BaggageEntry,
2120
getBaggage,
@@ -24,22 +23,15 @@ import {
2423
TextMapPropagator,
2524
TextMapSetter,
2625
createBaggage,
27-
baggageEntryMetadataFromString,
2826
isInstrumentationSuppressed,
2927
} from '@opentelemetry/api';
30-
31-
const KEY_PAIR_SEPARATOR = '=';
32-
const PROPERTIES_SEPARATOR = ';';
33-
const ITEMS_SEPARATOR = ',';
34-
35-
// Name of the http header used to propagate the baggage
36-
export const BAGGAGE_HEADER = 'baggage';
37-
// Maximum number of name-value pairs allowed by w3c spec
38-
export const MAX_NAME_VALUE_PAIRS = 180;
39-
// Maximum number of bytes per a single name-value pair allowed by w3c spec
40-
export const MAX_PER_NAME_VALUE_PAIRS = 4096;
41-
// Maximum total length of all name-value pairs allowed by w3c spec
42-
export const MAX_TOTAL_LENGTH = 8192;
28+
import { getKeyPairs, serializeKeyPairs, parsePairKeyValue } from '../utils';
29+
import {
30+
BAGGAGE_MAX_NAME_VALUE_PAIRS,
31+
BAGGAGE_ITEMS_SEPARATOR,
32+
BAGGAGE_HEADER,
33+
BAGGAGE_MAX_PER_NAME_VALUE_PAIRS,
34+
} from '../constants';
4335

4436
/**
4537
* Propagates {@link Baggage} through Context format propagation.
@@ -51,45 +43,27 @@ export class HttpBaggagePropagator implements TextMapPropagator {
5143
inject(context: Context, carrier: unknown, setter: TextMapSetter) {
5244
const baggage = getBaggage(context);
5345
if (!baggage || isInstrumentationSuppressed(context)) return;
54-
const keyPairs = this._getKeyPairs(baggage)
46+
const keyPairs = getKeyPairs(baggage)
5547
.filter((pair: string) => {
56-
return pair.length <= MAX_PER_NAME_VALUE_PAIRS;
48+
return pair.length <= BAGGAGE_MAX_PER_NAME_VALUE_PAIRS;
5749
})
58-
.slice(0, MAX_NAME_VALUE_PAIRS);
59-
const headerValue = this._serializeKeyPairs(keyPairs);
50+
.slice(0, BAGGAGE_MAX_NAME_VALUE_PAIRS);
51+
const headerValue = serializeKeyPairs(keyPairs);
6052
if (headerValue.length > 0) {
6153
setter.set(carrier, BAGGAGE_HEADER, headerValue);
6254
}
6355
}
6456

65-
private _serializeKeyPairs(keyPairs: string[]) {
66-
return keyPairs.reduce((hValue: string, current: string) => {
67-
const value = `${hValue}${
68-
hValue !== '' ? ITEMS_SEPARATOR : ''
69-
}${current}`;
70-
return value.length > MAX_TOTAL_LENGTH ? hValue : value;
71-
}, '');
72-
}
73-
74-
private _getKeyPairs(baggage: Baggage): string[] {
75-
return baggage
76-
.getAllEntries()
77-
.map(
78-
([key, value]) =>
79-
`${encodeURIComponent(key)}=${encodeURIComponent(value.value)}`
80-
);
81-
}
82-
8357
extract(context: Context, carrier: unknown, getter: TextMapGetter): Context {
8458
const headerValue: string = getter.get(carrier, BAGGAGE_HEADER) as string;
8559
if (!headerValue) return context;
8660
const baggage: Record<string, BaggageEntry> = {};
8761
if (headerValue.length === 0) {
8862
return context;
8963
}
90-
const pairs = headerValue.split(ITEMS_SEPARATOR);
64+
const pairs = headerValue.split(BAGGAGE_ITEMS_SEPARATOR);
9165
pairs.forEach(entry => {
92-
const keyPair = this._parsePairKeyValue(entry);
66+
const keyPair = parsePairKeyValue(entry);
9367
if (keyPair) {
9468
const baggageEntry: BaggageEntry = { value: keyPair.value };
9569
if (keyPair.metadata) {
@@ -104,24 +78,6 @@ export class HttpBaggagePropagator implements TextMapPropagator {
10478
return setBaggage(context, createBaggage(baggage));
10579
}
10680

107-
private _parsePairKeyValue(entry: string) {
108-
const valueProps = entry.split(PROPERTIES_SEPARATOR);
109-
if (valueProps.length <= 0) return;
110-
const keyPairPart = valueProps.shift();
111-
if (!keyPairPart) return;
112-
const keyPair = keyPairPart.split(KEY_PAIR_SEPARATOR);
113-
if (keyPair.length !== 2) return;
114-
const key = decodeURIComponent(keyPair[0].trim());
115-
const value = decodeURIComponent(keyPair[1].trim());
116-
let metadata;
117-
if (valueProps.length > 0) {
118-
metadata = baggageEntryMetadataFromString(
119-
valueProps.join(PROPERTIES_SEPARATOR)
120-
);
121-
}
122-
return { key, value, metadata };
123-
}
124-
12581
fields(): string[] {
12682
return [BAGGAGE_HEADER];
12783
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { Baggage, baggageEntryMetadataFromString } from '@opentelemetry/api';
17+
import {
18+
BAGGAGE_ITEMS_SEPARATOR,
19+
BAGGAGE_PROPERTIES_SEPARATOR,
20+
BAGGAGE_KEY_PAIR_SEPARATOR,
21+
BAGGAGE_MAX_TOTAL_LENGTH,
22+
} from './constants';
23+
24+
export const serializeKeyPairs = (keyPairs: string[]) => {
25+
return keyPairs.reduce((hValue: string, current: string) => {
26+
const value = `${hValue}${
27+
hValue !== '' ? BAGGAGE_ITEMS_SEPARATOR : ''
28+
}${current}`;
29+
return value.length > BAGGAGE_MAX_TOTAL_LENGTH ? hValue : value;
30+
}, '');
31+
};
32+
33+
export const getKeyPairs = (baggage: Baggage): string[] => {
34+
return baggage
35+
.getAllEntries()
36+
.map(
37+
([key, value]) =>
38+
`${encodeURIComponent(key)}=${encodeURIComponent(value.value)}`
39+
);
40+
};
41+
42+
export const parsePairKeyValue = (entry: string) => {
43+
const valueProps = entry.split(BAGGAGE_PROPERTIES_SEPARATOR);
44+
if (valueProps.length <= 0) return;
45+
const keyPairPart = valueProps.shift();
46+
if (!keyPairPart) return;
47+
const keyPair = keyPairPart.split(BAGGAGE_KEY_PAIR_SEPARATOR);
48+
if (keyPair.length !== 2) return;
49+
const key = decodeURIComponent(keyPair[0].trim());
50+
const value = decodeURIComponent(keyPair[1].trim());
51+
let metadata;
52+
if (valueProps.length > 0) {
53+
metadata = baggageEntryMetadataFromString(
54+
valueProps.join(BAGGAGE_PROPERTIES_SEPARATOR)
55+
);
56+
}
57+
return { key, value, metadata };
58+
};
59+
60+
/**
61+
* Parse a string serialized in the baggage HTTP Format (without metadata):
62+
* https://github.com/w3c/baggage/blob/master/baggage/HTTP_HEADER_FORMAT.md
63+
*/
64+
export const parseKeyPairsIntoRecord = (value?: string) => {
65+
if (typeof value !== 'string' || value.length === 0) return {};
66+
return value
67+
.split(BAGGAGE_ITEMS_SEPARATOR)
68+
.map(entry => {
69+
return parsePairKeyValue(entry);
70+
})
71+
.filter(keyPair => keyPair !== undefined && keyPair.value.length > 0)
72+
.reduce<Record<string, string>>((headers, keyPair) => {
73+
headers[keyPair!.key] = keyPair!.value;
74+
return headers;
75+
}, {});
76+
};

packages/opentelemetry-core/src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export * from './common/logging-error-handler';
2121
export * from './common/time';
2222
export * from './common/types';
2323
export * from './ExportResult';
24+
export * from './version';
25+
export * as baggageUtils from './baggage/utils';
2426
export * from './platform';
2527
export * from './propagation/composite';
2628
export * from './trace/HttpTraceContextPropagator';

packages/opentelemetry-core/src/utils/environment.ts

+12
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ export type ENVIRONMENT = {
6767
OTEL_EXPORTER_JAEGER_ENDPOINT?: string;
6868
OTEL_EXPORTER_JAEGER_PASSWORD?: string;
6969
OTEL_EXPORTER_JAEGER_USER?: string;
70+
OTEL_EXPORTER_OTLP_ENDPOINT?: string;
71+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT?: string;
72+
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT?: string;
73+
OTEL_EXPORTER_OTLP_HEADERS?: string;
74+
OTEL_EXPORTER_OTLP_TRACES_HEADERS?: string;
75+
OTEL_EXPORTER_OTLP_METRICS_HEADERS?: string;
7076
OTEL_EXPORTER_ZIPKIN_ENDPOINT?: string;
7177
OTEL_LOG_LEVEL?: DiagLogLevel;
7278
OTEL_RESOURCE_ATTRIBUTES?: string;
@@ -98,6 +104,12 @@ export const DEFAULT_ENVIRONMENT: Required<ENVIRONMENT> = {
98104
OTEL_EXPORTER_JAEGER_ENDPOINT: '',
99105
OTEL_EXPORTER_JAEGER_PASSWORD: '',
100106
OTEL_EXPORTER_JAEGER_USER: '',
107+
OTEL_EXPORTER_OTLP_ENDPOINT: '',
108+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: '',
109+
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: '',
110+
OTEL_EXPORTER_OTLP_HEADERS: '',
111+
OTEL_EXPORTER_OTLP_TRACES_HEADERS: '',
112+
OTEL_EXPORTER_OTLP_METRICS_HEADERS: '',
101113
OTEL_EXPORTER_ZIPKIN_ENDPOINT: 'http://localhost:9411/api/v2/spans',
102114
OTEL_LOG_LEVEL: DiagLogLevel.INFO,
103115
OTEL_NO_PATCH_MODULES: [],

packages/opentelemetry-core/test/baggage/HttpBaggagePropagator.test.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,8 @@ import {
2525
} from '@opentelemetry/api';
2626
import { ROOT_CONTEXT } from '@opentelemetry/api';
2727
import * as assert from 'assert';
28-
import {
29-
BAGGAGE_HEADER,
30-
HttpBaggagePropagator,
31-
} from '../../src/baggage/propagation/HttpBaggagePropagator';
28+
import { HttpBaggagePropagator } from '../../src/baggage/propagation/HttpBaggagePropagator';
29+
import { BAGGAGE_HEADER } from '../../src/baggage/constants';
3230

3331
describe('HttpBaggagePropagator', () => {
3432
const httpBaggagePropagator = new HttpBaggagePropagator();

packages/opentelemetry-exporter-collector-grpc/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![devDependencies][devDependencies-image]][devDependencies-url]
66
[![Apache License][license-image]][license-image]
77

8-
This module provides exporter for web and node to be used with [opentelemetry-collector][opentelemetry-collector-url] - last tested with version **0.16.0**.
8+
This module provides exporter for web and node to be used with [opentelemetry-collector][opentelemetry-collector-url] - last tested with version **0.25.0**.
99

1010
## Installation
1111

@@ -15,7 +15,7 @@ npm install --save @opentelemetry/exporter-collector-grpc
1515

1616
## Traces in Node - GRPC
1717

18-
The CollectorTraceExporter in Node expects the URL to only be the hostname. It will not work with `/v1/trace`.
18+
The CollectorTraceExporter in Node expects the URL to only be the hostname. It will not work with `/v1/traces`.
1919

2020
```js
2121
const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/tracing');

packages/opentelemetry-exporter-collector-grpc/src/CollectorMetricExporter.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
import { MetricRecord, MetricExporter } from '@opentelemetry/metrics';
2222
import { CollectorExporterConfigNode, ServiceClientType } from './types';
2323
import { CollectorExporterNodeBase } from './CollectorExporterNodeBase';
24+
import { getEnv } from '@opentelemetry/core';
2425

2526
const DEFAULT_SERVICE_NAME = 'collector-metric-exporter';
2627
const DEFAULT_COLLECTOR_URL = 'localhost:4317';
@@ -47,11 +48,14 @@ export class CollectorMetricExporter
4748
);
4849
}
4950

50-
getDefaultUrl(config: CollectorExporterConfigNode): string {
51-
if (!config.url) {
52-
return DEFAULT_COLLECTOR_URL;
53-
}
54-
return config.url;
51+
getDefaultUrl(config: CollectorExporterConfigNode) {
52+
return typeof config.url === 'string'
53+
? config.url
54+
: getEnv().OTEL_EXPORTER_OTLP_METRICS_ENDPOINT.length > 0
55+
? getEnv().OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
56+
: getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0
57+
? getEnv().OTEL_EXPORTER_OTLP_ENDPOINT
58+
: DEFAULT_COLLECTOR_URL;
5559
}
5660

5761
getDefaultServiceName(config: CollectorExporterConfigNode): string {

packages/opentelemetry-exporter-collector-grpc/src/CollectorTraceExporter.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
toCollectorExportTraceServiceRequest,
2222
} from '@opentelemetry/exporter-collector';
2323
import { CollectorExporterConfigNode, ServiceClientType } from './types';
24+
import { getEnv } from '@opentelemetry/core';
2425

2526
const DEFAULT_SERVICE_NAME = 'collector-trace-exporter';
2627
const DEFAULT_COLLECTOR_URL = 'localhost:4317';
@@ -40,11 +41,14 @@ export class CollectorTraceExporter
4041
return toCollectorExportTraceServiceRequest(spans, this);
4142
}
4243

43-
getDefaultUrl(config: CollectorExporterConfigNode): string {
44-
if (!config.url) {
45-
return DEFAULT_COLLECTOR_URL;
46-
}
47-
return config.url;
44+
getDefaultUrl(config: CollectorExporterConfigNode) {
45+
return typeof config.url === 'string'
46+
? config.url
47+
: getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT.length > 0
48+
? getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
49+
: getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0
50+
? getEnv().OTEL_EXPORTER_OTLP_ENDPOINT
51+
: DEFAULT_COLLECTOR_URL;
4852
}
4953

5054
getDefaultServiceName(config: CollectorExporterConfigNode): string {

0 commit comments

Comments
 (0)