From fa1c8ea2bdbcdcf0a1de59936d3292df6ed4f79b Mon Sep 17 00:00:00 2001 From: Bartlomiej Obecny Date: Fri, 12 Jun 2020 20:13:29 +0200 Subject: [PATCH 1/3] chore: adding platform specific class for getting environment variables --- packages/opentelemetry-api/src/index.ts | 1 + .../src/platform/browser/environment.ts | 33 +++++++ .../src/platform/browser/index.ts | 1 + .../src/platform/node/environment.ts | 30 ++++++ .../src/platform/node/index.ts | 3 +- .../src/utils/environment.ts | 97 +++++++++++++++++++ .../test/utils/environment.test.ts | 92 ++++++++++++++++++ 7 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 packages/opentelemetry-core/src/platform/browser/environment.ts create mode 100644 packages/opentelemetry-core/src/platform/node/environment.ts create mode 100644 packages/opentelemetry-core/src/utils/environment.ts create mode 100644 packages/opentelemetry-core/test/utils/environment.test.ts diff --git a/packages/opentelemetry-api/src/index.ts b/packages/opentelemetry-api/src/index.ts index 2f5f81ac99..00f971f5c8 100644 --- a/packages/opentelemetry-api/src/index.ts +++ b/packages/opentelemetry-api/src/index.ts @@ -30,6 +30,7 @@ export * from './metrics/MetricObservable'; export * from './metrics/NoopMeter'; export * from './metrics/NoopMeterProvider'; export * from './metrics/ObserverResult'; +export * from './platform'; export * from './trace/attributes'; export * from './trace/Event'; export * from './trace/instrumentation/Plugin'; diff --git a/packages/opentelemetry-core/src/platform/browser/environment.ts b/packages/opentelemetry-core/src/platform/browser/environment.ts new file mode 100644 index 0000000000..66e3e993cc --- /dev/null +++ b/packages/opentelemetry-core/src/platform/browser/environment.ts @@ -0,0 +1,33 @@ +/* + * 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 { + DEFAULT_ENVIRONMENT, + ENVIRONMENT, + ENVIRONMENT_MAP, + parseEnvironment, +} from '../../utils/environment'; +import * as api from '@opentelemetry/api'; + +/** + * Gets the environment variables + */ +export function getEnv(): ENVIRONMENT { + const globalEnv = parseEnvironment( + (api._globalThis as unknown) as ENVIRONMENT_MAP + ); + return Object.assign({}, DEFAULT_ENVIRONMENT, globalEnv); +} diff --git a/packages/opentelemetry-core/src/platform/browser/index.ts b/packages/opentelemetry-core/src/platform/browser/index.ts index d066951cf9..20c47613e6 100644 --- a/packages/opentelemetry-core/src/platform/browser/index.ts +++ b/packages/opentelemetry-core/src/platform/browser/index.ts @@ -15,6 +15,7 @@ */ export * from './BasePlugin'; +export * from './environment'; export * from './hex-to-base64'; export * from './id'; export * from './performance'; diff --git a/packages/opentelemetry-core/src/platform/node/environment.ts b/packages/opentelemetry-core/src/platform/node/environment.ts new file mode 100644 index 0000000000..f3595cd9af --- /dev/null +++ b/packages/opentelemetry-core/src/platform/node/environment.ts @@ -0,0 +1,30 @@ +/* + * 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 { + DEFAULT_ENVIRONMENT, + ENVIRONMENT, + ENVIRONMENT_MAP, + parseEnvironment, +} from '../../utils/environment'; + +/** + * Gets the environment variables + */ +export function getEnv(): ENVIRONMENT { + const processEnv = parseEnvironment(process.env as ENVIRONMENT_MAP); + return Object.assign({}, DEFAULT_ENVIRONMENT, processEnv); +} diff --git a/packages/opentelemetry-core/src/platform/node/index.ts b/packages/opentelemetry-core/src/platform/node/index.ts index 693bef3145..20c47613e6 100644 --- a/packages/opentelemetry-core/src/platform/node/index.ts +++ b/packages/opentelemetry-core/src/platform/node/index.ts @@ -15,8 +15,9 @@ */ export * from './BasePlugin'; +export * from './environment'; +export * from './hex-to-base64'; export * from './id'; export * from './performance'; export * from './sdk-info'; export * from './timer-util'; -export * from './hex-to-base64'; diff --git a/packages/opentelemetry-core/src/utils/environment.ts b/packages/opentelemetry-core/src/utils/environment.ts new file mode 100644 index 0000000000..be56f892c0 --- /dev/null +++ b/packages/opentelemetry-core/src/utils/environment.ts @@ -0,0 +1,97 @@ +/* + * 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 { LogLevel } from '../common/types'; + +export type ENVIRONMENT_MAP = { [key: string]: string | number }; + +/** + * Environment interface to define all names + */ +export interface ENVIRONMENT { + OTEL_LOG_LEVEL?: LogLevel; + OTEL_NO_PATCH_MODULES?: string; + OTEL_SAMPLING_PROBABILITY?: number; +} + +const ENVIRONMENT_NUMBERS: Partial[] = [ + 'OTEL_LOG_LEVEL', + 'OTEL_SAMPLING_PROBABILITY', +]; + +/** + * Default environment variables + */ +export const DEFAULT_ENVIRONMENT: ENVIRONMENT = { + OTEL_NO_PATCH_MODULES: '', + OTEL_LOG_LEVEL: LogLevel.ERROR, + OTEL_SAMPLING_PROBABILITY: 1, +}; + +/** + * Parses a variable as number with number validation + * @param name + * @param environment + * @param values + * @param min + * @param max + */ +function parseNumber( + name: keyof ENVIRONMENT, + environment: ENVIRONMENT_MAP | ENVIRONMENT, + values: ENVIRONMENT_MAP, + min = -Infinity, + max = Infinity +) { + if (typeof values[name] !== 'undefined') { + const value = Number(values[name] as string); + if (!isNaN(value) && value >= min && value <= max) { + environment[name] = value; + } + } +} + +/** + * Parses environment values + * @param values + */ +export function parseEnvironment(values: ENVIRONMENT_MAP): ENVIRONMENT { + const environment: ENVIRONMENT_MAP = {}; + + for (const env in DEFAULT_ENVIRONMENT) { + const key = env as keyof ENVIRONMENT; + switch (key) { + case 'OTEL_SAMPLING_PROBABILITY': + parseNumber(key, environment, values, 0, 1); + break; + + case 'OTEL_LOG_LEVEL': + parseNumber(key, environment, values, LogLevel.ERROR, LogLevel.DEBUG); + break; + + default: + if (ENVIRONMENT_NUMBERS.indexOf(key) >= 0) { + parseNumber(key, environment, values); + } else { + if (typeof values[key] !== 'undefined') { + environment[key] = values[key]; + } + } + } + } + + return environment; +} diff --git a/packages/opentelemetry-core/test/utils/environment.test.ts b/packages/opentelemetry-core/test/utils/environment.test.ts new file mode 100644 index 0000000000..267a6bf285 --- /dev/null +++ b/packages/opentelemetry-core/test/utils/environment.test.ts @@ -0,0 +1,92 @@ +/* + * 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 { getEnv } from '../../src/platform'; +import { + DEFAULT_ENVIRONMENT, + ENVIRONMENT, + ENVIRONMENT_MAP, +} from '../../src/utils/environment'; +import * as assert from 'assert'; +import * as sinon from 'sinon'; + +let lastMock: ENVIRONMENT_MAP = {}; + +function mockEnvironment(values: ENVIRONMENT_MAP) { + lastMock = values; + if (typeof process !== 'undefined') { + Object.keys(values).forEach(key => { + process.env[key] = String(values[key]); + }); + } else { + Object.keys(values).forEach(key => { + ((window as unknown) as ENVIRONMENT_MAP)[key] = String(values[key]); + }); + } +} + +function removeMockEnvironment() { + if (typeof process !== 'undefined') { + Object.keys(lastMock).forEach(key => { + delete process.env[key]; + }); + } else { + Object.keys(lastMock).forEach(key => { + delete ((window as unknown) as ENVIRONMENT_MAP)[key]; + }); + } + lastMock = {}; +} + +describe('environment', () => { + let sandbox: sinon.SinonSandbox; + + beforeEach(() => { + sandbox = sinon.createSandbox(); + }); + + afterEach(() => { + removeMockEnvironment(); + sandbox.restore(); + }); + + describe('parseEnvironment', () => { + it('should parse environment variables', () => { + mockEnvironment({ + FOO: '1', + OTEL_NO_PATCH_MODULES: 'a,b,c', + OTEL_LOG_LEVEL: '1', + OTEL_SAMPLING_PROBABILITY: '0.5', + }); + const env = getEnv(); + assert.strictEqual(env.OTEL_NO_PATCH_MODULES, 'a,b,c'); + assert.strictEqual(env.OTEL_LOG_LEVEL, 1); + assert.strictEqual(env.OTEL_SAMPLING_PROBABILITY, 0.5); + }); + + it('should parse environment variables and use defaults', () => { + const env = getEnv(); + Object.keys(DEFAULT_ENVIRONMENT).forEach(envKey => { + const key = envKey as keyof ENVIRONMENT; + assert.strictEqual( + env[key as keyof ENVIRONMENT], + DEFAULT_ENVIRONMENT[key], + `Variable '${key}' doesn't match` + ); + }); + }); + }); +}); From a939c7e9b8a5a239f4d86c509519a45ac517fb4f Mon Sep 17 00:00:00 2001 From: Bartlomiej Obecny Date: Mon, 22 Jun 2020 22:27:10 +0200 Subject: [PATCH 2/3] chore: removing globalthis --- packages/opentelemetry-api/src/index.ts | 1 - .../opentelemetry-core/src/platform/browser/environment.ts | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/opentelemetry-api/src/index.ts b/packages/opentelemetry-api/src/index.ts index 00f971f5c8..2f5f81ac99 100644 --- a/packages/opentelemetry-api/src/index.ts +++ b/packages/opentelemetry-api/src/index.ts @@ -30,7 +30,6 @@ export * from './metrics/MetricObservable'; export * from './metrics/NoopMeter'; export * from './metrics/NoopMeterProvider'; export * from './metrics/ObserverResult'; -export * from './platform'; export * from './trace/attributes'; export * from './trace/Event'; export * from './trace/instrumentation/Plugin'; diff --git a/packages/opentelemetry-core/src/platform/browser/environment.ts b/packages/opentelemetry-core/src/platform/browser/environment.ts index 66e3e993cc..b862581544 100644 --- a/packages/opentelemetry-core/src/platform/browser/environment.ts +++ b/packages/opentelemetry-core/src/platform/browser/environment.ts @@ -20,14 +20,11 @@ import { ENVIRONMENT_MAP, parseEnvironment, } from '../../utils/environment'; -import * as api from '@opentelemetry/api'; /** * Gets the environment variables */ export function getEnv(): ENVIRONMENT { - const globalEnv = parseEnvironment( - (api._globalThis as unknown) as ENVIRONMENT_MAP - ); + const globalEnv = parseEnvironment((window as unknown) as ENVIRONMENT_MAP); return Object.assign({}, DEFAULT_ENVIRONMENT, globalEnv); } From ced305a74f758550c56d2c8d6d0989a5719d99de Mon Sep 17 00:00:00 2001 From: Bartlomiej Obecny Date: Thu, 25 Jun 2020 18:45:24 +0200 Subject: [PATCH 3/3] chore: reviews --- .../opentelemetry-core/src/platform/browser/environment.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/opentelemetry-core/src/platform/browser/environment.ts b/packages/opentelemetry-core/src/platform/browser/environment.ts index b862581544..54a2a6c571 100644 --- a/packages/opentelemetry-core/src/platform/browser/environment.ts +++ b/packages/opentelemetry-core/src/platform/browser/environment.ts @@ -25,6 +25,7 @@ import { * Gets the environment variables */ export function getEnv(): ENVIRONMENT { - const globalEnv = parseEnvironment((window as unknown) as ENVIRONMENT_MAP); + const _window = window as typeof window & ENVIRONMENT_MAP; + const globalEnv = parseEnvironment(_window); return Object.assign({}, DEFAULT_ENVIRONMENT, globalEnv); }