feat(sdk-trace-base)!: do not read environment variables from window (#5455)
Co-authored-by: Trent Mick <trentm@gmail.com>
This commit is contained in:
parent
1a5b57b7f3
commit
e4381fcb18
|
@ -93,8 +93,12 @@ For semantic convention package changes, see the [semconv CHANGELOG](packages/se
|
|||
* (user-facing): `baggageUtils.parsePairKeyValue` was an internal utility function that was unintentionally exported. It has been removed without replacement.
|
||||
* (user-facing): `TimeOriginLegacy` has been removed without replacement.
|
||||
* (user-facing): `isAttributeKey` was an internal utility function that was unintentionally exported. It has been removed without replacement.
|
||||
* feat(sdk-trace-base)!: do not read environment variables from window in browsers [#5445](https://github.com/open-telemetry/opentelemetry-js/pull/5455) @pichlermarc
|
||||
* (user-facing): all configuration previously possible via `window.OTEL_*` is now not supported anymore, please pass configuration options to constructors instead.
|
||||
* Note: Node.js environment variable configuration continues to work as-is.
|
||||
* feat(exporter-zipkin)!: do not read environment variables from window in browsers [#5465](https://github.com/open-telemetry/opentelemetry-js/pull/5465) @pichlermarc
|
||||
* (user-facing): all configuration previously possible via `window.OTEL_*` is now not supported anymore, please pass configuration options to constructors instead.
|
||||
* Note: Node.js environment variable configuration continues to work as-is.
|
||||
* feat(resource)!: Remove resource class export in favor of functions and types only to aid in cross-version compatibility [#5421](https://github.com/open-telemetry/opentelemetry-js/pull/5421)
|
||||
* Renames `Resource` class to `ResourceImpl` and makes it package-private
|
||||
* Renames `IResource` interface to `Resource`
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*!
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
|
@ -17,8 +17,12 @@
|
|||
const karmaWebpackConfig = require('../../karma.webpack');
|
||||
const karmaBaseConfig = require('../../karma.base');
|
||||
|
||||
module.exports = (config) => {
|
||||
config.set(Object.assign({}, karmaBaseConfig, {
|
||||
webpack: karmaWebpackConfig,
|
||||
}))
|
||||
module.exports = config => {
|
||||
config.set(
|
||||
Object.assign({}, karmaBaseConfig, {
|
||||
webpack: karmaWebpackConfig,
|
||||
files: ['test/browser/index-webpack.ts'],
|
||||
preprocessors: { 'test/browser/index-webpack.ts': ['webpack'] },
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*!
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
|
@ -17,8 +17,17 @@
|
|||
const karmaWebpackConfig = require('../../karma.webpack');
|
||||
const karmaBaseConfig = require('../../karma.worker');
|
||||
|
||||
module.exports = (config) => {
|
||||
config.set(Object.assign({}, karmaBaseConfig, {
|
||||
webpack: karmaWebpackConfig,
|
||||
}))
|
||||
module.exports = config => {
|
||||
config.set(
|
||||
Object.assign({}, karmaBaseConfig, {
|
||||
webpack: karmaWebpackConfig,
|
||||
files: [
|
||||
{
|
||||
pattern: 'test/browser/index-webpack.worker.ts',
|
||||
included: false,
|
||||
},
|
||||
],
|
||||
preprocessors: { 'test/browser/index-webpack.worker.ts': ['webpack'] },
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
import { diag } from '@opentelemetry/api';
|
||||
import { getEnv, ENVIRONMENT } from '@opentelemetry/core';
|
||||
import { getNumberFromEnv, getStringFromEnv } from '@opentelemetry/core';
|
||||
import { Sampler } from './Sampler';
|
||||
import { AlwaysOffSampler } from './sampler/AlwaysOffSampler';
|
||||
import { AlwaysOnSampler } from './sampler/AlwaysOnSampler';
|
||||
|
@ -44,35 +44,38 @@ const DEFAULT_RATIO = 1;
|
|||
// object needs to be wrapped in this function and called when needed otherwise
|
||||
// envs are parsed before tests are ran - causes tests using these envs to fail
|
||||
export function loadDefaultConfig() {
|
||||
const env = getEnv();
|
||||
|
||||
return {
|
||||
sampler: buildSamplerFromEnv(env),
|
||||
sampler: buildSamplerFromEnv(),
|
||||
forceFlushTimeoutMillis: 30000,
|
||||
generalLimits: {
|
||||
attributeValueLengthLimit: env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT,
|
||||
attributeCountLimit: env.OTEL_ATTRIBUTE_COUNT_LIMIT,
|
||||
attributeValueLengthLimit:
|
||||
getNumberFromEnv('OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT') ?? Infinity,
|
||||
attributeCountLimit:
|
||||
getNumberFromEnv('OTEL_ATTRIBUTE_COUNT_LIMIT') ?? 128,
|
||||
},
|
||||
spanLimits: {
|
||||
attributeValueLengthLimit: env.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT,
|
||||
attributeCountLimit: env.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT,
|
||||
linkCountLimit: env.OTEL_SPAN_LINK_COUNT_LIMIT,
|
||||
eventCountLimit: env.OTEL_SPAN_EVENT_COUNT_LIMIT,
|
||||
attributeValueLengthLimit:
|
||||
getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT') ?? Infinity,
|
||||
attributeCountLimit:
|
||||
getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT') ?? 128,
|
||||
linkCountLimit: getNumberFromEnv('OTEL_SPAN_LINK_COUNT_LIMIT') ?? 128,
|
||||
eventCountLimit: getNumberFromEnv('OTEL_SPAN_EVENT_COUNT_LIMIT') ?? 128,
|
||||
attributePerEventCountLimit:
|
||||
env.OTEL_SPAN_ATTRIBUTE_PER_EVENT_COUNT_LIMIT,
|
||||
attributePerLinkCountLimit: env.OTEL_SPAN_ATTRIBUTE_PER_LINK_COUNT_LIMIT,
|
||||
getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_PER_EVENT_COUNT_LIMIT') ?? 128,
|
||||
attributePerLinkCountLimit:
|
||||
getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_PER_LINK_COUNT_LIMIT') ?? 128,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on environment, builds a sampler, complies with specification.
|
||||
* @param environment optional, by default uses getEnv(), but allows passing a value to reuse parsed environment
|
||||
*/
|
||||
export function buildSamplerFromEnv(
|
||||
environment: Required<ENVIRONMENT> = getEnv()
|
||||
): Sampler {
|
||||
switch (environment.OTEL_TRACES_SAMPLER) {
|
||||
export function buildSamplerFromEnv(): Sampler {
|
||||
const sampler =
|
||||
getStringFromEnv('OTEL_TRACES_SAMPLER') ??
|
||||
TracesSamplerValues.ParentBasedAlwaysOn;
|
||||
switch (sampler) {
|
||||
case TracesSamplerValues.AlwaysOn:
|
||||
return new AlwaysOnSampler();
|
||||
case TracesSamplerValues.AlwaysOff:
|
||||
|
@ -86,48 +89,31 @@ export function buildSamplerFromEnv(
|
|||
root: new AlwaysOffSampler(),
|
||||
});
|
||||
case TracesSamplerValues.TraceIdRatio:
|
||||
return new TraceIdRatioBasedSampler(
|
||||
getSamplerProbabilityFromEnv(environment)
|
||||
);
|
||||
return new TraceIdRatioBasedSampler(getSamplerProbabilityFromEnv());
|
||||
case TracesSamplerValues.ParentBasedTraceIdRatio:
|
||||
return new ParentBasedSampler({
|
||||
root: new TraceIdRatioBasedSampler(
|
||||
getSamplerProbabilityFromEnv(environment)
|
||||
),
|
||||
root: new TraceIdRatioBasedSampler(getSamplerProbabilityFromEnv()),
|
||||
});
|
||||
default:
|
||||
diag.error(
|
||||
`OTEL_TRACES_SAMPLER value "${environment.OTEL_TRACES_SAMPLER} invalid, defaulting to ${FALLBACK_OTEL_TRACES_SAMPLER}".`
|
||||
`OTEL_TRACES_SAMPLER value "${sampler}" invalid, defaulting to "${FALLBACK_OTEL_TRACES_SAMPLER}".`
|
||||
);
|
||||
return new AlwaysOnSampler();
|
||||
}
|
||||
}
|
||||
|
||||
function getSamplerProbabilityFromEnv(
|
||||
environment: Required<ENVIRONMENT>
|
||||
): number | undefined {
|
||||
if (
|
||||
environment.OTEL_TRACES_SAMPLER_ARG === undefined ||
|
||||
environment.OTEL_TRACES_SAMPLER_ARG === ''
|
||||
) {
|
||||
function getSamplerProbabilityFromEnv(): number | undefined {
|
||||
const probability = getNumberFromEnv('OTEL_TRACES_SAMPLER_ARG');
|
||||
if (probability == null) {
|
||||
diag.error(
|
||||
`OTEL_TRACES_SAMPLER_ARG is blank, defaulting to ${DEFAULT_RATIO}.`
|
||||
);
|
||||
return DEFAULT_RATIO;
|
||||
}
|
||||
|
||||
const probability = Number(environment.OTEL_TRACES_SAMPLER_ARG);
|
||||
|
||||
if (isNaN(probability)) {
|
||||
diag.error(
|
||||
`OTEL_TRACES_SAMPLER_ARG=${environment.OTEL_TRACES_SAMPLER_ARG} was given, but it is invalid, defaulting to ${DEFAULT_RATIO}.`
|
||||
);
|
||||
return DEFAULT_RATIO;
|
||||
}
|
||||
|
||||
if (probability < 0 || probability > 1) {
|
||||
diag.error(
|
||||
`OTEL_TRACES_SAMPLER_ARG=${environment.OTEL_TRACES_SAMPLER_ARG} was given, but it is out of range ([0..1]), defaulting to ${DEFAULT_RATIO}.`
|
||||
`OTEL_TRACES_SAMPLER_ARG=${probability} was given, but it is out of range ([0..1]), defaulting to ${DEFAULT_RATIO}.`
|
||||
);
|
||||
return DEFAULT_RATIO;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import { context, Context, diag, TraceFlags } from '@opentelemetry/api';
|
|||
import {
|
||||
BindOnceFuture,
|
||||
ExportResultCode,
|
||||
getEnv,
|
||||
getNumberFromEnv,
|
||||
globalErrorHandler,
|
||||
suppressTracing,
|
||||
unrefTimer,
|
||||
|
@ -51,23 +51,22 @@ export abstract class BatchSpanProcessorBase<T extends BufferConfig>
|
|||
private readonly _exporter: SpanExporter,
|
||||
config?: T
|
||||
) {
|
||||
const env = getEnv();
|
||||
this._maxExportBatchSize =
|
||||
typeof config?.maxExportBatchSize === 'number'
|
||||
? config.maxExportBatchSize
|
||||
: env.OTEL_BSP_MAX_EXPORT_BATCH_SIZE;
|
||||
: (getNumberFromEnv('OTEL_BSP_MAX_EXPORT_BATCH_SIZE') ?? 512);
|
||||
this._maxQueueSize =
|
||||
typeof config?.maxQueueSize === 'number'
|
||||
? config.maxQueueSize
|
||||
: env.OTEL_BSP_MAX_QUEUE_SIZE;
|
||||
: (getNumberFromEnv('OTEL_BSP_MAX_QUEUE_SIZE') ?? 2048);
|
||||
this._scheduledDelayMillis =
|
||||
typeof config?.scheduledDelayMillis === 'number'
|
||||
? config.scheduledDelayMillis
|
||||
: env.OTEL_BSP_SCHEDULE_DELAY;
|
||||
: (getNumberFromEnv('OTEL_BSP_SCHEDULE_DELAY') ?? 5000);
|
||||
this._exportTimeoutMillis =
|
||||
typeof config?.exportTimeoutMillis === 'number'
|
||||
? config.exportTimeoutMillis
|
||||
: env.OTEL_BSP_EXPORT_TIMEOUT;
|
||||
: (getNumberFromEnv('OTEL_BSP_EXPORT_TIMEOUT') ?? 30000);
|
||||
|
||||
this._shutdownOnce = new BindOnceFuture(this._shutdown, this);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import { SpanLimits, TracerConfig, GeneralLimits } from './types';
|
|||
import {
|
||||
DEFAULT_ATTRIBUTE_COUNT_LIMIT,
|
||||
DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT,
|
||||
getEnvWithoutDefaults,
|
||||
getNumberFromEnv,
|
||||
} from '@opentelemetry/core';
|
||||
|
||||
/**
|
||||
|
@ -68,16 +68,14 @@ export function mergeConfig(userConfig: TracerConfig): TracerConfig & {
|
|||
export function reconfigureLimits(userConfig: TracerConfig): TracerConfig {
|
||||
const spanLimits = Object.assign({}, userConfig.spanLimits);
|
||||
|
||||
const parsedEnvConfig = getEnvWithoutDefaults();
|
||||
|
||||
/**
|
||||
* Reassign span attribute count limit to use first non null value defined by user or use default value
|
||||
*/
|
||||
spanLimits.attributeCountLimit =
|
||||
userConfig.spanLimits?.attributeCountLimit ??
|
||||
userConfig.generalLimits?.attributeCountLimit ??
|
||||
parsedEnvConfig.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT ??
|
||||
parsedEnvConfig.OTEL_ATTRIBUTE_COUNT_LIMIT ??
|
||||
getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT') ??
|
||||
getNumberFromEnv('OTEL_ATTRIBUTE_COUNT_LIMIT') ??
|
||||
DEFAULT_ATTRIBUTE_COUNT_LIMIT;
|
||||
|
||||
/**
|
||||
|
@ -86,8 +84,8 @@ export function reconfigureLimits(userConfig: TracerConfig): TracerConfig {
|
|||
spanLimits.attributeValueLengthLimit =
|
||||
userConfig.spanLimits?.attributeValueLengthLimit ??
|
||||
userConfig.generalLimits?.attributeValueLengthLimit ??
|
||||
parsedEnvConfig.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT ??
|
||||
parsedEnvConfig.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT ??
|
||||
getNumberFromEnv('OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT') ??
|
||||
getNumberFromEnv('OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT') ??
|
||||
DEFAULT_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
|
||||
return Object.assign({}, userConfig, { spanLimits });
|
||||
|
|
|
@ -13,8 +13,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const testsContext = require.context('../browser', true, /test$/);
|
||||
testsContext.keys().forEach(testsContext);
|
||||
|
||||
{
|
||||
const testsContext = require.context('./', true, /test$/);
|
||||
testsContext.keys().forEach(testsContext);
|
||||
}
|
||||
const testsContextCommon = require.context('../common', true, /test$/);
|
||||
testsContextCommon.keys().forEach(testsContextCommon);
|
||||
|
||||
const srcContext = require.context('.', true, /src$/);
|
||||
srcContext.keys().forEach(srcContext);
|
|
@ -13,8 +13,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const testsContext = require.context('../browser', true, /test$/);
|
||||
testsContext.keys().forEach(testsContext);
|
||||
|
||||
{
|
||||
const testsContext = require.context('./', true, /test$/);
|
||||
testsContext.keys().forEach(testsContext);
|
||||
}
|
||||
const testsContextCommon = require.context('../common', true, /test$/);
|
||||
testsContextCommon.keys().forEach(testsContextCommon);
|
||||
|
||||
const srcContext = require.context('.', true, /src$/);
|
||||
srcContext.keys().forEach(srcContext);
|
|
@ -62,16 +62,9 @@ class DummyPropagator implements TextMapPropagator {
|
|||
}
|
||||
|
||||
describe('BasicTracerProvider', () => {
|
||||
let envSource: Record<string, any>;
|
||||
let setGlobalPropagatorStub: sinon.SinonSpy<[TextMapPropagator], boolean>;
|
||||
let setGlobalContextManagerStub: sinon.SinonSpy<[ContextManager], boolean>;
|
||||
|
||||
if (global.process?.versions?.node === undefined) {
|
||||
envSource = globalThis as unknown as Record<string, any>;
|
||||
} else {
|
||||
envSource = process.env as Record<string, any>;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
// to avoid actually registering the TraceProvider and leaking env to other tests
|
||||
sinon.stub(trace, 'setGlobalTracerProvider');
|
||||
|
@ -237,56 +230,7 @@ describe('BasicTracerProvider', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when attribute value length limit is defined via env', () => {
|
||||
it('should have general attribute value length limits value as defined with env', () => {
|
||||
envSource.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = '115';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeValueLengthLimit, 115);
|
||||
delete envSource.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
});
|
||||
it('should have span attribute value length limit value same as general limit value', () => {
|
||||
envSource.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = '125';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
assert.strictEqual(generalLimits.attributeValueLengthLimit, 125);
|
||||
assert.strictEqual(spanLimits.attributeValueLengthLimit, 125);
|
||||
delete envSource.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
});
|
||||
it('should have span and general attribute value length limits as defined in env', () => {
|
||||
envSource.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = '125';
|
||||
envSource.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = '109';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeValueLengthLimit, 125);
|
||||
assert.strictEqual(spanLimits.attributeValueLengthLimit, 109);
|
||||
delete envSource.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
delete envSource.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
});
|
||||
it('should have span attribute value length limit as default of Infinity', () => {
|
||||
envSource.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = '125';
|
||||
envSource.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = 'Infinity';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeValueLengthLimit, 125);
|
||||
assert.strictEqual(spanLimits.attributeValueLengthLimit, Infinity);
|
||||
delete envSource.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
delete envSource.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when attribute value length limit is not defined via env', () => {
|
||||
describe('when attribute value length limit is not defined', () => {
|
||||
it('should use default value of Infinity', () => {
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
|
@ -298,56 +242,7 @@ describe('BasicTracerProvider', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when attribute count limit is defined via env', () => {
|
||||
it('should general attribute count limit as defined with env', () => {
|
||||
envSource.OTEL_ATTRIBUTE_COUNT_LIMIT = '25';
|
||||
const tracer = new BasicTracerProvider({}).getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeCountLimit, 25);
|
||||
delete envSource.OTEL_ATTRIBUTE_COUNT_LIMIT;
|
||||
});
|
||||
it('should have span attribute count limit value same as general limit value', () => {
|
||||
envSource.OTEL_ATTRIBUTE_COUNT_LIMIT = '20';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
assert.strictEqual(generalLimits.attributeCountLimit, 20);
|
||||
assert.strictEqual(spanLimits.attributeCountLimit, 20);
|
||||
delete envSource.OTEL_ATTRIBUTE_COUNT_LIMIT;
|
||||
});
|
||||
it('should have span and general attribute count limits as defined in env', () => {
|
||||
envSource.OTEL_ATTRIBUTE_COUNT_LIMIT = '20';
|
||||
envSource.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = '35';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeCountLimit, 20);
|
||||
assert.strictEqual(spanLimits.attributeCountLimit, 35);
|
||||
delete envSource.OTEL_ATTRIBUTE_COUNT_LIMIT;
|
||||
delete envSource.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT;
|
||||
});
|
||||
it('should have span attribute count limit as default of 128', () => {
|
||||
envSource.OTEL_ATTRIBUTE_COUNT_LIMIT = '20';
|
||||
envSource.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = '128';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeCountLimit, 20);
|
||||
assert.strictEqual(spanLimits.attributeCountLimit, 128);
|
||||
delete envSource.OTEL_ATTRIBUTE_COUNT_LIMIT;
|
||||
delete envSource.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when attribute count limit is not defined via env', () => {
|
||||
describe('when attribute count limit is not defined', () => {
|
||||
it('should use default value of 128', () => {
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
|
|
|
@ -50,12 +50,6 @@ import { Tracer } from '../../src/Tracer';
|
|||
|
||||
describe('Tracer', () => {
|
||||
const tracerProvider = new BasicTracerProvider();
|
||||
let envSource: Record<string, any>;
|
||||
if (global.process?.versions?.node === undefined) {
|
||||
envSource = globalThis as unknown as Record<string, any>;
|
||||
} else {
|
||||
envSource = process.env as Record<string, any>;
|
||||
}
|
||||
|
||||
class TestSampler implements Sampler {
|
||||
constructor(private readonly traceState?: TraceState) {}
|
||||
|
@ -106,8 +100,6 @@ describe('Tracer', () => {
|
|||
|
||||
afterEach(() => {
|
||||
context.disable();
|
||||
delete envSource.OTEL_TRACES_SAMPLER;
|
||||
delete envSource.OTEL_TRACES_SAMPLER_ARG;
|
||||
});
|
||||
|
||||
it('should create a Tracer instance', () => {
|
||||
|
@ -327,51 +319,6 @@ describe('Tracer', () => {
|
|||
assert.strictEqual(trace.getSpan(samplerContext), undefined);
|
||||
});
|
||||
|
||||
it('should sample a trace when OTEL_TRACES_SAMPLER_ARG is unset', () => {
|
||||
envSource.OTEL_TRACES_SAMPLER = 'traceidratio';
|
||||
envSource.OTEL_TRACES_SAMPLER_ARG = '';
|
||||
const tracer = new Tracer(
|
||||
{ name: 'default', version: '0.0.1' },
|
||||
{},
|
||||
tracerProvider['_resource'],
|
||||
tracerProvider['_activeSpanProcessor']
|
||||
);
|
||||
const span = tracer.startSpan('my-span');
|
||||
const context = span.spanContext();
|
||||
assert.strictEqual(context.traceFlags, TraceFlags.SAMPLED);
|
||||
span.end();
|
||||
});
|
||||
|
||||
it('should not sample a trace when OTEL_TRACES_SAMPLER_ARG is out of range', () => {
|
||||
envSource.OTEL_TRACES_SAMPLER = 'traceidratio';
|
||||
envSource.OTEL_TRACES_SAMPLER_ARG = '2';
|
||||
const tracer = new Tracer(
|
||||
{ name: 'default', version: '0.0.1' },
|
||||
{},
|
||||
tracerProvider['_resource'],
|
||||
tracerProvider['_activeSpanProcessor']
|
||||
);
|
||||
const span = tracer.startSpan('my-span');
|
||||
const context = span.spanContext();
|
||||
assert.strictEqual(context.traceFlags, TraceFlags.SAMPLED);
|
||||
span.end();
|
||||
});
|
||||
|
||||
it('should not sample a trace when OTEL_TRACES_SAMPLER_ARG is 0', () => {
|
||||
envSource.OTEL_TRACES_SAMPLER = 'traceidratio';
|
||||
envSource.OTEL_TRACES_SAMPLER_ARG = '0';
|
||||
const tracer = new Tracer(
|
||||
{ name: 'default', version: '0.0.1' },
|
||||
{},
|
||||
tracerProvider['_resource'],
|
||||
tracerProvider['_activeSpanProcessor']
|
||||
);
|
||||
const span = tracer.startSpan('my-span');
|
||||
const context = span.spanContext();
|
||||
assert.strictEqual(context.traceFlags, TraceFlags.NONE);
|
||||
span.end();
|
||||
});
|
||||
|
||||
it('should start an active span with name and function args', () => {
|
||||
const tracer = new Tracer(
|
||||
{ name: 'default', version: '0.0.1' },
|
||||
|
|
|
@ -97,32 +97,6 @@ describe('BatchSpanProcessorBase', () => {
|
|||
assert.ok(processor instanceof BatchSpanProcessor);
|
||||
processor.shutdown();
|
||||
});
|
||||
|
||||
it('should read defaults from environment', () => {
|
||||
const bspConfig = {
|
||||
OTEL_BSP_MAX_EXPORT_BATCH_SIZE: 256,
|
||||
OTEL_BSP_SCHEDULE_DELAY: 2500,
|
||||
};
|
||||
|
||||
let env: Record<string, any>;
|
||||
if (global.process?.versions?.node === undefined) {
|
||||
env = globalThis as unknown as Record<string, any>;
|
||||
} else {
|
||||
env = process.env as Record<string, any>;
|
||||
}
|
||||
|
||||
Object.entries(bspConfig).forEach(([k, v]) => {
|
||||
env[k] = v;
|
||||
});
|
||||
|
||||
const processor = new BatchSpanProcessor(exporter);
|
||||
assert.ok(processor instanceof BatchSpanProcessor);
|
||||
assert.strictEqual(processor['_maxExportBatchSize'], 256);
|
||||
assert.strictEqual(processor['_scheduledDelayMillis'], 2500);
|
||||
processor.shutdown();
|
||||
|
||||
Object.keys(bspConfig).forEach(k => delete env[k]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.onStart/.onEnd/.shutdown', () => {
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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 { context, trace } from '@opentelemetry/api';
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import { BasicTracerProvider } from '../../src';
|
||||
import { Tracer } from '../../src/Tracer';
|
||||
|
||||
describe('BasicTracerProvider - Node', () => {
|
||||
beforeEach(() => {
|
||||
// to avoid actually registering the TraceProvider and leaking env to other tests
|
||||
sinon.stub(trace, 'setGlobalTracerProvider');
|
||||
context.disable();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
describe('spanLimits', () => {
|
||||
describe('when attribute value length limit is defined via env', () => {
|
||||
it('should have general attribute value length limits value as defined with env', () => {
|
||||
process.env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = '115';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeValueLengthLimit, 115);
|
||||
delete process.env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
});
|
||||
it('should have span attribute value length limit value same as general limit value', () => {
|
||||
process.env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = '125';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
assert.strictEqual(generalLimits.attributeValueLengthLimit, 125);
|
||||
assert.strictEqual(spanLimits.attributeValueLengthLimit, 125);
|
||||
delete process.env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
});
|
||||
it('should have span and general attribute value length limits as defined in env', () => {
|
||||
process.env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = '125';
|
||||
process.env.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = '109';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeValueLengthLimit, 125);
|
||||
assert.strictEqual(spanLimits.attributeValueLengthLimit, 109);
|
||||
delete process.env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
delete process.env.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when attribute count limit is defined via env', () => {
|
||||
it('should general attribute count limit as defined with env', () => {
|
||||
process.env.OTEL_ATTRIBUTE_COUNT_LIMIT = '25';
|
||||
const tracer = new BasicTracerProvider({}).getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeCountLimit, 25);
|
||||
delete process.env.OTEL_ATTRIBUTE_COUNT_LIMIT;
|
||||
});
|
||||
it('should have span attribute count limit value same as general limit value', () => {
|
||||
process.env.OTEL_ATTRIBUTE_COUNT_LIMIT = '20';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
assert.strictEqual(generalLimits.attributeCountLimit, 20);
|
||||
assert.strictEqual(spanLimits.attributeCountLimit, 20);
|
||||
delete process.env.OTEL_ATTRIBUTE_COUNT_LIMIT;
|
||||
});
|
||||
it('should have span and general attribute count limits as defined in env', () => {
|
||||
process.env.OTEL_ATTRIBUTE_COUNT_LIMIT = '20';
|
||||
process.env.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = '35';
|
||||
const tracer = new BasicTracerProvider().getTracer(
|
||||
'default'
|
||||
) as Tracer;
|
||||
const spanLimits = tracer.getSpanLimits();
|
||||
const generalLimits = tracer.getGeneralLimits();
|
||||
assert.strictEqual(generalLimits.attributeCountLimit, 20);
|
||||
assert.strictEqual(spanLimits.attributeCountLimit, 35);
|
||||
delete process.env.OTEL_ATTRIBUTE_COUNT_LIMIT;
|
||||
delete process.env.OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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 { context, TraceFlags } from '@opentelemetry/api';
|
||||
import * as assert from 'assert';
|
||||
import { BasicTracerProvider } from '../../src';
|
||||
import { TestStackContextManager } from '../common/export/TestStackContextManager';
|
||||
import { Tracer } from '../../src/Tracer';
|
||||
|
||||
describe('Tracer', () => {
|
||||
const tracerProvider = new BasicTracerProvider();
|
||||
|
||||
beforeEach(() => {
|
||||
const contextManager = new TestStackContextManager().enable();
|
||||
context.setGlobalContextManager(contextManager);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
context.disable();
|
||||
delete process.env.OTEL_TRACES_SAMPLER;
|
||||
delete process.env.OTEL_TRACES_SAMPLER_ARG;
|
||||
});
|
||||
|
||||
it('should sample a trace when OTEL_TRACES_SAMPLER_ARG is unset', () => {
|
||||
process.env.OTEL_TRACES_SAMPLER = 'traceidratio';
|
||||
process.env.OTEL_TRACES_SAMPLER_ARG = '';
|
||||
const tracer = new Tracer(
|
||||
{ name: 'default', version: '0.0.1' },
|
||||
{},
|
||||
tracerProvider['_resource'],
|
||||
tracerProvider['_activeSpanProcessor']
|
||||
);
|
||||
const span = tracer.startSpan('my-span');
|
||||
const context = span.spanContext();
|
||||
assert.strictEqual(context.traceFlags, TraceFlags.SAMPLED);
|
||||
span.end();
|
||||
});
|
||||
|
||||
it('should not sample a trace when OTEL_TRACES_SAMPLER_ARG is out of range', () => {
|
||||
process.env.OTEL_TRACES_SAMPLER = 'traceidratio';
|
||||
process.env.OTEL_TRACES_SAMPLER_ARG = '2';
|
||||
const tracer = new Tracer(
|
||||
{ name: 'default', version: '0.0.1' },
|
||||
{},
|
||||
tracerProvider['_resource'],
|
||||
tracerProvider['_activeSpanProcessor']
|
||||
);
|
||||
const span = tracer.startSpan('my-span');
|
||||
const context = span.spanContext();
|
||||
assert.strictEqual(context.traceFlags, TraceFlags.SAMPLED);
|
||||
span.end();
|
||||
});
|
||||
|
||||
it('should not sample a trace when OTEL_TRACES_SAMPLER_ARG is 0', () => {
|
||||
process.env.OTEL_TRACES_SAMPLER = 'traceidratio';
|
||||
process.env.OTEL_TRACES_SAMPLER_ARG = '0';
|
||||
const tracer = new Tracer(
|
||||
{ name: 'default', version: '0.0.1' },
|
||||
{},
|
||||
tracerProvider['_resource'],
|
||||
tracerProvider['_activeSpanProcessor']
|
||||
);
|
||||
const span = tracer.startSpan('my-span');
|
||||
const context = span.spanContext();
|
||||
assert.strictEqual(context.traceFlags, TraceFlags.NONE);
|
||||
span.end();
|
||||
});
|
||||
});
|
|
@ -24,34 +24,27 @@ import {
|
|||
import { buildSamplerFromEnv } from '../../src/config';
|
||||
|
||||
describe('config', () => {
|
||||
let envSource: Record<string, any>;
|
||||
if (global.process?.versions?.node === undefined) {
|
||||
envSource = globalThis as unknown as Record<string, any>;
|
||||
} else {
|
||||
envSource = process.env as Record<string, any>;
|
||||
}
|
||||
|
||||
describe('buildSamplerFromEnv()', () => {
|
||||
afterEach(() => {
|
||||
delete envSource.OTEL_TRACES_SAMPLER;
|
||||
delete envSource.OTEL_TRACES_SAMPLER_ARG;
|
||||
delete process.env.OTEL_TRACES_SAMPLER;
|
||||
delete process.env.OTEL_TRACES_SAMPLER_ARG;
|
||||
});
|
||||
|
||||
it('should handle always_on case', () => {
|
||||
envSource.OTEL_TRACES_SAMPLER = 'always_on';
|
||||
process.env.OTEL_TRACES_SAMPLER = 'always_on';
|
||||
assert.ok(buildSamplerFromEnv() instanceof AlwaysOnSampler);
|
||||
assert.strictEqual(buildSamplerFromEnv().toString(), 'AlwaysOnSampler');
|
||||
});
|
||||
|
||||
it('should handle always_off case', () => {
|
||||
envSource.OTEL_TRACES_SAMPLER = 'always_off';
|
||||
process.env.OTEL_TRACES_SAMPLER = 'always_off';
|
||||
assert.ok(buildSamplerFromEnv() instanceof AlwaysOffSampler);
|
||||
assert.strictEqual(buildSamplerFromEnv().toString(), 'AlwaysOffSampler');
|
||||
});
|
||||
|
||||
it('should handle traceidratio case', () => {
|
||||
envSource.OTEL_TRACES_SAMPLER = 'traceidratio';
|
||||
envSource.OTEL_TRACES_SAMPLER_ARG = '0.1';
|
||||
process.env.OTEL_TRACES_SAMPLER = 'traceidratio';
|
||||
process.env.OTEL_TRACES_SAMPLER_ARG = '0.1';
|
||||
assert.ok(buildSamplerFromEnv() instanceof TraceIdRatioBasedSampler);
|
||||
assert.strictEqual(
|
||||
buildSamplerFromEnv().toString(),
|
||||
|
@ -60,7 +53,7 @@ describe('config', () => {
|
|||
});
|
||||
|
||||
it('should handle parentbased_always_on case', () => {
|
||||
envSource.OTEL_TRACES_SAMPLER = 'parentbased_always_on';
|
||||
process.env.OTEL_TRACES_SAMPLER = 'parentbased_always_on';
|
||||
assert.ok(buildSamplerFromEnv() instanceof ParentBasedSampler);
|
||||
assert.strictEqual(
|
||||
buildSamplerFromEnv().toString(),
|
||||
|
@ -69,7 +62,7 @@ describe('config', () => {
|
|||
});
|
||||
|
||||
it('should handle parentbased_always_off case', () => {
|
||||
envSource.OTEL_TRACES_SAMPLER = 'parentbased_always_off';
|
||||
process.env.OTEL_TRACES_SAMPLER = 'parentbased_always_off';
|
||||
assert.ok(buildSamplerFromEnv() instanceof ParentBasedSampler);
|
||||
assert.strictEqual(
|
||||
buildSamplerFromEnv().toString(),
|
||||
|
@ -78,8 +71,8 @@ describe('config', () => {
|
|||
});
|
||||
|
||||
it('should handle parentbased_traceidratio case', () => {
|
||||
envSource.OTEL_TRACES_SAMPLER = 'parentbased_traceidratio';
|
||||
envSource.OTEL_TRACES_SAMPLER_ARG = '0.2';
|
||||
process.env.OTEL_TRACES_SAMPLER = 'parentbased_traceidratio';
|
||||
process.env.OTEL_TRACES_SAMPLER_ARG = '0.2';
|
||||
assert.ok(buildSamplerFromEnv() instanceof ParentBasedSampler);
|
||||
assert.strictEqual(
|
||||
buildSamplerFromEnv().toString(),
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 * as assert from 'assert';
|
||||
import { BufferConfig, InMemorySpanExporter } from '../../../src';
|
||||
import { BatchSpanProcessorBase } from '../../../src/export/BatchSpanProcessorBase';
|
||||
|
||||
class BatchSpanProcessor extends BatchSpanProcessorBase<BufferConfig> {
|
||||
onShutdown() {}
|
||||
}
|
||||
|
||||
describe('BatchSpanProcessorBase', () => {
|
||||
describe('constructor', () => {
|
||||
it('should read defaults from environment', () => {
|
||||
const exporter = new InMemorySpanExporter();
|
||||
const bspConfig = {
|
||||
OTEL_BSP_MAX_EXPORT_BATCH_SIZE: 256,
|
||||
OTEL_BSP_SCHEDULE_DELAY: 2500,
|
||||
};
|
||||
|
||||
let env: Record<string, any>;
|
||||
if (global.process?.versions?.node === undefined) {
|
||||
env = globalThis as unknown as Record<string, any>;
|
||||
} else {
|
||||
env = process.env as Record<string, any>;
|
||||
}
|
||||
|
||||
Object.entries(bspConfig).forEach(([k, v]) => {
|
||||
env[k] = v;
|
||||
});
|
||||
|
||||
const processor = new BatchSpanProcessor(exporter);
|
||||
assert.ok(processor instanceof BatchSpanProcessor);
|
||||
assert.strictEqual(processor['_maxExportBatchSize'], 256);
|
||||
assert.strictEqual(processor['_scheduledDelayMillis'], 2500);
|
||||
processor.shutdown();
|
||||
|
||||
Object.keys(bspConfig).forEach(k => delete env[k]);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue