From d4ab03fc5672ca21a970cf137b666cb55aa27c91 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Mon, 29 Aug 2022 09:31:40 +0200 Subject: [PATCH 01/77] chore(sdk-metrics): clean up exports (#3197) * chore(sdk-metrics): clean up exports * fix(changelog): add entry. * fix(changelog): move entry to unreleased. * fix: add TimeoutError back. * fix: add CollectionResult back in and update changelog. --- experimental/CHANGELOG.md | 10 ++ .../src/export/MetricData.ts | 2 +- .../opentelemetry-sdk-metrics/src/index.ts | 92 +++++++++++++++---- .../test/ObservableResult.test.ts | 7 +- .../test/state/MeterSharedState.test.ts | 2 +- .../test/state/MetricCollector.test.ts | 3 +- 6 files changed, 95 insertions(+), 21 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 23c2624293..f420b3f468 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -6,6 +6,16 @@ All notable changes to experimental packages in this project will be documented ### :boom: Breaking Change +* chore(metrics-sdk): clean up exports [#3197](https://github.com/open-telemetry/opentelemetry-js/pull/3197) @pichlermarc + * removes export for: + * `AccumulationRecord` + * `Aggregator` + * `AggregatorKind` + * `Accumulation` + * `createInstrumentDescriptor` + * `createInstrumentDescriptorWithView` + * `isDescriptorCompatibleWith` + ### :rocket: (Enhancement) ### :bug: (Bug Fix) diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts index 36e031e2d3..f31c748e0b 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts @@ -25,7 +25,7 @@ import { Histogram } from '../aggregator/types'; /** * Basic metric data fields. */ -export interface BaseMetricData { +interface BaseMetricData { readonly descriptor: InstrumentDescriptor; readonly aggregationTemporality: AggregationTemporality; /** diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/index.ts b/experimental/packages/opentelemetry-sdk-metrics/src/index.ts index e9ad1ef4b9..3ce97504de 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/index.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/index.ts @@ -14,19 +14,79 @@ * limitations under the License. */ -export { Sum, LastValue, Histogram } from './aggregator/types'; -export * from './export/AggregationTemporality'; -export * from './export/MetricData'; -export * from './export/MetricExporter'; -export * from './export/MetricProducer'; -export * from './export/MetricReader'; -export * from './export/PeriodicExportingMetricReader'; -export * from './export/InMemoryMetricExporter'; -export * from './export/ConsoleMetricExporter'; -export { InstrumentDescriptor, InstrumentType } from './InstrumentDescriptor'; -export * from './Meter'; -export * from './MeterProvider'; -export * from './ObservableResult'; -export { TimeoutError } from './utils'; -export * from './view/Aggregation'; -export * from './view/View'; +export { + Sum, + LastValue, + Histogram, +} from './aggregator/types'; + +export { + AggregationTemporality, + AggregationTemporalitySelector, +} from './export/AggregationTemporality'; + +export { + DataPoint, + DataPointType, + SumMetricData, + GaugeMetricData, + HistogramMetricData, + ResourceMetrics, + ScopeMetrics, + MetricData, + CollectionResult, +} from './export/MetricData'; + +export { + PushMetricExporter, +} from './export/MetricExporter'; + +export { + MetricReader, +} from './export/MetricReader'; + +export { + PeriodicExportingMetricReader, + PeriodicExportingMetricReaderOptions, +} from './export/PeriodicExportingMetricReader'; + +export { + InMemoryMetricExporter, +} from './export/InMemoryMetricExporter'; + +export { + ConsoleMetricExporter, +} from './export/ConsoleMetricExporter'; + +export { + InstrumentDescriptor, + InstrumentType, +} from './InstrumentDescriptor'; + +export { + Meter, +} from './Meter'; + +export { + MeterProvider, + MeterProviderOptions, +} from './MeterProvider'; + +export { + DefaultAggregation, + ExplicitBucketHistogramAggregation, + DropAggregation, + HistogramAggregation, + LastValueAggregation, + SumAggregation, + Aggregation +} from './view/Aggregation'; + +export { + View, + ViewOptions, +} from './view/View'; + +export { + TimeoutError +} from './utils'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts index f6a38ce443..aaa97768b8 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts @@ -16,9 +16,12 @@ import { ValueType } from '@opentelemetry/api-metrics'; import * as assert from 'assert'; -import { BatchObservableResultImpl, InstrumentType } from '../src'; +import { InstrumentType } from '../src'; import { ObservableInstrument } from '../src/Instruments'; -import { ObservableResultImpl } from '../src/ObservableResult'; +import { + BatchObservableResultImpl, + ObservableResultImpl +} from '../src/ObservableResult'; import { ObservableRegistry } from '../src/state/ObservableRegistry'; import { commonAttributes, commonValues, defaultInstrumentDescriptor } from './util'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts index bacbe87e3f..0a4b504b9f 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts @@ -21,12 +21,12 @@ import { Meter, MeterProvider, DataPointType, - CollectionResult, View } from '../../src'; import { assertMetricData, defaultInstrumentationScope, defaultResource, sleep } from '../util'; import { TestMetricReader } from '../export/TestMetricReader'; import { MeterSharedState } from '../../src/state/MeterSharedState'; +import { CollectionResult } from '../../src/export/MetricData'; describe('MeterSharedState', () => { afterEach(() => { diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts index 77047d9f52..ad65f1c027 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts @@ -16,7 +16,8 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; -import { MeterProvider, TimeoutError } from '../../src'; +import { MeterProvider } from '../../src'; +import { TimeoutError } from '../../src/utils'; import { DataPointType } from '../../src/export/MetricData'; import { PushMetricExporter } from '../../src/export/MetricExporter'; import { MeterProviderSharedState } from '../../src/state/MeterProviderSharedState'; From bd9159a35331406cbbd790c0d4542b1cebf3b442 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Mon, 29 Aug 2022 22:45:25 +0200 Subject: [PATCH 02/77] chore: cleanup eslint (#3209) --- eslint.config.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 3c65700699..5e8f1b50e6 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -13,7 +13,7 @@ module.exports = { "indent": ["error", 2, { "SwitchCase": 1 }], "no-trailing-spaces": "error", "eol-last": "error", - "quotes": [2, "single", { "avoidEscape": true }], + "quotes": ["error", "single", { "avoidEscape": true }], "brace-style": ["error", "1tbs"], "eqeqeq": [ "error", @@ -24,7 +24,7 @@ module.exports = { "no-shadow": "off", "arrow-parens": ["error", "as-needed"], "node/no-deprecated-api": ["warn"], - "header/header": [2, "block", [{ + "header/header": ["error", "block", [{ pattern: / \* Copyright The OpenTelemetry Authors[\r\n]+ \*[\r\n]+ \* Licensed under the Apache License, Version 2\.0 \(the \"License\"\);[\r\n]+ \* you may not use this file except in compliance with the License\.[\r\n]+ \* You may obtain a copy of the License at[\r\n]+ \*[\r\n]+ \* https:\/\/www\.apache\.org\/licenses\/LICENSE-2\.0[\r\n]+ \*[\r\n]+ \* Unless required by applicable law or agreed to in writing, software[\r\n]+ \* distributed under the License is distributed on an \"AS IS\" BASIS,[\r\n]+ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.[\r\n]+ \* See the License for the specific language governing permissions and[\r\n]+ \* limitations under the License\./gm, template: `\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n ` @@ -34,7 +34,7 @@ module.exports = { { files: ['*.ts'], rules: { - "@typescript-eslint/no-floating-promises": 2, + "@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/no-this-alias": "off", "@typescript-eslint/naming-convention": [ "error", @@ -45,7 +45,6 @@ module.exports = { "leadingUnderscore": "require" } ], - "@typescript-eslint/no-shadow": ["warn"], "@typescript-eslint/no-unused-vars": ["error", {"argsIgnorePattern": "^_", "args": "after-used"}], "@typescript-eslint/no-inferrable-types": ["error", { ignoreProperties: true }], "@typescript-eslint/no-empty-function": ["off"], @@ -65,7 +64,6 @@ module.exports = { "@typescript-eslint/ban-ts-ignore": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-floating-promises": 1, "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-var-requires": "off", "@typescript-eslint/no-shadow": ["off"], From dd22372a09236a62cfff6edb93527643af99a937 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Thu, 1 Sep 2022 13:57:05 +0800 Subject: [PATCH 03/77] feat(sdk-metrics-base): per metric-reader aggregation (#3153) --- experimental/CHANGELOG.md | 1 + .../test/OTLPMetricExporter.test.ts | 11 +- .../test/metricsHelper.ts | 5 + .../browser/CollectorMetricExporter.test.ts | 48 +++-- .../test/metricsHelper.ts | 5 + .../test/node/CollectorMetricExporter.test.ts | 23 ++- .../test/OTLPMetricExporter.test.ts | 11 +- .../test/metricsHelper.ts | 5 + .../src/PrometheusExporter.ts | 6 +- .../test/PrometheusExporter.test.ts | 29 ++- .../test/PrometheusSerializer.test.ts | 5 + .../src/export/AggregationSelector.ts | 29 +++ .../src/export/AggregationTemporality.ts | 4 - .../src/export/MetricReader.ts | 7 + .../export/PeriodicExportingMetricReader.ts | 38 +++- .../opentelemetry-sdk-metrics/src/index.ts | 6 +- .../src/state/MeterProviderSharedState.ts | 11 +- .../src/state/MeterSharedState.ts | 71 +++++--- .../src/state/MetricCollector.ts | 6 +- .../src/state/MetricStorage.ts | 2 +- .../src/state/MetricStorageRegistry.ts | 85 +++++++-- .../src/view/ViewRegistry.ts | 6 - .../test/Instruments.test.ts | 7 +- .../test/export/MetricReader.test.ts | 51 +++++- .../PeriodicExportingMetricReader.test.ts | 64 +------ .../test/export/TestMetricProducer.ts | 30 ++++ .../test/export/TestMetricReader.ts | 26 ++- .../test/state/MeterSharedState.test.ts | 119 +++++++++++- .../test/state/MetricCollector.test.ts | 32 ++-- .../test/state/MetricStorageRegistry.test.ts | 169 ++++++++++++++---- .../test/view/ViewRegistry.test.ts | 7 - 31 files changed, 667 insertions(+), 252 deletions(-) create mode 100644 experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts create mode 100644 experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricProducer.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index f420b3f468..8d5b302561 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -36,6 +36,7 @@ All notable changes to experimental packages in this project will be documented * feature(add-console-metrics-exporter): add ConsoleMetricExporter [#3120](https://github.com/open-telemetry/opentelemetry-js/pull/3120) @weyert * feature(prometheus-serialiser): export the unit block when unit is set in metric descriptor [#3066](https://github.com/open-telemetry/opentelemetry-js/pull/3041) @weyert * feat: support latest `@opentelemetry/api` [#3177](https://github.com/open-telemetry/opentelemetry-js/pull/3177) @dyladan +* feat(sdk-metrics-base): add per metric-reader aggregation support [#3153](https://github.com/open-telemetry/opentelemetry-js/pull/3153) @legendecas ### :bug: (Bug Fix) diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/OTLPMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/OTLPMetricExporter.test.ts index e6d4ced369..08a30aca3e 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/OTLPMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/OTLPMetricExporter.test.ts @@ -214,13 +214,18 @@ const testOTLPMetricExporter = (params: TestParams) => assert.ok(exportedData, 'exportedData does not exist'); + // The order of the metrics is not guaranteed. + const counterIndex = exportedData[0].scopeMetrics[0].metrics.findIndex(it => it.name === 'int-counter'); + const observableIndex = exportedData[0].scopeMetrics[0].metrics.findIndex(it => it.name === 'double-observable-gauge'); + const histogramIndex = exportedData[0].scopeMetrics[0].metrics.findIndex(it => it.name === 'int-histogram'); + const resource = exportedData[0].resource; const counter = - exportedData[0].scopeMetrics[0].metrics[0]; + exportedData[0].scopeMetrics[0].metrics[counterIndex]; const observableGauge = - exportedData[0].scopeMetrics[0].metrics[1]; + exportedData[0].scopeMetrics[0].metrics[observableIndex]; const histogram = - exportedData[0].scopeMetrics[0].metrics[2]; + exportedData[0].scopeMetrics[0].metrics[histogramIndex]; ensureExportedCounterIsCorrect( counter, counter.sum?.dataPoints[0].timeUnixNano, diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts index 88d91a872b..0ca7df3226 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts @@ -20,6 +20,7 @@ import * as assert from 'assert'; import * as grpc from '@grpc/grpc-js'; import { VERSION } from '@opentelemetry/core'; import { + Aggregation, AggregationTemporality, ExplicitBucketHistogramAggregation, MeterProvider, @@ -29,6 +30,10 @@ import { import { IKeyValue, IMetric, IResource } from '@opentelemetry/otlp-transformer'; class TestMetricReader extends MetricReader { + selectAggregation() { + return Aggregation.Default(); + } + selectAggregationTemporality() { return AggregationTemporality.CUMULATIVE; } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts index b0b95ce0be..166dbc4a81 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts @@ -99,6 +99,7 @@ describe('OTLPMetricExporter - web', () => { temporalityPreference: AggregationTemporality.CUMULATIVE }); }); + it('should successfully send metrics using sendBeacon', done => { collectorExporter.export(metrics, () => { }); @@ -109,16 +110,22 @@ describe('OTLPMetricExporter - web', () => { const blob: Blob = args[1]; const body = await blob.text(); const json = JSON.parse(body) as IExportMetricsServiceRequest; - const metric1 = json.resourceMetrics[0].scopeMetrics[0].metrics[0]; - const metric2 = json.resourceMetrics[0].scopeMetrics[0].metrics[1]; - const metric3 = json.resourceMetrics[0].scopeMetrics[0].metrics[2]; + + // The order of the metrics is not guaranteed. + const counterIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'int-counter'); + const observableIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'double-observable-gauge2'); + const histogramIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'int-histogram'); + + const metric1 = json.resourceMetrics[0].scopeMetrics[0].metrics[counterIndex]; + const metric2 = json.resourceMetrics[0].scopeMetrics[0].metrics[observableIndex]; + const metric3 = json.resourceMetrics[0].scopeMetrics[0].metrics[histogramIndex]; assert.ok(typeof metric1 !== 'undefined', "metric doesn't exist"); ensureCounterIsCorrect( metric1, - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[0].dataPoints[0].endTime), - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[0].dataPoints[0].startTime) + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].endTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].startTime) ); @@ -128,8 +135,8 @@ describe('OTLPMetricExporter - web', () => { ); ensureObservableGaugeIsCorrect( metric2, - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[1].dataPoints[0].endTime), - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[1].dataPoints[0].startTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0].endTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0].startTime), 6, 'double-observable-gauge2' ); @@ -140,8 +147,8 @@ describe('OTLPMetricExporter - web', () => { ); ensureHistogramIsCorrect( metric3, - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[2].dataPoints[0].endTime), - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[2].dataPoints[0].startTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0].endTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0].startTime), [0, 100], [0, 2, 0] ); @@ -216,15 +223,20 @@ describe('OTLPMetricExporter - web', () => { const body = request.requestBody; const json = JSON.parse(body) as IExportMetricsServiceRequest; - const metric1 = json.resourceMetrics[0].scopeMetrics[0].metrics[0]; - const metric2 = json.resourceMetrics[0].scopeMetrics[0].metrics[1]; - const metric3 = json.resourceMetrics[0].scopeMetrics[0].metrics[2]; + // The order of the metrics is not guaranteed. + const counterIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'int-counter'); + const observableIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'double-observable-gauge2'); + const histogramIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'int-histogram'); + + const metric1 = json.resourceMetrics[0].scopeMetrics[0].metrics[counterIndex]; + const metric2 = json.resourceMetrics[0].scopeMetrics[0].metrics[observableIndex]; + const metric3 = json.resourceMetrics[0].scopeMetrics[0].metrics[histogramIndex]; assert.ok(typeof metric1 !== 'undefined', "metric doesn't exist"); ensureCounterIsCorrect( metric1, - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[0].dataPoints[0].endTime), - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[0].dataPoints[0].startTime) + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].endTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].startTime) ); assert.ok( @@ -233,8 +245,8 @@ describe('OTLPMetricExporter - web', () => { ); ensureObservableGaugeIsCorrect( metric2, - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[1].dataPoints[0].endTime), - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[1].dataPoints[0].startTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0].endTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0].startTime), 6, 'double-observable-gauge2' ); @@ -245,8 +257,8 @@ describe('OTLPMetricExporter - web', () => { ); ensureHistogramIsCorrect( metric3, - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[2].dataPoints[0].endTime), - hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[2].dataPoints[0].startTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0].endTime), + hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0].startTime), [0, 100], [0, 2, 0] ); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts index 40a08775bf..8cb3811f81 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts @@ -27,6 +27,7 @@ import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; import { InstrumentationScope, VERSION } from '@opentelemetry/core'; import { + Aggregation, AggregationTemporality, ExplicitBucketHistogramAggregation, MeterProvider, @@ -57,6 +58,10 @@ class TestMetricReader extends MetricReader { return Promise.resolve(undefined); } + selectAggregation() { + return Aggregation.Default(); + } + selectAggregationTemporality() { return AggregationTemporality.CUMULATIVE; } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts index 9cdbaed7e0..77c5023153 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts @@ -288,29 +288,34 @@ describe('OTLPMetricExporter - node with json over http', () => { const responseBody = buff.toString(); const json = JSON.parse(responseBody) as IExportMetricsServiceRequest; - const metric1 = json.resourceMetrics[0].scopeMetrics[0].metrics[0]; - const metric2 = json.resourceMetrics[0].scopeMetrics[0].metrics[1]; - const metric3 = json.resourceMetrics[0].scopeMetrics[0].metrics[2]; + // The order of the metrics is not guaranteed. + const counterIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'int-counter'); + const observableIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'double-observable-gauge2'); + const histogramIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'int-histogram'); + + const metric1 = json.resourceMetrics[0].scopeMetrics[0].metrics[counterIndex]; + const metric2 = json.resourceMetrics[0].scopeMetrics[0].metrics[observableIndex]; + const metric3 = json.resourceMetrics[0].scopeMetrics[0].metrics[histogramIndex]; assert.ok(typeof metric1 !== 'undefined', "counter doesn't exist"); ensureCounterIsCorrect( metric1, - core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[0].dataPoints[0].endTime), - core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[0].dataPoints[0].startTime) + core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].endTime), + core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[counterIndex].dataPoints[0].startTime) ); assert.ok(typeof metric2 !== 'undefined', "observable gauge doesn't exist"); ensureObservableGaugeIsCorrect( metric2, - core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[1].dataPoints[0].endTime), - core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[1].dataPoints[0].startTime), + core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0].endTime), + core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[observableIndex].dataPoints[0].startTime), 6, 'double-observable-gauge2' ); assert.ok(typeof metric3 !== 'undefined', "histogram doesn't exist"); ensureHistogramIsCorrect( metric3, - core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[2].dataPoints[0].endTime), - core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[2].dataPoints[0].startTime), + core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0].endTime), + core.hrTimeToNanoseconds(metrics.scopeMetrics[0].metrics[histogramIndex].dataPoints[0].startTime), [0, 100], [0, 2, 0] ); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/OTLPMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/OTLPMetricExporter.test.ts index 38ea5db918..8ff43fed7c 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/OTLPMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/OTLPMetricExporter.test.ts @@ -240,9 +240,14 @@ describe('OTLPMetricExporter - node with proto over http', () => { const data = ExportTraceServiceRequestProto.decode(buff); const json = data?.toJSON() as IExportMetricsServiceRequest; - const metric1 = json.resourceMetrics[0].scopeMetrics[0].metrics[0]; - const metric2 = json.resourceMetrics[0].scopeMetrics[0].metrics[1]; - const metric3 = json.resourceMetrics[0].scopeMetrics[0].metrics[2]; + // The order of the metrics is not guaranteed. + const counterIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'int-counter'); + const observableIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'double-observable-gauge'); + const histogramIndex = metrics.scopeMetrics[0].metrics.findIndex(it => it.descriptor.name === 'int-histogram'); + + const metric1 = json.resourceMetrics[0].scopeMetrics[0].metrics[counterIndex]; + const metric2 = json.resourceMetrics[0].scopeMetrics[0].metrics[observableIndex]; + const metric3 = json.resourceMetrics[0].scopeMetrics[0].metrics[histogramIndex]; assert.ok(typeof metric1 !== 'undefined', "counter doesn't exist"); ensureExportedCounterIsCorrect( diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts index 0beb770ed8..3a69427f90 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts @@ -24,6 +24,7 @@ import { import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; import { + Aggregation, AggregationTemporality, ExplicitBucketHistogramAggregation, MeterProvider, @@ -34,6 +35,10 @@ import { IExportMetricsServiceRequest, IKeyValue, IMetric } from '@opentelemetry import { Stream } from 'stream'; export class TestMetricReader extends MetricReader { + selectAggregation() { + return Aggregation.Default(); + } + selectAggregationTemporality() { return AggregationTemporality.CUMULATIVE; } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts index c548b906dc..675472ec56 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts @@ -18,7 +18,7 @@ import { diag } from '@opentelemetry/api'; import { globalErrorHandler, } from '@opentelemetry/core'; -import { AggregationTemporality, MetricReader } from '@opentelemetry/sdk-metrics'; +import { Aggregation, AggregationTemporality, MetricReader } from '@opentelemetry/sdk-metrics'; import { createServer, IncomingMessage, Server, ServerResponse } from 'http'; import { ExporterConfig } from './export/types'; import { PrometheusSerializer } from './PrometheusSerializer'; @@ -90,6 +90,10 @@ export class PrometheusExporter extends MetricReader { } } + selectAggregation(): Aggregation { + return Aggregation.Default(); + } + selectAggregationTemporality(): AggregationTemporality { return AggregationTemporality.CUMULATIVE; } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts index 2a722e573a..080ac599e3 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts @@ -15,9 +15,7 @@ */ import { Meter, ObservableResult } from '@opentelemetry/api-metrics'; -import { - MeterProvider, -} from '@opentelemetry/sdk-metrics'; +import { MeterProvider } from '@opentelemetry/sdk-metrics'; import * as assert from 'assert'; import * as sinon from 'sinon'; import * as http from 'http'; @@ -480,22 +478,19 @@ describe('PrometheusExporter', () => { let meter: Meter; let meterProvider: MeterProvider; let counter: Counter; - let exporter: PrometheusExporter | undefined; + let exporter: PrometheusExporter; - beforeEach(() => { + function setup(reader: PrometheusExporter) { meterProvider = new MeterProvider(); + meterProvider.addMetricReader(reader); + meter = meterProvider.getMeter('test-prometheus'); counter = meter.createCounter('counter'); counter.add(10, { key1: 'attributeValue1' }); - }); + } - afterEach(done => { - if (exporter) { - exporter.shutdown().then(done); - exporter = undefined; - } else { - done(); - } + afterEach(async () => { + await exporter.shutdown(); }); it('should use a configured name prefix', done => { @@ -504,7 +499,7 @@ describe('PrometheusExporter', () => { prefix: 'test_prefix', }, async () => { - meterProvider.addMetricReader(exporter!); + setup(exporter); http .get('http://localhost:9464/metrics', res => { res.on('data', chunk => { @@ -532,7 +527,7 @@ describe('PrometheusExporter', () => { port: 8080, }, async () => { - meterProvider.addMetricReader(exporter!); + setup(exporter); http .get('http://localhost:8080/metrics', res => { res.on('data', chunk => { @@ -560,7 +555,7 @@ describe('PrometheusExporter', () => { endpoint: '/test', }, async () => { - meterProvider.addMetricReader(exporter!); + setup(exporter); http .get('http://localhost:9464/test', res => { res.on('data', chunk => { @@ -588,7 +583,7 @@ describe('PrometheusExporter', () => { appendTimestamp: false, }, async () => { - meterProvider.addMetricReader(exporter!); + setup(exporter); http .get('http://localhost:9464/metrics', res => { res.on('data', chunk => { diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts index c05f94f81c..00e082a861 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts @@ -17,6 +17,7 @@ import * as assert from 'assert'; import { MetricAttributes, UpDownCounter } from '@opentelemetry/api-metrics'; import { + Aggregation, AggregationTemporality, DataPoint, DataPointType, @@ -46,6 +47,10 @@ class TestMetricReader extends MetricReader { return AggregationTemporality.CUMULATIVE; } + selectAggregation() { + return Aggregation.Default(); + } + async onForceFlush() {} async onShutdown() {} diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts new file mode 100644 index 0000000000..8a372d0e74 --- /dev/null +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts @@ -0,0 +1,29 @@ +/* + * 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 { InstrumentType } from '../InstrumentDescriptor'; +import { Aggregation } from '../view/Aggregation'; +import { AggregationTemporality } from './AggregationTemporality'; + +/** + * Aggregation selector based on metric instrument types. + */ +export type AggregationSelector = (instrumentType: InstrumentType) => Aggregation; + +/** + * Aggregation temporality selector based on metric instrument types. + */ +export type AggregationTemporalitySelector = (instrumentType: InstrumentType) => AggregationTemporality; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationTemporality.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationTemporality.ts index 0b93671472..6cc6d1231b 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationTemporality.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationTemporality.ts @@ -14,8 +14,6 @@ * limitations under the License. */ -import { InstrumentType } from '../InstrumentDescriptor'; - /** * AggregationTemporality indicates the way additive quantities are expressed. */ @@ -23,5 +21,3 @@ export enum AggregationTemporality { DELTA, CUMULATIVE, } - -export type AggregationTemporalitySelector = (instrumentType: InstrumentType) => AggregationTemporality; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts index 35d86c5d94..3037384fcf 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts @@ -21,6 +21,7 @@ import { CollectionResult } from './MetricData'; import { callWithTimeout } from '../utils'; import { InstrumentType } from '../InstrumentDescriptor'; import { CollectionOptions, ForceFlushOptions, ShutdownOptions } from '../types'; +import { Aggregation } from '../view/Aggregation'; /** * A registered reader of metrics that, when linked to a {@link MetricProducer}, offers global @@ -46,6 +47,12 @@ export abstract class MetricReader { this.onInitialized(); } + /** + * Select the {@link Aggregation} for the given {@link InstrumentType} for this + * reader. + */ + abstract selectAggregation(instrumentType: InstrumentType): Aggregation; + /** * Select the {@link AggregationTemporality} for the given * {@link InstrumentType} for this reader. diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts index 3e188c0293..4d2206cda0 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts @@ -25,25 +25,43 @@ import { AggregationTemporality } from './AggregationTemporality'; import { InstrumentType } from '../InstrumentDescriptor'; import { PushMetricExporter } from './MetricExporter'; import { callWithTimeout, TimeoutError } from '../utils'; +import { Aggregation } from '../view/Aggregation'; +import { AggregationSelector } from './AggregationSelector'; export type PeriodicExportingMetricReaderOptions = { - exporter: PushMetricExporter - exportIntervalMillis?: number, - exportTimeoutMillis?: number + /** + * Aggregation selector based on metric instrument types. If no views are + * configured for a metric instrument, a per-metric-reader aggregation is + * selected with this selector. + */ + aggregationSelector?: AggregationSelector; + /** + * The backing exporter for the metric reader. + */ + exporter: PushMetricExporter; + /** + * An internal milliseconds for the metric reader to initiate metric + * collection. + */ + exportIntervalMillis?: number; + /** + * Milliseconds for the async observable callback to timeout. + */ + exportTimeoutMillis?: number; }; +const DEFAULT_AGGREGATION_SELECTOR: AggregationSelector = Aggregation.Default; + /** * {@link MetricReader} which collects metrics based on a user-configurable time interval, and passes the metrics to * the configured {@link MetricExporter} */ export class PeriodicExportingMetricReader extends MetricReader { private _interval?: ReturnType; - private _exporter: PushMetricExporter; - private readonly _exportInterval: number; - private readonly _exportTimeout: number; + private readonly _aggregationSelector: AggregationSelector; constructor(options: PeriodicExportingMetricReaderOptions) { super(); @@ -65,6 +83,7 @@ export class PeriodicExportingMetricReader extends MetricReader { this._exportInterval = options.exportIntervalMillis ?? 60000; this._exportTimeout = options.exportTimeoutMillis ?? 30000; this._exporter = options.exporter; + this._aggregationSelector = options.aggregationSelector ?? DEFAULT_AGGREGATION_SELECTOR; } private async _runOnce(): Promise { @@ -119,6 +138,13 @@ export class PeriodicExportingMetricReader extends MetricReader { await this._exporter.shutdown(); } + /** + * @inheritdoc + */ + selectAggregation(instrumentType: InstrumentType): Aggregation { + return this._aggregationSelector(instrumentType); + } + /** * @inheritdoc */ diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/index.ts b/experimental/packages/opentelemetry-sdk-metrics/src/index.ts index 3ce97504de..e5e1ab6ed2 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/index.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/index.ts @@ -21,8 +21,12 @@ export { } from './aggregator/types'; export { - AggregationTemporality, + AggregationSelector, AggregationTemporalitySelector, +} from './export/AggregationSelector'; + +export { + AggregationTemporality, } from './export/AggregationTemporality'; export { diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterProviderSharedState.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterProviderSharedState.ts index 87fe540ee5..a63f53d51d 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterProviderSharedState.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterProviderSharedState.ts @@ -16,10 +16,11 @@ import { InstrumentationScope } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; +import { Aggregation, InstrumentType } from '..'; import { instrumentationScopeId } from '../utils'; import { ViewRegistry } from '../view/ViewRegistry'; import { MeterSharedState } from './MeterSharedState'; -import { MetricCollector } from './MetricCollector'; +import { MetricCollector, MetricCollectorHandle } from './MetricCollector'; /** * An internal record for shared meter provider states. @@ -42,4 +43,12 @@ export class MeterProviderSharedState { } return meterSharedState; } + + selectAggregations(instrumentType: InstrumentType) { + const result: [MetricCollectorHandle, Aggregation][] = []; + for (const collector of this.metricCollectors) { + result.push([collector, collector.selectAggregation(instrumentType)]); + } + return result; + } } diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts index ed96aca444..4ddc0b8932 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts @@ -20,7 +20,7 @@ import { MetricCollectOptions } from '../export/MetricProducer'; import { ScopeMetrics } from '../export/MetricData'; import { createInstrumentDescriptorWithView, InstrumentDescriptor } from '../InstrumentDescriptor'; import { Meter } from '../Meter'; -import { isNotNullish } from '../utils'; +import { isNotNullish, Maybe } from '../utils'; import { AsyncMetricStorage } from './AsyncMetricStorage'; import { MeterProviderSharedState } from './MeterProviderSharedState'; import { MetricCollectorHandle } from './MetricCollector'; @@ -28,12 +28,15 @@ import { MetricStorageRegistry } from './MetricStorageRegistry'; import { MultiMetricStorage } from './MultiWritableMetricStorage'; import { ObservableRegistry } from './ObservableRegistry'; import { SyncMetricStorage } from './SyncMetricStorage'; +import { Accumulation, Aggregator } from '../aggregator/types'; +import { AttributesProcessor } from '../view/AttributesProcessor'; +import { MetricStorage } from './MetricStorage'; /** * An internal record for shared meter provider states. */ export class MeterSharedState { - private _metricStorageRegistry = new MetricStorageRegistry(); + metricStorageRegistry = new MetricStorageRegistry(); observableRegistry = new ObservableRegistry(); meter: Meter; @@ -42,15 +45,8 @@ export class MeterSharedState { } registerMetricStorage(descriptor: InstrumentDescriptor) { - const views = this._meterProviderSharedState.viewRegistry.findViews(descriptor, this._instrumentationScope); - const storages = views - .map(view => { - const viewDescriptor = createInstrumentDescriptorWithView(view, descriptor); - const aggregator = view.aggregation.createAggregator(viewDescriptor); - const storage = new SyncMetricStorage(viewDescriptor, aggregator, view.attributesProcessor); - return this._metricStorageRegistry.register(storage); - }) - .filter(isNotNullish); + const storages = this._registerMetricStorage(descriptor, SyncMetricStorage); + if (storages.length === 1) { return storages[0]; } @@ -58,15 +54,8 @@ export class MeterSharedState { } registerAsyncMetricStorage(descriptor: InstrumentDescriptor) { - const views = this._meterProviderSharedState.viewRegistry.findViews(descriptor, this._instrumentationScope); - const storages = views - .map(view => { - const viewDescriptor = createInstrumentDescriptorWithView(view, descriptor); - const aggregator = view.aggregation.createAggregator(viewDescriptor); - const viewStorage = new AsyncMetricStorage(viewDescriptor, aggregator, view.attributesProcessor); - return this._metricStorageRegistry.register(viewStorage); - }) - .filter(isNotNullish); + const storages = this._registerMetricStorage(descriptor, AsyncMetricStorage); + return storages; } @@ -81,7 +70,7 @@ export class MeterSharedState { * 2. Collect metric result for the collector. */ const errors = await this.observableRegistry.observe(collectionTime, options?.timeoutMillis); - const metricDataList = Array.from(this._metricStorageRegistry.getStorages()) + const metricDataList = Array.from(this.metricStorageRegistry.getStorages(collector)) .map(metricStorage => { return metricStorage.collect( collector, @@ -98,9 +87,49 @@ export class MeterSharedState { errors, }; } + + private _registerMetricStorage>(descriptor: InstrumentDescriptor, MetricStorageType: MetricStorageType): R[] { + const views = this._meterProviderSharedState.viewRegistry.findViews(descriptor, this._instrumentationScope); + let storages = views + .map(view => { + const viewDescriptor = createInstrumentDescriptorWithView(view, descriptor); + const compatibleStorage = this.metricStorageRegistry.findOrUpdateCompatibleStorage(viewDescriptor); + if (compatibleStorage != null) { + return compatibleStorage; + } + const aggregator = view.aggregation.createAggregator(viewDescriptor); + const viewStorage = new MetricStorageType(viewDescriptor, aggregator, view.attributesProcessor) as R; + this.metricStorageRegistry.register(viewStorage); + return viewStorage; + }); + + // Fallback to the per-collector aggregations if no view is configured for the instrument. + if (storages.length === 0) { + const perCollectorAggregations = this._meterProviderSharedState.selectAggregations(descriptor.type); + const collectorStorages = perCollectorAggregations.map(([collector, aggregation]) => { + const compatibleStorage = this.metricStorageRegistry.findOrUpdateCompatibleCollectorStorage(collector, descriptor); + if (compatibleStorage != null) { + return compatibleStorage; + } + const aggregator = aggregation.createAggregator(descriptor); + const storage = new MetricStorageType(descriptor, aggregator, AttributesProcessor.Noop()) as R; + this.metricStorageRegistry.registerForCollector(collector, storage); + return storage; + }); + storages = storages.concat(collectorStorages); + } + + return storages; + } } interface ScopeMetricsResult { scopeMetrics: ScopeMetrics; errors: unknown[]; } + +interface MetricStorageConstructor { + new (instrumentDescriptor: InstrumentDescriptor, + aggregator: Aggregator>, + attributesProcessor: AttributesProcessor): MetricStorage; +} diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricCollector.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricCollector.ts index 066106e47d..fbffc2f060 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricCollector.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricCollector.ts @@ -15,7 +15,7 @@ */ import { hrTime } from '@opentelemetry/core'; -import { AggregationTemporalitySelector } from '../export/AggregationTemporality'; +import { AggregationTemporalitySelector } from '../export/AggregationSelector'; import { CollectionResult } from '../export/MetricData'; import { MetricProducer, MetricCollectOptions } from '../export/MetricProducer'; import { MetricReader } from '../export/MetricReader'; @@ -65,6 +65,10 @@ export class MetricCollector implements MetricProducer { selectAggregationTemporality(instrumentType: InstrumentType) { return this._metricReader.selectAggregationTemporality(instrumentType); } + + selectAggregation(instrumentType: InstrumentType) { + return this._metricReader.selectAggregation(instrumentType); + } } /** diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorage.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorage.ts index 8e24da668a..f69a00daa4 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorage.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorage.ts @@ -41,7 +41,7 @@ export abstract class MetricStorage { collectionTime: HrTime, ): Maybe; - getInstrumentDescriptor(): InstrumentDescriptor{ + getInstrumentDescriptor(): Readonly { return this._instrumentDescriptor; } diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorageRegistry.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorageRegistry.ts index 1a930cacb0..c65a1dd7b2 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorageRegistry.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorageRegistry.ts @@ -15,40 +15,93 @@ */ import { MetricStorage } from './MetricStorage'; -import { isDescriptorCompatibleWith } from '../InstrumentDescriptor'; +import { InstrumentDescriptor, isDescriptorCompatibleWith } from '../InstrumentDescriptor'; import * as api from '@opentelemetry/api'; -import { Maybe } from '../utils'; import { getConflictResolutionRecipe, getIncompatibilityDetails } from '../view/RegistrationConflicts'; +import { MetricCollectorHandle } from './MetricCollector'; + +type StorageMap = Map; /** * Internal class for storing {@link MetricStorage} */ export class MetricStorageRegistry { - private readonly _metricStorageRegistry = new Map(); + private readonly _sharedRegistry: StorageMap = new Map(); + private readonly _perCollectorRegistry = new Map(); static create(){ return new MetricStorageRegistry(); } - getStorages(): MetricStorage[] { + getStorages(collector: MetricCollectorHandle): MetricStorage[] { let storages: MetricStorage[] = []; - for (const metricStorages of this._metricStorageRegistry.values()) { + for (const metricStorages of this._sharedRegistry.values()) { storages = storages.concat(metricStorages); } + const perCollectorStorages = this._perCollectorRegistry.get(collector); + if (perCollectorStorages != null) { + for (const metricStorages of perCollectorStorages.values()) { + storages = storages.concat(metricStorages); + } + } + return storages; } - register(storage: T): Maybe { - const expectedDescriptor = storage.getInstrumentDescriptor(); - const existingStorages = this._metricStorageRegistry.get(expectedDescriptor.name); + register(storage: MetricStorage) { + this._registerStorage(storage, this._sharedRegistry); + } + + registerForCollector(collector: MetricCollectorHandle, storage: MetricStorage) { + let storageMap = this._perCollectorRegistry.get(collector); + if (storageMap == null) { + storageMap = new Map(); + this._perCollectorRegistry.set(collector, storageMap); + } + this._registerStorage(storage, storageMap); + } + + findOrUpdateCompatibleStorage(expectedDescriptor: InstrumentDescriptor): T | null { + const storages = this._sharedRegistry.get(expectedDescriptor.name); + if (storages === undefined) { + return null; + } + + // If the descriptor is compatible, the type of their metric storage + // (either SyncMetricStorage or AsyncMetricStorage) must be compatible. + return this._findOrUpdateCompatibleStorage(expectedDescriptor, storages); + } - // Add storage if it does not exist. - if (existingStorages === undefined) { - this._metricStorageRegistry.set(expectedDescriptor.name, [storage]); - return storage; + findOrUpdateCompatibleCollectorStorage(collector: MetricCollectorHandle, expectedDescriptor: InstrumentDescriptor): T | null { + const storageMap = this._perCollectorRegistry.get(collector); + if (storageMap === undefined) { + return null; } + const storages = this._sharedRegistry.get(expectedDescriptor.name); + if (storages === undefined) { + return null; + } + + // If the descriptor is compatible, the type of their metric storage + // (either SyncMetricStorage or AsyncMetricStorage) must be compatible. + return this._findOrUpdateCompatibleStorage(expectedDescriptor, storages); + } + + private _registerStorage(storage: MetricStorage, storageMap: StorageMap) { + const descriptor = storage.getInstrumentDescriptor(); + const storages = storageMap.get(descriptor.name); + + if (storages === undefined) { + storageMap.set(descriptor.name, [storage]); + return; + } + + storages.push(storage); + } + + private _findOrUpdateCompatibleStorage(expectedDescriptor: InstrumentDescriptor, existingStorages: MetricStorage[]): T | null { let compatibleStorage = null; for (const existingStorage of existingStorages) { @@ -84,12 +137,6 @@ export class MetricStorageRegistry { } } - if (compatibleStorage != null) { - return compatibleStorage; - } - - // None of the storages were compatible, add the current one to the list. - existingStorages.push(storage); - return storage; + return compatibleStorage; } } diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/ViewRegistry.ts b/experimental/packages/opentelemetry-sdk-metrics/src/view/ViewRegistry.ts index 1a26387d10..1dcaf7d22f 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/view/ViewRegistry.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/view/ViewRegistry.ts @@ -21,9 +21,6 @@ import { MeterSelector } from './MeterSelector'; import { View } from './View'; export class ViewRegistry { - private static DEFAULT_VIEW = new View({ - instrumentName: '*' - }); private _registeredViews: View[] = []; addView(view: View) { @@ -37,9 +34,6 @@ export class ViewRegistry { this._matchMeter(registeredView.meterSelector, meter); }); - if (views.length === 0) { - return [ViewRegistry.DEFAULT_VIEW]; - } return views; } diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts index 2bb47be3b2..772e268fa4 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts @@ -19,7 +19,6 @@ import * as sinon from 'sinon'; import { InstrumentationScope } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; import { - AggregationTemporality, InstrumentDescriptor, InstrumentType, MeterProvider, @@ -28,7 +27,7 @@ import { DataPointType, Histogram } from '../src'; -import { TestMetricReader } from './export/TestMetricReader'; +import { TestDeltaMetricReader, TestMetricReader } from './export/TestMetricReader'; import { assertMetricData, assertDataPoint, @@ -654,9 +653,9 @@ function setup() { const meter = meterProvider.getMeter(defaultInstrumentationScope.name, defaultInstrumentationScope.version, { schemaUrl: defaultInstrumentationScope.schemaUrl, }); - const deltaReader = new TestMetricReader(() => AggregationTemporality.DELTA); + const deltaReader = new TestDeltaMetricReader(); meterProvider.addMetricReader(deltaReader); - const cumulativeReader = new TestMetricReader(() => AggregationTemporality.CUMULATIVE); + const cumulativeReader = new TestMetricReader(); meterProvider.addMetricReader(cumulativeReader); return { diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts index 1ee88df5d1..27a54d867a 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts @@ -15,10 +15,12 @@ */ import * as assert from 'assert'; +import * as sinon from 'sinon'; import { MeterProvider } from '../../src/MeterProvider'; +import { assertRejects } from '../test-utils'; +import { emptyResourceMetrics, TestMetricProducer } from './TestMetricProducer'; import { TestMetricReader } from './TestMetricReader'; - describe('MetricReader', () => { describe('setMetricProducer', () => { it('The SDK MUST NOT allow a MetricReader instance to be registered on more than one MeterProvider instance', () => { @@ -31,4 +33,51 @@ describe('MetricReader', () => { assert.throws(() => meterProvider2.addMetricReader(reader), /MetricReader can not be bound to a MeterProvider again/); }); }); + + describe('setMetricProducer', () => { + it('should initialize the metric reader', async () => { + const reader = new TestMetricReader(); + + reader.setMetricProducer(new TestMetricProducer()); + const result = await reader.collect(); + + assert.deepStrictEqual(result, { + resourceMetrics: emptyResourceMetrics, + errors: [], + }); + await reader.shutdown(); + }); + }); + + describe('collect', () => { + it('should throw on non-initialized instance', async () => { + const reader = new TestMetricReader(); + + await assertRejects(() => reader.collect(), /MetricReader is not bound to a MetricProducer/); + }); + + it('should return empty on shut-down instance', async () => { + const reader = new TestMetricReader(); + + reader.setMetricProducer(new TestMetricProducer()); + + await reader.shutdown(); + assertRejects(reader.collect(), /MetricReader is shutdown/); + }); + + it('should call MetricProduce.collect with timeout', async () => { + const reader = new TestMetricReader(); + const producer = new TestMetricProducer(); + reader.setMetricProducer(producer); + + const collectStub = sinon.stub(producer, 'collect'); + + await reader.collect({ timeoutMillis: 20 }); + assert(collectStub.calledOnce); + const args = collectStub.args[0]; + assert.deepStrictEqual(args, [{ timeoutMillis: 20 }]); + + await reader.shutdown(); + }); + }); }); diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts index 21890024bf..77489f1e23 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts @@ -17,14 +17,13 @@ import { PeriodicExportingMetricReader } from '../../src/export/PeriodicExportingMetricReader'; import { AggregationTemporality } from '../../src/export/AggregationTemporality'; import { InstrumentType, PushMetricExporter } from '../../src'; -import { CollectionResult, ResourceMetrics } from '../../src/export/MetricData'; +import { ResourceMetrics } from '../../src/export/MetricData'; import * as assert from 'assert'; import * as sinon from 'sinon'; -import { MetricProducer } from '../../src/export/MetricProducer'; import { TimeoutError } from '../../src/utils'; import { ExportResult, ExportResultCode } from '@opentelemetry/core'; import { assertRejects } from '../test-utils'; -import { defaultResource } from '../util'; +import { emptyResourceMetrics, TestMetricProducer } from './TestMetricProducer'; const MAX_32_BIT_INT = 2 ** 31 - 1; @@ -88,17 +87,6 @@ class TestDeltaMetricExporter extends TestMetricExporter { } } -const emptyResourceMetrics = { resource: defaultResource, scopeMetrics: [] }; - -class TestMetricProducer implements MetricProducer { - async collect(): Promise { - return { - resourceMetrics: { resource: defaultResource, scopeMetrics: [] }, - errors: [], - }; - } -} - describe('PeriodicExportingMetricReader', () => { afterEach(() => { sinon.restore(); @@ -364,53 +352,5 @@ describe('PeriodicExportingMetricReader', () => { await assertRejects(() => reader.shutdown(), /Error during forceFlush/); }); - }) - ; - - describe('collect', () => { - it('should throw on non-initialized instance', async () => { - const exporter = new TestMetricExporter(); - const reader = new PeriodicExportingMetricReader({ - exporter: exporter, - exportIntervalMillis: MAX_32_BIT_INT, - exportTimeoutMillis: 80, - }); - - await assertRejects(() => reader.collect(), /MetricReader is not bound to a MetricProducer/); - }); - - it('should return empty on shut-down instance', async () => { - const exporter = new TestMetricExporter(); - const reader = new PeriodicExportingMetricReader({ - exporter: exporter, - exportIntervalMillis: MAX_32_BIT_INT, - exportTimeoutMillis: 80, - }); - - reader.setMetricProducer(new TestMetricProducer()); - - await reader.shutdown(); - assertRejects(reader.collect(), /MetricReader is shutdown/); - }); - - it('should call MetricProduce.collect with timeout', async () => { - const exporter = new TestMetricExporter(); - const reader = new PeriodicExportingMetricReader({ - exporter: exporter, - exportIntervalMillis: MAX_32_BIT_INT, - exportTimeoutMillis: 80, - }); - const producer = new TestMetricProducer(); - reader.setMetricProducer(producer); - - const collectStub = sinon.stub(producer, 'collect'); - - await reader.collect({ timeoutMillis: 20 }); - assert(collectStub.calledOnce); - const args = collectStub.args[0]; - assert.deepStrictEqual(args, [{ timeoutMillis: 20 }]); - - await reader.shutdown(); - }); }); }); diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricProducer.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricProducer.ts new file mode 100644 index 0000000000..cb1247ed00 --- /dev/null +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricProducer.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 { CollectionResult } from '../../src/export/MetricData'; +import { MetricProducer } from '../../src/export/MetricProducer'; +import { defaultResource } from '../util'; + +export const emptyResourceMetrics = { resource: defaultResource, scopeMetrics: [] }; + +export class TestMetricProducer implements MetricProducer { + async collect(): Promise { + return { + resourceMetrics: { resource: defaultResource, scopeMetrics: [] }, + errors: [], + }; + } +} diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts index 4b02562c94..e708e1d2e0 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts @@ -15,6 +15,8 @@ */ import { + Aggregation, + AggregationSelector, AggregationTemporality, AggregationTemporalitySelector, InstrumentType, @@ -22,15 +24,22 @@ import { } from '../../src'; import { MetricCollector } from '../../src/state/MetricCollector'; +export interface TestMetricReaderOptions { + aggregationTemporalitySelector?: AggregationTemporalitySelector; + aggregationSelector?: AggregationSelector; +} + /** * A test metric reader that implements no-op onForceFlush() and onShutdown() handlers. */ export class TestMetricReader extends MetricReader { private _aggregationTemporalitySelector: AggregationTemporalitySelector; + private _aggregationSelector: AggregationSelector; - constructor(aggregationTemporalitySelector?: AggregationTemporalitySelector) { + constructor(options?: TestMetricReaderOptions) { super(); - this._aggregationTemporalitySelector = aggregationTemporalitySelector ?? (() => AggregationTemporality.CUMULATIVE); + this._aggregationTemporalitySelector = options?.aggregationTemporalitySelector ?? (() => AggregationTemporality.CUMULATIVE); + this._aggregationSelector = options?.aggregationSelector ?? Aggregation.Default; } protected onForceFlush(): Promise { @@ -45,7 +54,20 @@ export class TestMetricReader extends MetricReader { return this._aggregationTemporalitySelector(instrumentType); } + selectAggregation(instrumentType: InstrumentType) { + return this._aggregationSelector(instrumentType); + } + getMetricCollector(): MetricCollector { return this['_metricProducer'] as MetricCollector; } } + +export class TestDeltaMetricReader extends TestMetricReader { + constructor(options: TestMetricReaderOptions = {}) { + super({ + ...options, + aggregationTemporalitySelector: () => AggregationTemporality.DELTA, + }); + } +} diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts index 0a4b504b9f..dc7651f83a 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts @@ -17,14 +17,16 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import { - AggregationTemporality, Meter, MeterProvider, DataPointType, - View + View, + Aggregation, + MetricReader, + InstrumentType } from '../../src'; import { assertMetricData, defaultInstrumentationScope, defaultResource, sleep } from '../util'; -import { TestMetricReader } from '../export/TestMetricReader'; +import { TestDeltaMetricReader, TestMetricReader } from '../export/TestMetricReader'; import { MeterSharedState } from '../../src/state/MeterSharedState'; import { CollectionResult } from '../../src/export/MetricData'; @@ -33,15 +35,122 @@ describe('MeterSharedState', () => { sinon.restore(); }); + describe('registerMetricStorage', () => { + function setupMeter(views?: View[], readers?: MetricReader[]) { + const meterProvider = new MeterProvider({ + resource: defaultResource, + views, + }); + readers?.forEach(reader => meterProvider.addMetricReader(reader)); + + const meter = meterProvider.getMeter('test-meter'); + + return { + meter, + meterSharedState: meterProvider['_sharedState'].getMeterSharedState({ name: 'test-meter' }), + collectors: Array.from(meterProvider['_sharedState'].metricCollectors), + }; + } + + it('should register metric storages with views', () => { + const reader = new TestMetricReader({ + aggregationSelector: () => { + throw new Error('should not be called'); + }, + }); + const { meter, meterSharedState, collectors } = setupMeter( + [ new View({ instrumentName: 'test-counter' }) ], + [reader], + ); + + meter.createCounter('test-counter'); + const metricStorages = meterSharedState.metricStorageRegistry.getStorages(collectors[0]); + + assert.strictEqual(metricStorages.length, 1); + assert.strictEqual(metricStorages[0].getInstrumentDescriptor().name, 'test-counter'); + }); + + it('should register metric storages with views', () => { + const reader = new TestMetricReader({ + aggregationSelector: () => { + throw new Error('should not be called'); + }, + }); + const { meter, meterSharedState, collectors } = setupMeter( + [ new View({ instrumentName: 'test-counter' }) ], + [reader], + ); + + meter.createCounter('test-counter'); + const metricStorages = meterSharedState.metricStorageRegistry.getStorages(collectors[0]); + + assert.strictEqual(metricStorages.length, 1); + assert.strictEqual(metricStorages[0].getInstrumentDescriptor().name, 'test-counter'); + }); + + it('should register metric storages with the collector', () => { + const reader = new TestMetricReader({ + aggregationSelector: (instrumentType: InstrumentType) => { + return Aggregation.Drop(); + }, + }); + const readerAggregationSelectorSpy = sinon.spy(reader, 'selectAggregation'); + + const { meter, meterSharedState, collectors } = setupMeter( + [], /** no views registered */ + [reader], + ); + + meter.createCounter('test-counter'); + const metricStorages = meterSharedState.metricStorageRegistry.getStorages(collectors[0]); + + // Should select aggregation with the metric reader. + assert.strictEqual(readerAggregationSelectorSpy.callCount, 1); + assert.strictEqual(metricStorages.length, 1); + assert.strictEqual(metricStorages[0].getInstrumentDescriptor().name, 'test-counter'); + }); + + it('should register metric storages with collectors', () => { + const reader = new TestMetricReader({ + aggregationSelector: (instrumentType: InstrumentType) => { + return Aggregation.Drop(); + }, + }); + const reader2 = new TestMetricReader({ + aggregationSelector: (instrumentType: InstrumentType) => { + return Aggregation.LastValue(); + }, + }); + + const { meter, meterSharedState, collectors } = setupMeter( + [], /** no views registered */ + [reader, reader2], + ); + + meter.createCounter('test-counter'); + const metricStorages = meterSharedState.metricStorageRegistry.getStorages(collectors[0]); + const metricStorages2 = meterSharedState.metricStorageRegistry.getStorages(collectors[1]); + + // Should select aggregation with the metric reader. + assert.strictEqual(metricStorages.length, 1); + assert.strictEqual(metricStorages[0].getInstrumentDescriptor().name, 'test-counter'); + + assert.strictEqual(metricStorages2.length, 1); + assert.strictEqual(metricStorages2[0].getInstrumentDescriptor().name, 'test-counter'); + + assert.notStrictEqual(metricStorages[0], metricStorages2[0], 'should create a distinct metric storage for each metric reader'); + }); + }); + describe('collect', () => { function setupInstruments(views?: View[]) { const meterProvider = new MeterProvider({ resource: defaultResource, views: views }); - const cumulativeReader = new TestMetricReader(() => AggregationTemporality.CUMULATIVE); + const cumulativeReader = new TestMetricReader(); meterProvider.addMetricReader(cumulativeReader); const cumulativeCollector = cumulativeReader.getMetricCollector(); - const deltaReader = new TestMetricReader(() => AggregationTemporality.DELTA); + const deltaReader = new TestDeltaMetricReader(); meterProvider.addMetricReader(deltaReader); const deltaCollector = deltaReader.getMetricCollector(); diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts index ad65f1c027..6f316a11ed 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts @@ -19,7 +19,6 @@ import * as sinon from 'sinon'; import { MeterProvider } from '../../src'; import { TimeoutError } from '../../src/utils'; import { DataPointType } from '../../src/export/MetricData'; -import { PushMetricExporter } from '../../src/export/MetricExporter'; import { MeterProviderSharedState } from '../../src/state/MeterProviderSharedState'; import { MetricCollector } from '../../src/state/MetricCollector'; import { @@ -30,8 +29,7 @@ import { ObservableCallbackDelegate, BatchObservableCallbackDelegate, } from '../util'; -import { TestMetricReader } from '../export/TestMetricReader'; -import { TestDeltaMetricExporter, TestMetricExporter } from '../export/TestMetricExporter'; +import { TestDeltaMetricReader, TestMetricReader } from '../export/TestMetricReader'; describe('MetricCollector', () => { afterEach(() => { @@ -41,20 +39,18 @@ describe('MetricCollector', () => { describe('constructor', () => { it('should construct MetricCollector without exceptions', () => { const meterProviderSharedState = new MeterProviderSharedState(defaultResource); - const exporters = [ new TestMetricExporter(), new TestDeltaMetricExporter() ]; - for (const exporter of exporters) { - const reader = new TestMetricReader(exporter.selectAggregationTemporality); + const readers = [ new TestMetricReader(), new TestDeltaMetricReader() ]; + for (const reader of readers) { assert.doesNotThrow(() => new MetricCollector(meterProviderSharedState, reader)); } }); }); describe('collect', () => { - - function setupInstruments(exporter: PushMetricExporter) { + function setupInstruments() { const meterProvider = new MeterProvider({ resource: defaultResource }); - const reader = new TestMetricReader(exporter.selectAggregationTemporality); + const reader = new TestMetricReader(); meterProvider.addMetricReader(reader); const metricCollector = reader.getMetricCollector(); @@ -67,8 +63,7 @@ describe('MetricCollector', () => { it('should collect sync metrics', async () => { /** preparing test instrumentations */ - const exporter = new TestMetricExporter(); - const { metricCollector, meter } = setupInstruments(exporter); + const { metricCollector, meter } = setupInstruments(); /** creating metric events */ const counter = meter.createCounter('counter1'); @@ -105,8 +100,7 @@ describe('MetricCollector', () => { it('should collect async metrics', async () => { /** preparing test instrumentations */ - const exporter = new TestMetricExporter(); - const { metricCollector, meter } = setupInstruments(exporter); + const { metricCollector, meter } = setupInstruments(); /** creating metric events */ /** observable */ @@ -164,8 +158,7 @@ describe('MetricCollector', () => { it('should collect observer metrics with timeout', async () => { sinon.useFakeTimers(); /** preparing test instrumentations */ - const exporter = new TestMetricExporter(); - const { metricCollector, meter } = setupInstruments(exporter); + const { metricCollector, meter } = setupInstruments(); /** creating metric events */ @@ -247,8 +240,7 @@ describe('MetricCollector', () => { it('should collect with throwing observable callbacks', async () => { /** preparing test instrumentations */ - const exporter = new TestMetricExporter(); - const { metricCollector, meter } = setupInstruments(exporter); + const { metricCollector, meter } = setupInstruments(); /** creating metric events */ const counter = meter.createCounter('counter1'); @@ -284,8 +276,7 @@ describe('MetricCollector', () => { it('should collect batch observer metrics with timeout', async () => { sinon.useFakeTimers(); /** preparing test instrumentations */ - const exporter = new TestMetricExporter(); - const { metricCollector, meter } = setupInstruments(exporter); + const { metricCollector, meter } = setupInstruments(); /** creating metric events */ @@ -367,8 +358,7 @@ describe('MetricCollector', () => { it('should collect with throwing batch observable callbacks', async () => { /** preparing test instrumentations */ - const exporter = new TestMetricExporter(); - const { metricCollector, meter } = setupInstruments(exporter); + const { metricCollector, meter } = setupInstruments(); /** creating metric events */ const counter = meter.createCounter('counter1'); diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts index e3defd2c92..fa8424b992 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts @@ -31,7 +31,8 @@ import { } from '../../src/view/RegistrationConflicts'; class TestMetricStorage extends MetricStorage { - collect(collector: MetricCollectorHandle, + collect( + collector: MetricCollectorHandle, collectors: MetricCollectorHandle[], collectionTime: HrTime, ): Maybe { @@ -50,8 +51,19 @@ describe('MetricStorageRegistry', () => { sinon.restore(); }); + const collectorHandle: MetricCollectorHandle = { + selectAggregationTemporality: () => { + throw new Error('should not be invoked'); + }, + }; + const collectorHandle2: MetricCollectorHandle = { + selectAggregationTemporality: () => { + throw new Error('should not be invoked'); + }, + }; + describe('register', () => { - it('should register MetricStorage if it does not exist', () => { + it('should register MetricStorage', () => { const registry = new MetricStorageRegistry(); const storage = new TestMetricStorage({ name: 'instrument', @@ -61,34 +73,65 @@ describe('MetricStorageRegistry', () => { valueType: ValueType.DOUBLE }); - const registeredStorage = registry.register(storage); - const registeredStorages = registry.getStorages(); + registry.register(storage); + const registeredStorages = registry.getStorages(collectorHandle); - // returned the same storage - assert.strictEqual(registeredStorage, storage); - // registered the actual storage + // registered the storage. assert.deepStrictEqual([storage], registeredStorages); - // no warning logs written - assert.strictEqual(spyLoggerWarn.args.length, 0); }); + }); - function testConflictingRegistration(existingDescriptor: InstrumentDescriptor, + describe('registerForCollector', () => { + it('should register MetricStorage for each collector', () => { + const registry = new MetricStorageRegistry(); + const storage = new TestMetricStorage({ + name: 'instrument', + type: InstrumentType.COUNTER, + description: 'description', + unit: '1', + valueType: ValueType.DOUBLE + }); + const storage2 = new TestMetricStorage({ + name: 'instrument2', + type: InstrumentType.COUNTER, + description: 'description', + unit: '1', + valueType: ValueType.DOUBLE + }); + + registry.registerForCollector(collectorHandle, storage); + registry.registerForCollector(collectorHandle2, storage); + registry.registerForCollector(collectorHandle2, storage2); + + assert.deepStrictEqual(registry.getStorages(collectorHandle), [storage]); + assert.deepStrictEqual(registry.getStorages(collectorHandle2), [storage, storage2]); + }); + }); + + describe('findOrUpdateCompatibleStorage', () => { + function testConflictingRegistration( + existingDescriptor: InstrumentDescriptor, otherDescriptor: InstrumentDescriptor, - expectedLog: string) { + expectedLog: string + ) { const registry = new MetricStorageRegistry(); const storage = new TestMetricStorage(existingDescriptor); const otherStorage = new TestMetricStorage(otherDescriptor); - assert.strictEqual(registry.register(storage), storage); - assert.strictEqual(registry.register(otherStorage), otherStorage); - const registeredStorages = registry.getStorages(); + assert.strictEqual(registry.findOrUpdateCompatibleStorage(existingDescriptor), null); + registry.register(storage); + assertLogNotCalled(); - // registered both storages - assert.deepStrictEqual([storage, otherStorage], registeredStorages); + assert.strictEqual(registry.findOrUpdateCompatibleStorage(otherDescriptor), null); // warned assertLogCalledOnce(); assertFirstLogContains(expectedLog); + registry.register(otherStorage); + + // registered both storages + const registeredStorages = registry.getStorages(collectorHandle); + assert.deepStrictEqual([storage, otherStorage], registeredStorages); } it('warn when instrument with same name and different type is already registered', () => { @@ -179,17 +222,14 @@ describe('MetricStorageRegistry', () => { const storage = new TestMetricStorage(existingDescriptor); const otherStorage = new TestMetricStorage(otherDescriptor); - // returns the first registered storage. - assert.strictEqual(registry.register(storage), storage); - // returns the original storage - assert.strictEqual(registry.register(otherStorage), storage); + // register the first storage. + assert.strictEqual(registry.findOrUpdateCompatibleStorage(existingDescriptor), null); + registry.register(storage); + // register the second storage. + assert.strictEqual(registry.findOrUpdateCompatibleStorage(otherDescriptor), storage); // original storage now has the updated (longer) description. assert.strictEqual(otherStorage.getInstrumentDescriptor().description, otherDescriptor.description); - const registeredStorages = registry.getStorages(); - - // only the original storage has been added - assert.deepStrictEqual([storage], registeredStorages); // log called exactly once assertLogCalledOnce(); // added resolution recipe to the log @@ -207,14 +247,9 @@ describe('MetricStorageRegistry', () => { }; const storage = new TestMetricStorage(descriptor); - const otherStorage = new TestMetricStorage(descriptor); - assert.strictEqual(registry.register(storage), storage); - assert.strictEqual(registry.register(otherStorage), storage); - const registeredStorages = registry.getStorages(); - - // registered the actual storage, but not more than that. - assert.deepStrictEqual([storage], registeredStorages); + registry.register(storage); + assert.strictEqual(registry.findOrUpdateCompatibleStorage(descriptor), storage); }); it('should return the existing instrument if a compatible sync instrument is already registered', () => { @@ -228,18 +263,15 @@ describe('MetricStorageRegistry', () => { }; const storage = new TestMetricStorage(descriptor); - const otherStorage = new TestMetricStorage(descriptor); registry.register(storage); - const previouslyRegisteredStorage = registry.register(otherStorage); - const registeredStorages = registry.getStorages(); - - // returned undefined - assert.strictEqual(previouslyRegisteredStorage, storage); - // registered the actual storage, but not more than that. - assert.deepStrictEqual([storage], registeredStorages); + assert.strictEqual(registry.findOrUpdateCompatibleStorage(descriptor), storage); }); + function assertLogNotCalled() { + assert.strictEqual(spyLoggerWarn.args.length, 0); + } + function assertLogCalledOnce() { assert.strictEqual(spyLoggerWarn.args.length, 1); } @@ -248,4 +280,63 @@ describe('MetricStorageRegistry', () => { assert.ok(spyLoggerWarn.args[0].includes(expectedString), 'Logs did not include: ' + expectedString); } }); + + describe('findOrUpdateCompatibleCollectorStorage', () => { + it('register conflicting metric storages for collector', () => { + const existingDescriptor = { + name: 'instrument', + type: InstrumentType.COUNTER, + description: 'description', + unit: '1', + valueType: ValueType.DOUBLE + }; + + const otherDescriptor = { + name: 'instrument', + type: InstrumentType.UP_DOWN_COUNTER, + description: 'description', + unit: '1', + valueType: ValueType.DOUBLE + }; + + const registry = new MetricStorageRegistry(); + + const storage = new TestMetricStorage(existingDescriptor); + const otherStorage = new TestMetricStorage(otherDescriptor); + + assert.strictEqual(registry.findOrUpdateCompatibleCollectorStorage(collectorHandle, existingDescriptor), null); + registry.registerForCollector(collectorHandle, storage); + + // Should not return an existing metric storage. + assert.strictEqual(registry.findOrUpdateCompatibleCollectorStorage(collectorHandle, otherDescriptor), null); + registry.registerForCollector(collectorHandle, otherStorage); + + // registered both storages + const registeredStorages = registry.getStorages(collectorHandle); + assert.deepStrictEqual([storage, otherStorage], registeredStorages); + }); + + it('register the same metric storage for each collector', () => { + const descriptor = { + name: 'instrument', + type: InstrumentType.COUNTER, + description: 'description', + unit: '1', + valueType: ValueType.DOUBLE + }; + const registry = new MetricStorageRegistry(); + + const storage = new TestMetricStorage(descriptor); + + assert.strictEqual(registry.findOrUpdateCompatibleCollectorStorage(collectorHandle, descriptor), null); + registry.registerForCollector(collectorHandle, storage); + + assert.strictEqual(registry.findOrUpdateCompatibleCollectorStorage(collectorHandle2, descriptor), null); + registry.registerForCollector(collectorHandle2, storage); + + // registered the storage for each collector + assert.deepStrictEqual(registry.getStorages(collectorHandle), [storage]); + assert.deepStrictEqual(registry.getStorages(collectorHandle2), [storage]); + }); + }); }); diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/view/ViewRegistry.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/view/ViewRegistry.test.ts index a56d7b65e0..68f9f27072 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/view/ViewRegistry.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/view/ViewRegistry.test.ts @@ -23,13 +23,6 @@ import { View } from '../../src'; describe('ViewRegistry', () => { describe('findViews', () => { - it('should return default view if no view registered', () => { - const registry = new ViewRegistry(); - const views = registry.findViews(defaultInstrumentDescriptor, defaultInstrumentationScope); - assert.strictEqual(views.length, 1); - assert.strictEqual(views[0], ViewRegistry['DEFAULT_VIEW']); - }); - describe('InstrumentSelector', () => { it('should match view with instrument name', () => { const registry = new ViewRegistry(); From a669f9c5e2c6ae6ab61e27a3e0d5e955f280ce9b Mon Sep 17 00:00:00 2001 From: avzis <107620508+avzis@users.noreply.github.com> Date: Thu, 1 Sep 2022 11:56:43 +0300 Subject: [PATCH 04/77] chore(deps): update prometheus example dependencies to 0.32 (#3216) * chore(deps): update prometheus example dependencies to 0.32 * chore(deps): update CHANGELOG --- experimental/CHANGELOG.md | 1 + experimental/examples/prometheus/package.json | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 8d5b302561..2d5ea268fa 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -37,6 +37,7 @@ All notable changes to experimental packages in this project will be documented * feature(prometheus-serialiser): export the unit block when unit is set in metric descriptor [#3066](https://github.com/open-telemetry/opentelemetry-js/pull/3041) @weyert * feat: support latest `@opentelemetry/api` [#3177](https://github.com/open-telemetry/opentelemetry-js/pull/3177) @dyladan * feat(sdk-metrics-base): add per metric-reader aggregation support [#3153](https://github.com/open-telemetry/opentelemetry-js/pull/3153) @legendecas +* chore(deps): update prometheus example dependencies to 0.32 [#3126](https://github.com/open-telemetry/opentelemetry-js/pull/3216) @avzis ### :bug: (Bug Fix) diff --git a/experimental/examples/prometheus/package.json b/experimental/examples/prometheus/package.json index a3c5dbca51..9816279e53 100644 --- a/experimental/examples/prometheus/package.json +++ b/experimental/examples/prometheus/package.json @@ -1,7 +1,7 @@ { "name": "prometheus-example", - "version": "0.28.0", - "description": "Example of using @opentelemetry/sdk-metrics-base and @opentelemetry/exporter-prometheus", + "version": "0.32.0", + "description": "Example of using @opentelemetry/sdk-metrics and @opentelemetry/exporter-prometheus", "main": "index.js", "scripts": { "start": "node index.js" @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.0.2", - "@opentelemetry/exporter-prometheus": "0.28.0", - "@opentelemetry/sdk-metrics-base": "0.28.0" + "@opentelemetry/exporter-prometheus": "0.32.0", + "@opentelemetry/sdk-metrics": "0.32.0" } } From 4e123b5372c39b4bf8605f2a041d7eb1ec2b2aa0 Mon Sep 17 00:00:00 2001 From: Osher Vaknin <81672378+osherv@users.noreply.github.com> Date: Fri, 2 Sep 2022 05:46:34 +0300 Subject: [PATCH 05/77] feat(node-sdk): added resourceDetectors option to NodeSDK #3210 (#3212) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(node-sdk): added resourceDetectors option to NodeSDK #3210 * feat(node-sdk): fixed markdown lint #3210 * feat(node-sdk): fixed types lint #3210 * feat(node-sdk): added resourceDetectors option to NodeSDK #3210 * feat(node-sdk): added resourceDetectors option to NodeSDK #3210 * feat(node-sdk): updated proto subproject commit NodeSDK #3210 * feat(node-sdk): returned protobuf repos to v0.18.0 #3210 * Update experimental/packages/opentelemetry-sdk-node/README.md Co-authored-by: Daniel Dyla * feat(node-sdk): added breaking changelog #3210 * feat(node-sdk): added breaking changelog #3210 * Update experimental/CHANGELOG.md Co-authored-by: Gerhard Stöbich Co-authored-by: Daniel Dyla Co-authored-by: Gerhard Stöbich --- experimental/CHANGELOG.md | 6 ++++ .../packages/opentelemetry-sdk-node/README.md | 7 +++- .../opentelemetry-sdk-node/src/sdk.ts | 10 +++--- .../opentelemetry-sdk-node/src/types.ts | 3 +- .../opentelemetry-sdk-node/test/sdk.test.ts | 36 ++++++++++++++++--- 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 2d5ea268fa..98efacaa7e 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -6,6 +6,10 @@ All notable changes to experimental packages in this project will be documented ### :boom: Breaking Change +* Add `resourceDetectors` option to `NodeSDK` [#3210](https://github.com/open-telemetry/opentelemetry-js/issues/3210) + * `NodeSDK.detectResources()` function is no longer able to receive config as a parameter. + Instead, the detectors are passed to the constructor. + * chore(metrics-sdk): clean up exports [#3197](https://github.com/open-telemetry/opentelemetry-js/pull/3197) @pichlermarc * removes export for: * `AccumulationRecord` @@ -18,6 +22,8 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) +* Add `resourceDetectors` option to `NodeSDK` [#3210](https://github.com/open-telemetry/opentelemetry-js/issues/3210) + ### :bug: (Bug Fix) ### :books: (Refine Doc) diff --git a/experimental/packages/opentelemetry-sdk-node/README.md b/experimental/packages/opentelemetry-sdk-node/README.md index 5b288ba1f3..e0ed90099c 100644 --- a/experimental/packages/opentelemetry-sdk-node/README.md +++ b/experimental/packages/opentelemetry-sdk-node/README.md @@ -114,9 +114,14 @@ or configure each instrumentation individually. Configure a resource. Resources may also be detected by using the `autoDetectResources` method of the SDK. +### resourceDetectors + +Configure resource detectors. By default, the resource detectors are [envDetector, processDetector]. +NOTE: In order to enable the detection, the parameter `autoDetectResources` has to be `true`. + ### sampler -Configure a custom sampler. By default all traces will be sampled. +Configure a custom sampler. By default, all traces will be sampled. ### spanProcessor diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts index 2c6005806d..11870ebf28 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts @@ -21,6 +21,7 @@ import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { + Detector, detectResources, envDetector, processDetector, @@ -62,6 +63,7 @@ export class NodeSDK { private _instrumentations: InstrumentationOption[]; private _resource: Resource; + private _resourceDetectors: Detector[]; private _autoDetectResources: boolean; @@ -74,6 +76,7 @@ export class NodeSDK { */ public constructor(configuration: Partial = {}) { this._resource = configuration.resource ?? new Resource({}); + this._resourceDetectors = configuration.resourceDetectors ?? [envDetector, processDetector]; this._serviceName = configuration.serviceName; @@ -166,12 +169,9 @@ export class NodeSDK { } /** Detect resource attributes */ - public async detectResources( - config?: ResourceDetectionConfig - ): Promise { + public async detectResources(): Promise { const internalConfig: ResourceDetectionConfig = { - detectors: [envDetector, processDetector], - ...config, + detectors: this._resourceDetectors, }; this.addResource(await detectResources(internalConfig)); diff --git a/experimental/packages/opentelemetry-sdk-node/src/types.ts b/experimental/packages/opentelemetry-sdk-node/src/types.ts index 425b375bac..722201f03f 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/types.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/types.ts @@ -17,7 +17,7 @@ import type { ContextManager, SpanAttributes } from '@opentelemetry/api'; import { TextMapPropagator } from '@opentelemetry/api'; import { InstrumentationOption } from '@opentelemetry/instrumentation'; -import { Resource } from '@opentelemetry/resources'; +import { Detector, Resource } from '@opentelemetry/resources'; import { MetricReader, View } from '@opentelemetry/sdk-metrics'; import { Sampler, @@ -35,6 +35,7 @@ export interface NodeSDKConfiguration { views: View[] instrumentations: InstrumentationOption[]; resource: Resource; + resourceDetectors: Detector[]; sampler: Sampler; serviceName?: string; spanProcessor: SpanProcessor; diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index edad60c5ec..ebc07dc2bc 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -41,7 +41,7 @@ import * as assert from 'assert'; import * as semver from 'semver'; import * as Sinon from 'sinon'; import { NodeSDK } from '../src'; -import { envDetector, processDetector } from '@opentelemetry/resources'; +import {envDetector, processDetector, Resource} from '@opentelemetry/resources'; const DefaultContextManager = semver.gte(process.version, '14.8.0') @@ -284,19 +284,47 @@ describe('Node SDK', () => { delete process.env.OTEL_RESOURCE_ATTRIBUTES; }); - describe('with a buggy detector', () => { + describe('with a custom resource', () => { it('returns a merged resource', async () => { const sdk = new NodeSDK({ autoDetectResources: true, + resourceDetectors: [processDetector, { + async detect(): Promise { + return new Resource({'customAttr': 'someValue'}); + } + }, + envDetector] + }); + await sdk.detectResources(); + const resource = sdk['_resource']; + + assert.strictEqual( + resource.attributes['customAttr'], + 'someValue' + ); + + assertServiceResource(resource, { + instanceId: '627cc493', + name: 'my-service', + namespace: 'default', + version: '0.0.1', }); - await sdk.detectResources({ - detectors: [processDetector, { + }); + }); + + describe('with a buggy detector', () => { + it('returns a merged resource', async () => { + const sdk = new NodeSDK({ + autoDetectResources: true, + resourceDetectors: [processDetector, { detect() { throw new Error('Buggy detector'); } }, envDetector] }); + + await sdk.detectResources(); const resource = sdk['_resource']; assertServiceResource(resource, { From d3adc22c4715d77e3a6913d0e14950fd68d470f9 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Mon, 5 Sep 2022 10:05:43 +0200 Subject: [PATCH 06/77] chore(api-metrics): clean up exports (#3198) * chore(api-metrics): clean up exports * fix(changelog): add changelog entry. * fix(changelog): add changelog entry. * fix: formatting. * fix(changelog): move entry to unreleased. * fix(instrumentation): remove references to NOOP_METER_PROVIDER * fix(instrumentation): also stub setMeterProvider. * sort changelog export list * feat(api-metrics): add createNoopMeter function. * feat(api-metrics): document createNoopMeter. * fix(whitespace): reformat NoopMeter.ts * chore: add test for createNoopMeter() Co-authored-by: Daniel Dyla --- experimental/CHANGELOG.md | 19 +++++++++ .../src/NoopMeter.ts | 10 +++++ .../opentelemetry-api-metrics/src/index.ts | 40 ++++++++++++++++--- .../test/api/api.test.ts | 5 ++- .../test/api/global.test.ts | 2 +- .../noop-implementations/noop-meter.test.ts | 11 ++++- .../test/common/autoLoader.test.ts | 26 ++++++++---- .../src/MeterProvider.ts | 2 +- .../test/MeterProvider.test.ts | 4 +- .../opentelemetry-sdk-node/test/sdk.test.ts | 24 ++++++++--- 10 files changed, 117 insertions(+), 26 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 98efacaa7e..a489427839 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -19,6 +19,25 @@ All notable changes to experimental packages in this project will be documented * `createInstrumentDescriptor` * `createInstrumentDescriptorWithView` * `isDescriptorCompatibleWith` +* chore(api-metrics): clean up exports [#3198](https://github.com/open-telemetry/opentelemetry-js/pull/3198) @pichlermarc + * removes export for: + * `NOOP_COUNTER_METRIC` + * `NOOP_HISTOGRAM_METRIC` + * `NOOP_METER_PROVIDER` + * `NOOP_OBSERVABLE_COUNTER_METRIC` + * `NOOP_OBSERVABLE_GAUGE_METRIC` + * `NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC` + * `NOOP_UP_DOWN_COUNTER_METRIC` + * `NoopCounterMetric` + * `NoopHistogramMetric` + * `NoopMeter` + * `NoopMeterProvider` + * `NoopMetric` + * `NoopObservableCounterMetric` + * `NoopObservableGaugeMetric` + * `NoopObservableMetric` + * `NoopObservableUpDownCounterMetric` + * `NoopUpDownCounterMetric` ### :rocket: (Enhancement) diff --git a/experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts b/experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts index 317431096f..69c2513449 100644 --- a/experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts +++ b/experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts @@ -114,11 +114,14 @@ export class NoopHistogramMetric extends NoopMetric implements Histogram { export class NoopObservableMetric { addCallback(_callback: ObservableCallback) {} + removeCallback(_callback: ObservableCallback) {} } export class NoopObservableCounterMetric extends NoopObservableMetric implements ObservableCounter {} + export class NoopObservableGaugeMetric extends NoopObservableMetric implements ObservableGauge {} + export class NoopObservableUpDownCounterMetric extends NoopObservableMetric implements ObservableUpDownCounter {} export const NOOP_METER = new NoopMeter(); @@ -132,3 +135,10 @@ export const NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric(); export const NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableCounterMetric(); export const NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableGaugeMetric(); export const NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableUpDownCounterMetric(); + +/** + * Create a no-op Meter + */ +export function createNoopMeter(): Meter { + return NOOP_METER; +} diff --git a/experimental/packages/opentelemetry-api-metrics/src/index.ts b/experimental/packages/opentelemetry-api-metrics/src/index.ts index e306e6c1ab..5a59fe2d96 100644 --- a/experimental/packages/opentelemetry-api-metrics/src/index.ts +++ b/experimental/packages/opentelemetry-api-metrics/src/index.ts @@ -14,13 +14,41 @@ * limitations under the License. */ -export * from './NoopMeter'; -export * from './NoopMeterProvider'; -export * from './types/Meter'; -export * from './types/MeterProvider'; -export * from './types/Metric'; -export * from './types/ObservableResult'; +export { + createNoopMeter, +} from './NoopMeter'; + +export { + MeterOptions, + Meter, +} from './types/Meter'; + +export { + MeterProvider, +} from './types/MeterProvider'; + +export { + ValueType, + Counter, + Histogram, + MetricOptions, + Observable, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + UpDownCounter, + BatchObservableCallback, + MetricAttributes, + MetricAttributeValue, + ObservableCallback, +} from './types/Metric'; + +export { + BatchObservableResult, + ObservableResult, +} from './types/ObservableResult'; import { MetricsAPI } from './api/metrics'; + /** Entrypoint for metrics API */ export const metrics = MetricsAPI.getInstance(); diff --git a/experimental/packages/opentelemetry-api-metrics/test/api/api.test.ts b/experimental/packages/opentelemetry-api-metrics/test/api/api.test.ts index e9a837230e..66278d6bc7 100644 --- a/experimental/packages/opentelemetry-api-metrics/test/api/api.test.ts +++ b/experimental/packages/opentelemetry-api-metrics/test/api/api.test.ts @@ -15,7 +15,10 @@ */ import * as assert from 'assert'; -import { metrics, NoopMeter, NoopMeterProvider } from '../../src'; +import { metrics } from '../../src'; +import { NoopMeter } from '../../src/NoopMeter'; +import { NoopMeterProvider } from '../../src/NoopMeterProvider'; + describe('API', () => { it('should expose a meter provider via getMeterProvider', () => { diff --git a/experimental/packages/opentelemetry-api-metrics/test/api/global.test.ts b/experimental/packages/opentelemetry-api-metrics/test/api/global.test.ts index 485c68c41a..c48949a3e5 100644 --- a/experimental/packages/opentelemetry-api-metrics/test/api/global.test.ts +++ b/experimental/packages/opentelemetry-api-metrics/test/api/global.test.ts @@ -16,7 +16,7 @@ import * as assert from 'assert'; import { _global, GLOBAL_METRICS_API_KEY } from '../../src/api/global-utils'; -import { NoopMeterProvider } from '../../src'; +import { NoopMeterProvider } from '../../src/NoopMeterProvider'; const api1 = require('../../src') as typeof import('../../src'); diff --git a/experimental/packages/opentelemetry-api-metrics/test/noop-implementations/noop-meter.test.ts b/experimental/packages/opentelemetry-api-metrics/test/noop-implementations/noop-meter.test.ts index 82f0e8b6be..07395a925b 100644 --- a/experimental/packages/opentelemetry-api-metrics/test/noop-implementations/noop-meter.test.ts +++ b/experimental/packages/opentelemetry-api-metrics/test/noop-implementations/noop-meter.test.ts @@ -17,14 +17,15 @@ import * as assert from 'assert'; import { NoopMeter, - NoopMeterProvider, NOOP_COUNTER_METRIC, NOOP_HISTOGRAM_METRIC, NOOP_OBSERVABLE_COUNTER_METRIC, NOOP_OBSERVABLE_GAUGE_METRIC, NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC, NOOP_UP_DOWN_COUNTER_METRIC, -} from '../../src'; + createNoopMeter, +} from '../../src/NoopMeter'; +import { NoopMeterProvider } from '../../src/NoopMeterProvider'; const attributes = {}; const options = { @@ -133,3 +134,9 @@ describe('NoopMeter', () => { meter.removeBatchObservableCallback(() => {}, []); }); }); + +describe('createNoopMeter', () => { + it('should return NoopMeter', () => { + assert.ok(createNoopMeter() instanceof NoopMeter); + }); +}); diff --git a/experimental/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts b/experimental/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts index ff7971f66a..c7bf2f6967 100644 --- a/experimental/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts +++ b/experimental/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts @@ -15,16 +15,27 @@ */ import { Tracer, TracerProvider } from '@opentelemetry/api'; -import { NOOP_METER_PROVIDER } from '@opentelemetry/api-metrics'; import * as assert from 'assert'; import * as sinon from 'sinon'; import { InstrumentationBase, registerInstrumentations } from '../../src'; +import { + Meter, + MeterOptions, + MeterProvider, +} from '@opentelemetry/api-metrics'; class DummyTracerProvider implements TracerProvider { getTracer(name: string, version?: string): Tracer { throw new Error('not implemented'); } } + +class DummyMeterProvider implements MeterProvider { + getMeter(name: string, version?: string, options?: MeterOptions): Meter { + throw new Error('not implemented'); + } +} + class FooInstrumentation extends InstrumentationBase { init() { return []; @@ -50,14 +61,14 @@ describe('autoLoader', () => { let instrumentation: InstrumentationBase; let enableSpy: sinon.SinonSpy; let setTracerProviderSpy: sinon.SinonSpy; - let setsetMeterProvider: sinon.SinonSpy; + let setMeterProviderSpy: sinon.SinonSpy; const tracerProvider = new DummyTracerProvider(); - const meterProvider = NOOP_METER_PROVIDER; + const meterProvider = new DummyMeterProvider(); beforeEach(() => { instrumentation = new FooInstrumentation('foo', '1', {}); enableSpy = sinon.spy(instrumentation, 'enable'); setTracerProviderSpy = sinon.stub(instrumentation, 'setTracerProvider'); - setsetMeterProvider = sinon.stub(instrumentation, 'setMeterProvider'); + setMeterProviderSpy = sinon.stub(instrumentation, 'setMeterProvider'); unload = registerInstrumentations({ instrumentations: [instrumentation], tracerProvider, @@ -85,6 +96,7 @@ describe('autoLoader', () => { ); enableSpy = sinon.spy(instrumentation, 'enable'); setTracerProviderSpy = sinon.stub(instrumentation, 'setTracerProvider'); + setMeterProviderSpy = sinon.stub(instrumentation, 'setMeterProvider'); unload = registerInstrumentations({ instrumentations: [instrumentation], tracerProvider, @@ -104,9 +116,9 @@ describe('autoLoader', () => { }); it('should set MeterProvider', () => { - assert.strictEqual(setsetMeterProvider.callCount, 1); - assert.ok(setsetMeterProvider.lastCall.args[0] === meterProvider); - assert.strictEqual(setsetMeterProvider.lastCall.args.length, 1); + assert.strictEqual(setMeterProviderSpy.callCount, 1); + assert.ok(setMeterProviderSpy.lastCall.args[0] === meterProvider); + assert.strictEqual(setMeterProviderSpy.lastCall.args.length, 1); }); }); }); diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts b/experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts index 003bb41a6b..f8008d1c4b 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts @@ -55,7 +55,7 @@ export class MeterProvider implements metrics.MeterProvider { // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#meter-creation if (this._shutdown) { api.diag.warn('A shutdown MeterProvider cannot provide a Meter'); - return metrics.NOOP_METER; + return metrics.createNoopMeter(); } return this._sharedState diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts index 3d7dc68c6a..e8c42bf798 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts @@ -15,7 +15,6 @@ */ import * as assert from 'assert'; -import { NOOP_METER } from '@opentelemetry/api-metrics'; import { Meter, MeterProvider, InstrumentType, DataPointType } from '../src'; import { assertScopeMetrics, @@ -62,7 +61,8 @@ describe('MeterProvider', () => { const meterProvider = new MeterProvider(); meterProvider.shutdown(); const meter = meterProvider.getMeter('meter1', '1.0.0'); - assert.strictEqual(meter, NOOP_METER); + // returned tracer should be no-op, not instance of Meter (from SDK) + assert.ok(!(meter instanceof Meter)); }); it('get meter with same identity', async () => { diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index ebc07dc2bc..c1b0b90d56 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -22,13 +22,21 @@ import { diag, DiagLogLevel, } from '@opentelemetry/api'; -import { metrics, NoopMeterProvider } from '@opentelemetry/api-metrics'; +import { metrics } from '@opentelemetry/api-metrics'; import { AsyncHooksContextManager, AsyncLocalStorageContextManager, } from '@opentelemetry/context-async-hooks'; import { CompositePropagator } from '@opentelemetry/core'; -import { AggregationTemporality, ConsoleMetricExporter, InMemoryMetricExporter, InstrumentType, MeterProvider, PeriodicExportingMetricReader, View } from '@opentelemetry/sdk-metrics'; +import { + AggregationTemporality, + ConsoleMetricExporter, + InMemoryMetricExporter, + InstrumentType, + MeterProvider, + PeriodicExportingMetricReader, + View, +} from '@opentelemetry/sdk-metrics'; import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { assertServiceResource, @@ -41,7 +49,11 @@ import * as assert from 'assert'; import * as semver from 'semver'; import * as Sinon from 'sinon'; import { NodeSDK } from '../src'; -import {envDetector, processDetector, Resource} from '@opentelemetry/resources'; +import { + envDetector, + processDetector, + Resource +} from '@opentelemetry/resources'; const DefaultContextManager = semver.gte(process.version, '14.8.0') @@ -76,7 +88,7 @@ describe('Node SDK', () => { assert.strictEqual(propagation['_getGlobalPropagator'](), propagator, 'propagator should not change'); assert.strictEqual((trace.getTracerProvider() as ProxyTracerProvider).getDelegate(), delegate, 'tracer provider should not have changed'); - assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); + assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider)); }); it('should register a tracer provider if an exporter is provided', async () => { @@ -87,7 +99,7 @@ describe('Node SDK', () => { await sdk.start(); - assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); + assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider)); assert.ok( context['_getContextManager']().constructor.name === DefaultContextManager.name @@ -110,7 +122,7 @@ describe('Node SDK', () => { await sdk.start(); - assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); + assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider)); assert.ok( context['_getContextManager']().constructor.name === DefaultContextManager.name From c926e3d76b0b7397a7ecf286be31c40ab0b445d9 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Tue, 6 Sep 2022 05:31:07 +0200 Subject: [PATCH 07/77] fix: rollback linkinator (#3231) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e8bf21849a..59bc7ae95c 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "gh-pages": "4.0.0", "lerna": "5.4.3", "lerna-changelog": "2.2.0", - "linkinator": "4.0.2", + "linkinator": "3.0.3", "markdownlint-cli": "0.29.0", "semver": "7.3.5", "typedoc": "0.22.10", From a8047ba9cdda65292778614ec9a1f8a2045faa9f Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Tue, 6 Sep 2022 15:34:20 +0200 Subject: [PATCH 08/77] docs: add experimental disclaimers to all experimental packages. (#3233) --- experimental/packages/exporter-trace-otlp-grpc/README.md | 2 ++ experimental/packages/exporter-trace-otlp-http/README.md | 2 ++ experimental/packages/exporter-trace-otlp-proto/README.md | 2 ++ experimental/packages/opentelemetry-api-metrics/README.md | 2 ++ .../opentelemetry-exporter-metrics-otlp-grpc/README.md | 2 ++ .../opentelemetry-exporter-metrics-otlp-http/README.md | 2 ++ .../opentelemetry-exporter-metrics-otlp-proto/README.md | 2 ++ .../packages/opentelemetry-exporter-prometheus/README.md | 2 ++ .../packages/opentelemetry-instrumentation-fetch/README.md | 2 ++ .../packages/opentelemetry-instrumentation-grpc/README.md | 2 ++ .../packages/opentelemetry-instrumentation-http/README.md | 2 ++ .../opentelemetry-instrumentation-xml-http-request/README.md | 2 ++ experimental/packages/opentelemetry-instrumentation/README.md | 2 ++ experimental/packages/opentelemetry-sdk-metrics/README.md | 2 ++ experimental/packages/opentelemetry-sdk-node/README.md | 2 ++ experimental/packages/otlp-exporter-base/README.md | 2 ++ experimental/packages/otlp-grpc-exporter-base/README.md | 2 ++ experimental/packages/otlp-proto-exporter-base/README.md | 2 ++ experimental/packages/otlp-transformer/README.md | 4 +++- 19 files changed, 39 insertions(+), 1 deletion(-) diff --git a/experimental/packages/exporter-trace-otlp-grpc/README.md b/experimental/packages/exporter-trace-otlp-grpc/README.md index 3893a9f449..b03274b320 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/README.md +++ b/experimental/packages/exporter-trace-otlp-grpc/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides exporter for node to be used with OTLP (`grpc`) compatible receivers. Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.16 <=0.50`. diff --git a/experimental/packages/exporter-trace-otlp-http/README.md b/experimental/packages/exporter-trace-otlp-http/README.md index 448c8caf20..5afdf0d9e0 100644 --- a/experimental/packages/exporter-trace-otlp-http/README.md +++ b/experimental/packages/exporter-trace-otlp-http/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides exporter for web and node to be used with OTLP (`http/json`) compatible receivers. Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.48 <=0.50`. diff --git a/experimental/packages/exporter-trace-otlp-proto/README.md b/experimental/packages/exporter-trace-otlp-proto/README.md index 56551f9288..0338b4cd93 100644 --- a/experimental/packages/exporter-trace-otlp-proto/README.md +++ b/experimental/packages/exporter-trace-otlp-proto/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides exporter for node to be used with OTLP (`http/protobuf`) compatible receivers. Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.32 <=0.50`. diff --git a/experimental/packages/opentelemetry-api-metrics/README.md b/experimental/packages/opentelemetry-api-metrics/README.md index 838aca5226..d9e8745ec7 100644 --- a/experimental/packages/opentelemetry-api-metrics/README.md +++ b/experimental/packages/opentelemetry-api-metrics/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This package provides everything needed to interact with the unstable OpenTelemetry Metrics API, including all TypeScript interfaces, enums, and no-op implementations. It is intended for use both on the server and in the browser. ## Beta Software - Use at your own risk diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md index 382e657272..02f25fc855 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides exporter for node to be used with OTLP (`grpc`) compatible receivers. Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.16 <=0.53`. diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md index 644a5b3449..28fa70613b 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides exporter for web and node to be used with OTLP (`http/json`) compatible receivers. Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.52 <=0.53`. diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md index da8746fb5b..1c1c115d48 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides exporter for node to be used with OTLP (`http/protobuf`) compatible receivers. Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.32 <=0.53`. diff --git a/experimental/packages/opentelemetry-exporter-prometheus/README.md b/experimental/packages/opentelemetry-exporter-prometheus/README.md index f0ce7ff97d..97ea063d3c 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/README.md +++ b/experimental/packages/opentelemetry-exporter-prometheus/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + The OpenTelemetry Prometheus Metrics Exporter allows the user to send collected [OpenTelemetry Metrics](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-metrics) to Prometheus. [Prometheus](https://prometheus.io/) is a monitoring system that collects metrics, by scraping exposed endpoints at regular intervals, evaluating rule expressions. It can also trigger alerts if certain conditions are met. For assistance setting up Prometheus, [Click here](https://opencensus.io/codelabs/prometheus/#0) for a guided codelab. diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/README.md b/experimental/packages/opentelemetry-instrumentation-fetch/README.md index bf6719731c..67ecbd6082 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/README.md +++ b/experimental/packages/opentelemetry-instrumentation-fetch/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides auto instrumentation for web using fetch. ## Installation diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/README.md b/experimental/packages/opentelemetry-instrumentation-grpc/README.md index 44d598fe14..16a5b22eae 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/README.md +++ b/experimental/packages/opentelemetry-instrumentation-grpc/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides automatic instrumentation for [`grpc`](https://grpc.github.io/grpc/node/) and [`@grpc/grpc-js`](https://grpc.io/blog/grpc-js-1.0/). Currently, version [`1.x`](https://www.npmjs.com/package/grpc?activeTab=versions) of `grpc` and version [`1.x`](https://www.npmjs.com/package/@grpc/grpc-js?activeTab=versions) of `@grpc/grpc-js` is supported. For automatic instrumentation see the diff --git a/experimental/packages/opentelemetry-instrumentation-http/README.md b/experimental/packages/opentelemetry-instrumentation-http/README.md index 4684adaa4c..5973ceb796 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/README.md +++ b/experimental/packages/opentelemetry-instrumentation-http/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides automatic instrumentation for [`http`](https://nodejs.org/api/http.html) and [`https`](https://nodejs.org/api/https.html). For automatic instrumentation see the diff --git a/experimental/packages/opentelemetry-instrumentation-xml-http-request/README.md b/experimental/packages/opentelemetry-instrumentation-xml-http-request/README.md index bdd343d46c..c02aa030d2 100644 --- a/experimental/packages/opentelemetry-instrumentation-xml-http-request/README.md +++ b/experimental/packages/opentelemetry-instrumentation-xml-http-request/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides auto instrumentation for web using XMLHttpRequest . ## Installation diff --git a/experimental/packages/opentelemetry-instrumentation/README.md b/experimental/packages/opentelemetry-instrumentation/README.md index 834b5adc87..26e9f8c696 100644 --- a/experimental/packages/opentelemetry-instrumentation/README.md +++ b/experimental/packages/opentelemetry-instrumentation/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + ## Installation ```bash diff --git a/experimental/packages/opentelemetry-sdk-metrics/README.md b/experimental/packages/opentelemetry-sdk-metrics/README.md index 39b4f5f3c7..044c385913 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/README.md +++ b/experimental/packages/opentelemetry-sdk-metrics/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + OpenTelemetry metrics module contains the foundation for all metrics SDKs of [opentelemetry-js](https://github.com/open-telemetry/opentelemetry-js). Used standalone, this module provides methods for manual instrumentation of code, offering full control over recording metrics for client-side JavaScript (browser) and Node.js. diff --git a/experimental/packages/opentelemetry-sdk-node/README.md b/experimental/packages/opentelemetry-sdk-node/README.md index e0ed90099c..008e8f5eee 100644 --- a/experimental/packages/opentelemetry-sdk-node/README.md +++ b/experimental/packages/opentelemetry-sdk-node/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This package provides the full OpenTelemetry SDK for Node.js including tracing and metrics. ## Quick Start diff --git a/experimental/packages/otlp-exporter-base/README.md b/experimental/packages/otlp-exporter-base/README.md index cdb8a26cdc..f44387c402 100644 --- a/experimental/packages/otlp-exporter-base/README.md +++ b/experimental/packages/otlp-exporter-base/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides a base exporter for web and node to be used with [opentelemetry-collector][opentelemetry-collector-url]. ## Installation diff --git a/experimental/packages/otlp-grpc-exporter-base/README.md b/experimental/packages/otlp-grpc-exporter-base/README.md index c55d7d2e2a..ec6f495b9a 100644 --- a/experimental/packages/otlp-grpc-exporter-base/README.md +++ b/experimental/packages/otlp-grpc-exporter-base/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides a gRPC exporter base for Node.js (browsers not supported) to be used with [opentelemetry-collector][opentelemetry-collector-url]. ## Installation diff --git a/experimental/packages/otlp-proto-exporter-base/README.md b/experimental/packages/otlp-proto-exporter-base/README.md index adeffe39f4..ed9f0d679b 100644 --- a/experimental/packages/otlp-proto-exporter-base/README.md +++ b/experimental/packages/otlp-proto-exporter-base/README.md @@ -3,6 +3,8 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] +**Note: This is an experimental package under active development. New releases may include breaking changes.** + This module provides a OTLP-http/protobuf exporter base for Node.js (browsers not supported) to be used with [opentelemetry-collector][opentelemetry-collector-url]. ## Installation diff --git a/experimental/packages/otlp-transformer/README.md b/experimental/packages/otlp-transformer/README.md index fc5c13af9e..e069aab559 100644 --- a/experimental/packages/otlp-transformer/README.md +++ b/experimental/packages/otlp-transformer/README.md @@ -3,7 +3,9 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] -**NOTE: This package is intended for internal use only.** +**Note: This package is intended for internal use only.** + +**Note: This is an experimental package under active development. New releases may include breaking changes.** This package provides everything needed to serialize [OpenTelemetry SDK][sdk] traces and metrics into the [OpenTelemetry Protocol][otlp] format. From 597ea98e58a4f68bcd9aec5fd283852efe444cd6 Mon Sep 17 00:00:00 2001 From: Hector Hernandez <39923391+hectorhdzg@users.noreply.github.com> Date: Tue, 6 Sep 2022 11:22:22 -0700 Subject: [PATCH 09/77] Add HTTP Server and Client duration Metrics in HTTP Node.js Instrumentation (#3149) --- experimental/CHANGELOG.md | 1 + .../package.json | 2 + .../src/http.ts | 101 ++++++++++++----- .../src/utils.ts | 64 ++++++++++- .../test/functionals/http-metrics.test.ts | 103 ++++++++++++++++++ .../test/utils/assertSpan.ts | 7 +- .../tsconfig.json | 6 + 7 files changed, 254 insertions(+), 30 deletions(-) create mode 100644 experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index a489427839..377e37c9fa 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -57,6 +57,7 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) +* feature(instrumentation-http): Add HTTP Server and Client duration Metrics in HTTP Node.js Instrumentation [#3149](https://github.com/open-telemetry/opentelemetry-js/pull/3149) @hectorhdzg * fix(add-views-to-node-sdk): added the ability to define meter views in `NodeSDK` [#3066](https://github.com/open-telemetry/opentelemetry-js/pull/3124) @weyert * feature(add-console-metrics-exporter): add ConsoleMetricExporter [#3120](https://github.com/open-telemetry/opentelemetry-js/pull/3120) @weyert * feature(prometheus-serialiser): export the unit block when unit is set in metric descriptor [#3066](https://github.com/open-telemetry/opentelemetry-js/pull/3041) @weyert diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index a248b031ea..754414cf9f 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -74,8 +74,10 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { + "@opentelemetry/api-metrics": "0.32.0", "@opentelemetry/core": "1.6.0", "@opentelemetry/instrumentation": "0.32.0", + "@opentelemetry/sdk-metrics": "0.32.0", "@opentelemetry/semantic-conventions": "1.6.0", "semver": "^7.3.5" }, diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts index 5459e1d26f..a0e07a1e9f 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts @@ -15,6 +15,7 @@ */ import { context, + HrTime, INVALID_SPAN_CONTEXT, propagation, ROOT_CONTEXT, @@ -25,7 +26,8 @@ import { SpanStatusCode, trace, } from '@opentelemetry/api'; -import { suppressTracing } from '@opentelemetry/core'; +import { Histogram, MeterProvider, MetricAttributes, ValueType } from '@opentelemetry/api-metrics'; +import { hrTime, hrTimeDuration, hrTimeToMilliseconds, suppressTracing } from '@opentelemetry/core'; import type * as http from 'http'; import type * as https from 'https'; import { Socket } from 'net'; @@ -58,6 +60,8 @@ export class HttpInstrumentation extends InstrumentationBase { private readonly _spanNotEnded: WeakSet = new WeakSet(); private readonly _version = process.versions.node; private _headerCapture; + private _httpServerDurationHistogram!: Histogram; + private _httpClientDurationHistogram!: Histogram; constructor(config?: HttpInstrumentationConfig) { super( @@ -65,8 +69,26 @@ export class HttpInstrumentation extends InstrumentationBase { VERSION, config ); - this._headerCapture = this._createHeaderCapture(); + this._updateMetricInstruments(); + } + + override setMeterProvider(meterProvider: MeterProvider) { + super.setMeterProvider(meterProvider); + this._updateMetricInstruments(); + } + + private _updateMetricInstruments() { + this._httpServerDurationHistogram = this.meter.createHistogram('http.server.duration', { + description: 'measures the duration of the inbound HTTP requests', + unit: 'ms', + valueType: ValueType.DOUBLE + }); + this._httpClientDurationHistogram = this.meter.createHistogram('http.client.duration', { + description: 'measures the duration of the outbound HTTP requests', + unit: 'ms', + valueType: ValueType.DOUBLE + }); } private _getConfig(): HttpInstrumentationConfig { @@ -272,11 +294,15 @@ export class HttpInstrumentation extends InstrumentationBase { * @param request The original request object. * @param options The arguments to the original function. * @param span representing the current operation + * @param startTime representing the start time of the request to calculate duration in Metric + * @param metricAttributes metric attributes */ private _traceClientRequest( request: http.ClientRequest, hostname: string, - span: Span + span: Span, + startTime: HrTime, + metricAttributes: MetricAttributes ): http.ClientRequest { if (this._getConfig().requestHook) { this._callRequestHook(span, request); @@ -294,6 +320,8 @@ export class HttpInstrumentation extends InstrumentationBase { response, ); span.setAttributes(responseAttributes); + metricAttributes = Object.assign(metricAttributes, utils.getOutgoingRequestMetricAttributesOnResponse(responseAttributes)); + if (this._getConfig().responseHook) { this._callResponseHook(span, response); } @@ -323,32 +351,32 @@ export class HttpInstrumentation extends InstrumentationBase { request, response ), - () => {}, + () => { }, true ); } - this._closeHttpSpan(span); + this._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes); }); response.on('error', (error: Err) => { this._diag.debug('outgoingRequest on error()', error); utils.setSpanWithError(span, error); const code = utils.parseResponseStatus(SpanKind.CLIENT, response.statusCode); span.setStatus({ code, message: error.message }); - this._closeHttpSpan(span); + this._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes); }); } ); request.on('close', () => { this._diag.debug('outgoingRequest on request close()'); if (!request.aborted) { - this._closeHttpSpan(span); + this._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes); } }); request.on('error', (error: Err) => { this._diag.debug('outgoingRequest on request error()', error); utils.setSpanWithError(span, error); - this._closeHttpSpan(span); + this._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes); }); this._diag.debug('http.ClientRequest return request'); @@ -404,18 +432,23 @@ export class HttpInstrumentation extends InstrumentationBase { const headers = request.headers; + const spanAttributes = utils.getIncomingRequestAttributes(request, { + component: component, + serverName: instrumentation._getConfig().serverName, + hookAttributes: instrumentation._callStartSpanHook( + request, + instrumentation._getConfig().startIncomingSpanHook + ), + }); + const spanOptions: SpanOptions = { kind: SpanKind.SERVER, - attributes: utils.getIncomingRequestAttributes(request, { - component: component, - serverName: instrumentation._getConfig().serverName, - hookAttributes: instrumentation._callStartSpanHook( - request, - instrumentation._getConfig().startIncomingSpanHook - ), - }), + attributes: spanAttributes, }; + const startTime = hrTime(); + let metricAttributes: MetricAttributes = utils.getIncomingRequestMetricAttributes(spanAttributes); + const ctx = propagation.extract(ROOT_CONTEXT, headers); const span = instrumentation._startHttpSpan( `${component.toLocaleUpperCase()} ${method}`, @@ -456,7 +489,7 @@ export class HttpInstrumentation extends InstrumentationBase { error => { if (error) { utils.setSpanWithError(span, error); - instrumentation._closeHttpSpan(span); + instrumentation._closeHttpSpan(span, SpanKind.SERVER, startTime, metricAttributes); throw error; } } @@ -466,6 +499,7 @@ export class HttpInstrumentation extends InstrumentationBase { request, response ); + metricAttributes = Object.assign(metricAttributes, utils.getIncomingRequestMetricAttributesOnResponse(attributes)); instrumentation._headerCapture.server.captureResponseHeaders(span, header => response.getHeader(header)); @@ -481,12 +515,12 @@ export class HttpInstrumentation extends InstrumentationBase { request, response ), - () => {}, + () => { }, true ); } - instrumentation._closeHttpSpan(span); + instrumentation._closeHttpSpan(span, SpanKind.SERVER, startTime, metricAttributes); return returned; }; @@ -495,7 +529,7 @@ export class HttpInstrumentation extends InstrumentationBase { error => { if (error) { utils.setSpanWithError(span, error); - instrumentation._closeHttpSpan(span); + instrumentation._closeHttpSpan(span, SpanKind.SERVER, startTime, metricAttributes); throw error; } } @@ -520,7 +554,7 @@ export class HttpInstrumentation extends InstrumentationBase { } const extraOptions = typeof args[0] === 'object' && - (typeof options === 'string' || options instanceof url.URL) + (typeof options === 'string' || options instanceof url.URL) ? (args.shift() as http.RequestOptions) : undefined; const { origin, pathname, method, optionsParsed } = utils.getRequestInfo( @@ -572,6 +606,9 @@ export class HttpInstrumentation extends InstrumentationBase { ), }); + const startTime = hrTime(); + const metricAttributes: MetricAttributes = utils.getOutgoingRequestMetricAttributes(attributes); + const spanOptions: SpanOptions = { kind: SpanKind.CLIENT, attributes, @@ -601,7 +638,7 @@ export class HttpInstrumentation extends InstrumentationBase { error => { if (error) { utils.setSpanWithError(span, error); - instrumentation._closeHttpSpan(span); + instrumentation._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes); throw error; } } @@ -612,7 +649,9 @@ export class HttpInstrumentation extends InstrumentationBase { return instrumentation._traceClientRequest( request, hostname, - span + span, + startTime, + metricAttributes ); }); }; @@ -646,13 +685,21 @@ export class HttpInstrumentation extends InstrumentationBase { return span; } - private _closeHttpSpan(span: Span) { + private _closeHttpSpan(span: Span, spanKind: SpanKind, startTime: HrTime, metricAttributes: MetricAttributes) { if (!this._spanNotEnded.has(span)) { return; } span.end(); this._spanNotEnded.delete(span); + + // Record metrics + const duration = hrTimeToMilliseconds(hrTimeDuration(startTime, hrTime())); + if (spanKind === SpanKind.SERVER) { + this._httpServerDurationHistogram.record(duration, metricAttributes); + } else if (spanKind === SpanKind.CLIENT) { + this._httpClientDurationHistogram.record(duration, metricAttributes); + } } private _callResponseHook( @@ -661,7 +708,7 @@ export class HttpInstrumentation extends InstrumentationBase { ) { safeExecuteInTheMiddle( () => this._getConfig().responseHook!(span, response), - () => {}, + () => { }, true ); } @@ -672,7 +719,7 @@ export class HttpInstrumentation extends InstrumentationBase { ) { safeExecuteInTheMiddle( () => this._getConfig().requestHook!(span, request), - () => {}, + () => { }, true ); } @@ -681,7 +728,7 @@ export class HttpInstrumentation extends InstrumentationBase { request: http.IncomingMessage | http.RequestOptions, hookFunc: Function | undefined, ) { - if(typeof hookFunc === 'function'){ + if (typeof hookFunc === 'function') { return safeExecuteInTheMiddle( () => hookFunc(request), () => { }, diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts index f42f9955b3..e9e9b45468 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts @@ -35,6 +35,7 @@ import { getRPCMetadata, RPCType } from '@opentelemetry/core'; import * as url from 'url'; import { AttributeNames } from './enums/AttributeNames'; import { Err, IgnoreMatcher, ParsedRequestOptions } from './types'; +import { MetricAttributes } from '@opentelemetry/api-metrics'; /** * Get an absolute url @@ -299,7 +300,7 @@ export const extractHostnameAndPort = ( requestOptions: Pick ): { hostname: string, port: number | string } => { if (requestOptions.hostname && requestOptions.port) { - return {hostname: requestOptions.hostname, port: requestOptions.port}; + return { hostname: requestOptions.hostname, port: requestOptions.port }; } const matches = requestOptions.host?.match(/^([^:/ ]+)(:\d{1,5})?/) || null; const hostname = requestOptions.hostname || (matches === null ? 'localhost' : matches[1]); @@ -312,7 +313,7 @@ export const extractHostnameAndPort = ( port = requestOptions.protocol === 'https:' ? '443' : '80'; } } - return {hostname, port}; + return { hostname, port }; }; /** @@ -348,6 +349,20 @@ export const getOutgoingRequestAttributes = ( return Object.assign(attributes, options.hookAttributes); }; +/** + * Returns outgoing request Metric attributes scoped to the request data + * @param {SpanAttributes} spanAttributes the span attributes + */ +export const getOutgoingRequestMetricAttributes = ( + spanAttributes: SpanAttributes +): MetricAttributes => { + const metricAttributes: MetricAttributes = {}; + metricAttributes[SemanticAttributes.HTTP_METHOD] = spanAttributes[SemanticAttributes.HTTP_METHOD]; + metricAttributes[SemanticAttributes.NET_PEER_NAME] = spanAttributes[SemanticAttributes.NET_PEER_NAME]; + //TODO: http.url attribute, it should susbtitute any parameters to avoid high cardinality. + return metricAttributes; +}; + /** * Returns attributes related to the kind of HTTP protocol used * @param {string} [kind] Kind of HTTP protocol used: "1.0", "1.1", "2", "SPDY" or "QUIC". @@ -392,6 +407,20 @@ export const getOutgoingRequestAttributesOnResponse = ( return Object.assign(attributes, httpKindAttributes); }; +/** + * Returns outgoing request Metric attributes scoped to the response data + * @param {SpanAttributes} spanAttributes the span attributes + */ +export const getOutgoingRequestMetricAttributesOnResponse = ( + spanAttributes: SpanAttributes +): MetricAttributes => { + const metricAttributes: MetricAttributes = {}; + metricAttributes[SemanticAttributes.NET_PEER_PORT] = spanAttributes[SemanticAttributes.NET_PEER_PORT]; + metricAttributes[SemanticAttributes.HTTP_STATUS_CODE] = spanAttributes[SemanticAttributes.HTTP_STATUS_CODE]; + metricAttributes[SemanticAttributes.HTTP_FLAVOR] = spanAttributes[SemanticAttributes.HTTP_FLAVOR]; + return metricAttributes; +}; + /** * Returns incoming request attributes scoped to the request data * @param {IncomingMessage} request the request object @@ -422,6 +451,7 @@ export const getIncomingRequestAttributes = ( [SemanticAttributes.HTTP_HOST]: host, [SemanticAttributes.NET_HOST_NAME]: hostname, [SemanticAttributes.HTTP_METHOD]: method, + [SemanticAttributes.HTTP_SCHEME]: options.component, }; if (typeof ips === 'string') { @@ -445,6 +475,23 @@ export const getIncomingRequestAttributes = ( return Object.assign(attributes, httpKindAttributes, options.hookAttributes); }; +/** + * Returns incoming request Metric attributes scoped to the request data + * @param {SpanAttributes} spanAttributes the span attributes + * @param {{ component: string }} options used to pass data needed to create attributes + */ +export const getIncomingRequestMetricAttributes = ( + spanAttributes: SpanAttributes +): MetricAttributes => { + const metricAttributes: MetricAttributes = {}; + metricAttributes[SemanticAttributes.HTTP_SCHEME] = spanAttributes[SemanticAttributes.HTTP_SCHEME]; + metricAttributes[SemanticAttributes.HTTP_METHOD] = spanAttributes[SemanticAttributes.HTTP_METHOD]; + metricAttributes[SemanticAttributes.NET_HOST_NAME] = spanAttributes[SemanticAttributes.NET_HOST_NAME]; + metricAttributes[SemanticAttributes.HTTP_FLAVOR] = spanAttributes[SemanticAttributes.HTTP_FLAVOR]; + //TODO: http.target attribute, it should susbtitute any parameters to avoid high cardinality. + return metricAttributes; +}; + /** * Returns incoming request attributes scoped to the response data * @param {(ServerResponse & { socket: Socket; })} response the response object @@ -475,6 +522,19 @@ export const getIncomingRequestAttributesOnResponse = ( return attributes; }; +/** + * Returns incoming request Metric attributes scoped to the request data + * @param {SpanAttributes} spanAttributes the span attributes + */ +export const getIncomingRequestMetricAttributesOnResponse = ( + spanAttributes: SpanAttributes +): MetricAttributes => { + const metricAttributes: MetricAttributes = {}; + metricAttributes[SemanticAttributes.HTTP_STATUS_CODE] = spanAttributes[SemanticAttributes.HTTP_STATUS_CODE]; + metricAttributes[SemanticAttributes.NET_HOST_PORT] = spanAttributes[SemanticAttributes.NET_HOST_PORT]; + return metricAttributes; +}; + export function headerCapture(type: 'request' | 'response', headers: string[]) { const normalizedHeaders = new Map(headers.map(header => [header.toLowerCase(), header.toLowerCase().replace(/-/g, '_')])); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts new file mode 100644 index 0000000000..5ab046b45f --- /dev/null +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts @@ -0,0 +1,103 @@ +/* + * 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 { + AggregationTemporality, + DataPointType, + InMemoryMetricExporter, + MeterProvider, + PeriodicExportingMetricReader, +} from '@opentelemetry/sdk-metrics'; +import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; +import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; +import * as assert from 'assert'; +import { HttpInstrumentation } from '../../src/http'; +import { httpRequest } from '../utils/httpRequest'; + +const instrumentation = new HttpInstrumentation(); +instrumentation.enable(); +instrumentation.disable(); + +import * as http from 'http'; + +let server: http.Server; +const serverPort = 22346; +const protocol = 'http'; +const hostname = 'localhost'; +const pathname = '/test'; +const tracerProvider = new NodeTracerProvider(); +const meterProvider = new MeterProvider(); +const metricsMemoryExporter = new InMemoryMetricExporter(AggregationTemporality.DELTA); +const metricReader = new PeriodicExportingMetricReader({ exporter: metricsMemoryExporter, exportIntervalMillis: 100 }); +meterProvider.addMetricReader(metricReader); +instrumentation.setTracerProvider(tracerProvider); +instrumentation.setMeterProvider(meterProvider); + + +describe('metrics', () => { + beforeEach(() => { + metricsMemoryExporter.reset(); + }); + + before(() => { + instrumentation.enable(); + server = http.createServer((request, response) => { + response.end('Test Server Response'); + }); + server.listen(serverPort); + }); + + after(() => { + server.close(); + instrumentation.disable(); + }); + + it('should add server/client duration metrics', async () => { + const requestCount = 3; + for (let i = 0; i < requestCount; i++) { + await httpRequest.get(`${protocol}://${hostname}:${serverPort}${pathname}`); + } + await new Promise(resolve => setTimeout(resolve, 300)); + const resourceMetrics = metricsMemoryExporter.getMetrics(); + const scopeMetrics = resourceMetrics[0].scopeMetrics; + assert.strictEqual(scopeMetrics.length, 1, 'scopeMetrics count'); + const metrics = scopeMetrics[0].metrics; + assert.strictEqual(metrics.length, 2, 'metrics count'); + assert.strictEqual(metrics[0].dataPointType, DataPointType.HISTOGRAM); + assert.strictEqual(metrics[0].descriptor.description, 'measures the duration of the inbound HTTP requests'); + assert.strictEqual(metrics[0].descriptor.name, 'http.server.duration'); + assert.strictEqual(metrics[0].descriptor.unit, 'ms'); + assert.strictEqual(metrics[0].dataPoints.length, 1); + assert.strictEqual((metrics[0].dataPoints[0].value as any).count, requestCount); + assert.strictEqual(metrics[0].dataPoints[0].attributes[SemanticAttributes.HTTP_SCHEME], 'http'); + assert.strictEqual(metrics[0].dataPoints[0].attributes[SemanticAttributes.HTTP_METHOD], 'GET'); + assert.strictEqual(metrics[0].dataPoints[0].attributes[SemanticAttributes.HTTP_FLAVOR], '1.1'); + assert.strictEqual(metrics[0].dataPoints[0].attributes[SemanticAttributes.NET_HOST_NAME], 'localhost'); + assert.strictEqual(metrics[0].dataPoints[0].attributes[SemanticAttributes.HTTP_STATUS_CODE], 200); + assert.strictEqual(metrics[0].dataPoints[0].attributes[SemanticAttributes.NET_HOST_PORT], 22346); + + assert.strictEqual(metrics[1].dataPointType, DataPointType.HISTOGRAM); + assert.strictEqual(metrics[1].descriptor.description, 'measures the duration of the outbound HTTP requests'); + assert.strictEqual(metrics[1].descriptor.name, 'http.client.duration'); + assert.strictEqual(metrics[1].descriptor.unit, 'ms'); + assert.strictEqual(metrics[1].dataPoints.length, 1); + assert.strictEqual((metrics[1].dataPoints[0].value as any).count, requestCount); + assert.strictEqual(metrics[1].dataPoints[0].attributes[SemanticAttributes.HTTP_METHOD], 'GET'); + assert.strictEqual(metrics[1].dataPoints[0].attributes[SemanticAttributes.NET_PEER_NAME], 'localhost'); + assert.strictEqual(metrics[1].dataPoints[0].attributes[SemanticAttributes.NET_PEER_PORT], 22346); + assert.strictEqual(metrics[1].dataPoints[0].attributes[SemanticAttributes.HTTP_STATUS_CODE], 200); + assert.strictEqual(metrics[1].dataPoints[0].attributes[SemanticAttributes.HTTP_FLAVOR], '1.1'); + }); +}); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/utils/assertSpan.ts b/experimental/packages/opentelemetry-instrumentation-http/test/utils/assertSpan.ts index db0d0d1ea0..3b9b1a402d 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/utils/assertSpan.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/utils/assertSpan.ts @@ -125,7 +125,7 @@ export const assertSpan = ( validations.hostname, 'must be consistent (PEER_NAME and hostname)' ); - if(!validations.noNetPeer) { + if (!validations.noNetPeer) { assert.ok( span.attributes[SemanticAttributes.NET_PEER_IP], 'must have PEER_IP' @@ -178,6 +178,11 @@ export const assertSpan = ( 'must have HOST_IP' ); } + assert.strictEqual( + span.attributes[SemanticAttributes.HTTP_SCHEME], + validations.component, + ' must have http.scheme attribute' + ); assert.ok(typeof span.parentSpanId === 'string'); assert.ok(isValidSpanId(span.parentSpanId)); } else if (validations.reqHeaders) { diff --git a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json index b883031b0f..034c613b3e 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json @@ -24,8 +24,14 @@ { "path": "../../../packages/opentelemetry-semantic-conventions" }, + { + "path": "../opentelemetry-api-metrics" + }, { "path": "../opentelemetry-instrumentation" + }, + { + "path": "../opentelemetry-sdk-metrics" } ] } From 5005b0be18ad5f4b7a42abdd03e53a71e9cf7b5c Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Wed, 7 Sep 2022 21:09:43 +0200 Subject: [PATCH 10/77] docs(node-sdk): update outdated metric documentation. (#3226) --- .../packages/opentelemetry-sdk-node/README.md | 26 ++++++++----------- .../opentelemetry-sdk-node/src/sdk.ts | 5 +--- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/experimental/packages/opentelemetry-sdk-node/README.md b/experimental/packages/opentelemetry-sdk-node/README.md index 008e8f5eee..97027ff7fb 100644 --- a/experimental/packages/opentelemetry-sdk-node/README.md +++ b/experimental/packages/opentelemetry-sdk-node/README.md @@ -20,7 +20,7 @@ $ npm install @opentelemetry/sdk-node $ # Install exporters and plugins $ npm install \ @opentelemetry/exporter-jaeger \ # add tracing exporters as needed - @opentelemetry/exporter-prometheus # add metrics exporters as needed + @opentelemetry/exporter-prometheus \ # add metrics exporters as needed @opentelemetry/instrumentation-http # add instrumentations as needed $ # or install all officially supported core and contrib plugins @@ -28,7 +28,7 @@ $ npm install @opentelemetry/auto-instrumentations-node ``` -> Note: this example is for Node.js. See [examples/tracer-web](https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/tracer-web) for a browser example. +> Note: this example is for Node.js. See [examples/opentelemetry-web](https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/opentelemetry-web) for a browser example. ### Initialize the SDK @@ -52,7 +52,7 @@ const sdk = new opentelemetry.NodeSDK({ // Optional - if omitted, the tracing SDK will not be initialized traceExporter: jaegerExporter, // Optional - If omitted, the metrics SDK will not be initialized - metricExporter: prometheusExporter, + metricReader: prometheusExporter, // Optional - you can use the metapackage or load each instrumentation individually instrumentations: [getNodeAutoInstrumentations()], // See the Configuration section below for additional configuration options @@ -94,17 +94,17 @@ Use a custom context manager. Default: [AsyncHooksContextManager](../../../packa Use a custom propagator. Default: [CompositePropagator](../../../packages/opentelemetry-core/src/propagation/composite.ts) using [W3C Trace Context](../../../packages/opentelemetry-core/README.md#w3ctracecontextpropagator-propagator) and [Baggage](../../../packages/opentelemetry-core/README.md#baggage-propagator) -### metricProcessor +### metricReader -Use a custom processor for metrics. Default: UngroupedProcessor +Add a [MetricReader](../opentelemetry-sdk-metrics/src/export/MetricReader.ts) +that will be passed to the `MeterProvider`. If `metricReader` is not configured, +the metrics SDK will not be initialized and registered. -### metricExporter - -Configure a metric exporter. If an exporter is not configured, the metrics SDK will not be initialized and registered. - -### metricInterval +### views -Configure an interval for metrics export in ms. Default: 60,000 (60 seconds) +A list of views to be passed to the `MeterProvider`. +Accepts an array of [View](../opentelemetry-sdk-metrics/src/view/View.ts)-instances. +This parameter can be used to configure explicit bucket sizes of histogram metrics. ### instrumentations @@ -135,10 +135,6 @@ Configure a trace exporter. If an exporter OR span processor is not configured, Configure tracing parameters. These are the same trace parameters used to [configure a tracer](../../../packages/opentelemetry-sdk-trace-base/src/types.ts#L71). -### views - -Configure views of your instruments and accepts an array of [View](../opentelemetry-sdk-metrics-base/src/view/View.ts)-instances. The parameter can be used to configure the explicit bucket sizes of histogram metrics. - ### serviceName Configure the [service name](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md#service). diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts index 11870ebf28..a48028760b 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts @@ -45,10 +45,7 @@ export type MeterProviderConfig = { */ reader?: MetricReader /** - * Lists the views that should be passed when meterProvider - * - * Note: This is only getting used when NodeSDK is responsible for - * instantiated an instance of MeterProvider + * List of {@link View}s that should be passed to the MeterProvider */ views?: View[] }; From cdbf67d1c24753a2fb49ac5323200fc17e27f4ec Mon Sep 17 00:00:00 2001 From: Martin Kuba Date: Thu, 8 Sep 2022 13:05:04 -0700 Subject: [PATCH 11/77] Logs/events API (#3117) Co-authored-by: Daniel Dyla Co-authored-by: Marc Pichler --- .github/workflows/w3c-integration-test.yml | 4 + experimental/CHANGELOG.md | 1 + experimental/packages/api-logs/.eslintignore | 1 + experimental/packages/api-logs/.eslintrc.js | 8 + experimental/packages/api-logs/LICENSE | 201 ++++++++++++++++++ experimental/packages/api-logs/README.md | 66 ++++++ experimental/packages/api-logs/karma.conf.js | 24 +++ experimental/packages/api-logs/package.json | 87 ++++++++ .../packages/api-logs/src/NoopLogger.ts | 24 +++ .../api-logs/src/NoopLoggerProvider.ts | 28 +++ .../packages/api-logs/src/api/logs.ts | 80 +++++++ experimental/packages/api-logs/src/index.ts | 24 +++ .../api-logs/src/internal/global-utils.ts | 55 +++++ .../src/platform/browser/globalThis.ts | 35 +++ .../api-logs/src/platform/browser/index.ts | 17 ++ .../packages/api-logs/src/platform/index.ts | 17 ++ .../api-logs/src/platform/node/globalThis.ts | 19 ++ .../api-logs/src/platform/node/index.ts | 17 ++ .../packages/api-logs/src/types/LogEvent.ts | 54 +++++ .../packages/api-logs/src/types/LogRecord.ts | 59 +++++ .../packages/api-logs/src/types/Logger.ts | 34 +++ .../api-logs/src/types/LoggerOptions.ts | 42 ++++ .../api-logs/src/types/LoggerProvider.ts | 34 +++ .../packages/api-logs/test/api/api.test.ts | 69 ++++++ .../packages/api-logs/test/index-webpack.ts | 20 ++ .../api-logs/test/internal/global.test.ts | 76 +++++++ .../noop-logger-provider.test.ts | 31 +++ .../noop-implementations/noop-logger.test.ts | 36 ++++ .../packages/api-logs/tsconfig.all.json | 9 + .../packages/api-logs/tsconfig.docs.json | 15 ++ .../packages/api-logs/tsconfig.esm.json | 11 + .../packages/api-logs/tsconfig.esnext.json | 11 + experimental/packages/api-logs/tsconfig.json | 11 + tsconfig.json | 3 + 34 files changed, 1223 insertions(+) create mode 100644 experimental/packages/api-logs/.eslintignore create mode 100644 experimental/packages/api-logs/.eslintrc.js create mode 100644 experimental/packages/api-logs/LICENSE create mode 100644 experimental/packages/api-logs/README.md create mode 100644 experimental/packages/api-logs/karma.conf.js create mode 100644 experimental/packages/api-logs/package.json create mode 100644 experimental/packages/api-logs/src/NoopLogger.ts create mode 100644 experimental/packages/api-logs/src/NoopLoggerProvider.ts create mode 100644 experimental/packages/api-logs/src/api/logs.ts create mode 100644 experimental/packages/api-logs/src/index.ts create mode 100644 experimental/packages/api-logs/src/internal/global-utils.ts create mode 100644 experimental/packages/api-logs/src/platform/browser/globalThis.ts create mode 100644 experimental/packages/api-logs/src/platform/browser/index.ts create mode 100644 experimental/packages/api-logs/src/platform/index.ts create mode 100644 experimental/packages/api-logs/src/platform/node/globalThis.ts create mode 100644 experimental/packages/api-logs/src/platform/node/index.ts create mode 100644 experimental/packages/api-logs/src/types/LogEvent.ts create mode 100644 experimental/packages/api-logs/src/types/LogRecord.ts create mode 100644 experimental/packages/api-logs/src/types/Logger.ts create mode 100644 experimental/packages/api-logs/src/types/LoggerOptions.ts create mode 100644 experimental/packages/api-logs/src/types/LoggerProvider.ts create mode 100644 experimental/packages/api-logs/test/api/api.test.ts create mode 100644 experimental/packages/api-logs/test/index-webpack.ts create mode 100644 experimental/packages/api-logs/test/internal/global.test.ts create mode 100644 experimental/packages/api-logs/test/noop-implementations/noop-logger-provider.test.ts create mode 100644 experimental/packages/api-logs/test/noop-implementations/noop-logger.test.ts create mode 100644 experimental/packages/api-logs/tsconfig.all.json create mode 100644 experimental/packages/api-logs/tsconfig.docs.json create mode 100644 experimental/packages/api-logs/tsconfig.esm.json create mode 100644 experimental/packages/api-logs/tsconfig.esnext.json create mode 100644 experimental/packages/api-logs/tsconfig.json diff --git a/.github/workflows/w3c-integration-test.yml b/.github/workflows/w3c-integration-test.yml index c2be63b9df..971ea6ee7f 100644 --- a/.github/workflows/w3c-integration-test.yml +++ b/.github/workflows/w3c-integration-test.yml @@ -13,6 +13,10 @@ jobs: - name: Checkout 🛎️ uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '16' + - name: restore lock files uses: actions/cache@master # must use unreleased master to cache multiple paths id: cache diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 377e37c9fa..9c3307b0b4 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -42,6 +42,7 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) * Add `resourceDetectors` option to `NodeSDK` [#3210](https://github.com/open-telemetry/opentelemetry-js/issues/3210) +* feat: add Logs API @mkuba [#3117](https://github.com/open-telemetry/opentelemetry-js/pull/3117) ### :bug: (Bug Fix) diff --git a/experimental/packages/api-logs/.eslintignore b/experimental/packages/api-logs/.eslintignore new file mode 100644 index 0000000000..378eac25d3 --- /dev/null +++ b/experimental/packages/api-logs/.eslintignore @@ -0,0 +1 @@ +build diff --git a/experimental/packages/api-logs/.eslintrc.js b/experimental/packages/api-logs/.eslintrc.js new file mode 100644 index 0000000000..7654abb6ac --- /dev/null +++ b/experimental/packages/api-logs/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + "env": { + "mocha": true, + "commonjs": true, + "shared-node-browser": true + }, + ...require('../../../eslint.config.js') +} diff --git a/experimental/packages/api-logs/LICENSE b/experimental/packages/api-logs/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/experimental/packages/api-logs/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + 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. diff --git a/experimental/packages/api-logs/README.md b/experimental/packages/api-logs/README.md new file mode 100644 index 0000000000..d940cfc0cc --- /dev/null +++ b/experimental/packages/api-logs/README.md @@ -0,0 +1,66 @@ +# OpenTelemetry API for JavaScript + +[![NPM Published Version][npm-img]][npm-url] +[![Apache License][license-image]][license-image] + +This package provides everything needed to interact with the unstable OpenTelemetry Logs API, including all TypeScript interfaces, enums, and no-op implementations. It is intended for use both on the server and in the browser. + +## Beta Software - Use at your own risk + +The logs API is considered alpha software and there is no guarantee of stability or long-term support. When the API is stabilized, it will be made available and supported long-term in the `@opentelemetry/api` package and this package will be deprecated. + +## Quick Start + +Purposefully left blank until SDK is available. + +## Version Compatibility + +Because the npm installer and node module resolution algorithm could potentially allow two or more copies of any given package to exist within the same `node_modules` structure, the OpenTelemetry API takes advantage of a variable on the `global` object to store the global API. When an API method in the API package is called, it checks if this `global` API exists and proxies calls to it if and only if it is a compatible API version. This means if a package has a dependency on an OpenTelemetry API version which is not compatible with the API used by the end user, the package will receive a no-op implementation of the API. + +## Advanced Use + +### API Methods + +If you are writing an instrumentation library, or prefer to call the API methods directly rather than using the `register` method on the Tracer/Meter/Logger Provider, OpenTelemetry provides direct access to the underlying API methods through the `@opentelemetry/api-logs` package. API entry points are defined as global singleton objects `trace`, `metrics`, `logs`, `propagation`, and `context` which contain methods used to initialize SDK implementations and acquire resources from the API. + +- [Logs API Documentation][logs-api-docs] + +```javascript +const api = require("@opentelemetry/api-logs"); + +/* A specific implementation of LoggerProvider comes from an SDK */ +const loggerProvider = createLoggerProvider(); + +/* Initialize LoggerProvider */ +api.logs.setGlobalLoggerProvider(loggerProvider); +/* returns loggerProvider (no-op if a working provider has not been initialized) */ +api.logs.getLoggerProvider(); +/* returns a logger from the registered global logger provider (no-op if a working provider has not been initialized) */ +const logger = api.logs.getLogger(name, version); + +// logging an event in an instrumentation library +logger.emitEvent({ name: 'event-name', domain: 'event-domain' }); + +// logging an event in a log appender +logger.emitLogRecord({ severityNumber: 1, body: 'log data' }); +``` + +## Useful links + +- For more information on OpenTelemetry, visit: +- For more about OpenTelemetry JavaScript: +- For help or feedback on this project, join us in [GitHub Discussions][discussions-url] + +## License + +Apache 2.0 - See [LICENSE][license-url] for more information. + +[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions +[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE +[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat +[npm-url]: https://www.npmjs.com/package/@opentelemetry/api-metrics +[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi-metrics.svg + +[metrics-api-docs]: https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api_metrics.html + +[other-tracing-backends]: https://github.com/open-telemetry/opentelemetry-js#trace-exporters diff --git a/experimental/packages/api-logs/karma.conf.js b/experimental/packages/api-logs/karma.conf.js new file mode 100644 index 0000000000..6174839d65 --- /dev/null +++ b/experimental/packages/api-logs/karma.conf.js @@ -0,0 +1,24 @@ +/*! + * 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 + * + * 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. + */ + +const karmaWebpackConfig = require('../../../karma.webpack'); +const karmaBaseConfig = require('../../../karma.base'); + +module.exports = (config) => { + config.set(Object.assign({}, karmaBaseConfig, { + webpack: karmaWebpackConfig + })) +}; diff --git a/experimental/packages/api-logs/package.json b/experimental/packages/api-logs/package.json new file mode 100644 index 0000000000..91a2ac61f0 --- /dev/null +++ b/experimental/packages/api-logs/package.json @@ -0,0 +1,87 @@ +{ + "name": "@opentelemetry/api-logs", + "version": "0.32.0", + "description": "Public logs API for OpenTelemetry", + "main": "build/src/index.js", + "module": "build/esm/index.js", + "esnext": "build/esnext/index.js", + "types": "build/src/index.d.ts", + "browser": { + "./src/platform/index.ts": "./src/platform/browser/index.ts", + "./build/esm/platform/index.js": "./build/esm/platform/browser/index.js", + "./build/esnext/platform/index.js": "./build/esnext/platform/browser/index.js", + "./build/src/platform/index.js": "./build/src/platform/browser/index.js" + }, + "repository": "open-telemetry/opentelemetry-js", + "scripts": { + "prepublishOnly": "npm run compile", + "compile": "tsc --build tsconfig.all.json", + "clean": "tsc --build --clean tsconfig.all.json", + "test": "nyc ts-mocha -p tsconfig.json test/**/*.test.ts", + "test:browser": "nyc karma start --single-run", + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../../", + "codecov:browser": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../../", + "build": "npm run compile", + "lint": "eslint . --ext .ts", + "lint:fix": "eslint . --ext .ts --fix", + "version": "node ../../../scripts/version-update.js", + "watch": "tsc --build --watch tsconfig.all.json", + "precompile": "lerna run version --scope $(npm pkg get name) --include-dependencies", + "prewatch": "node ../../../scripts/version-update.js" + }, + "keywords": [ + "opentelemetry", + "nodejs", + "browser", + "profiling", + "logs", + "events", + "stats", + "monitoring" + ], + "author": "OpenTelemetry Authors", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "files": [ + "build/esm/**/*.js", + "build/esm/**/*.js.map", + "build/esm/**/*.d.ts", + "build/esnext/**/*.js", + "build/esnext/**/*.js.map", + "build/esnext/**/*.d.ts", + "build/src/**/*.js", + "build/src/**/*.js.map", + "build/src/**/*.d.ts", + "doc", + "LICENSE", + "README.md" + ], + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "devDependencies": { + "@types/mocha": "9.1.1", + "@types/node": "18.6.5", + "@types/webpack-env": "1.16.3", + "codecov": "3.8.3", + "istanbul-instrumenter-loader": "3.0.1", + "karma": "6.3.16", + "karma-chrome-launcher": "3.1.0", + "karma-coverage-istanbul-reporter": "3.0.3", + "karma-mocha": "2.0.1", + "karma-spec-reporter": "0.0.32", + "karma-webpack": "4.0.2", + "mocha": "10.0.0", + "nyc": "15.1.0", + "ts-loader": "8.4.0", + "ts-mocha": "10.0.0", + "typescript": "4.4.4", + "webpack": "4.46.0" + }, + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/api-logs" +} diff --git a/experimental/packages/api-logs/src/NoopLogger.ts b/experimental/packages/api-logs/src/NoopLogger.ts new file mode 100644 index 0000000000..3f2227154c --- /dev/null +++ b/experimental/packages/api-logs/src/NoopLogger.ts @@ -0,0 +1,24 @@ +/* + * 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 { Logger } from './types/Logger'; +import { LogEvent } from './types/LogEvent'; +import { LogRecord } from './types/LogRecord'; + +export class NoopLogger implements Logger { + emitLogRecord(_logRecord: LogRecord): void {} + emitEvent(_event: LogEvent): void {} +} diff --git a/experimental/packages/api-logs/src/NoopLoggerProvider.ts b/experimental/packages/api-logs/src/NoopLoggerProvider.ts new file mode 100644 index 0000000000..5c69e5a7bd --- /dev/null +++ b/experimental/packages/api-logs/src/NoopLoggerProvider.ts @@ -0,0 +1,28 @@ +/* + * 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 { LoggerProvider } from './types/LoggerProvider'; +import { Logger } from './types/Logger'; +import { LoggerOptions } from './types/LoggerOptions'; +import { NoopLogger } from './NoopLogger'; + +export class NoopLoggerProvider implements LoggerProvider { + getLogger(_name: string, _version?: string | undefined, _options?: LoggerOptions | undefined): Logger { + return new NoopLogger(); + } +} + +export const NOOP_LOGGER_PROVIDER = new NoopLoggerProvider(); diff --git a/experimental/packages/api-logs/src/api/logs.ts b/experimental/packages/api-logs/src/api/logs.ts new file mode 100644 index 0000000000..0f9388648a --- /dev/null +++ b/experimental/packages/api-logs/src/api/logs.ts @@ -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 { + API_BACKWARDS_COMPATIBILITY_VERSION, + GLOBAL_LOGS_API_KEY, + _global, + makeGetter +} from '../internal/global-utils'; +import { LoggerProvider } from '../types/LoggerProvider'; +import { NOOP_LOGGER_PROVIDER } from '../NoopLoggerProvider'; +import { Logger } from '../types/Logger'; +import { LoggerOptions } from '../types/LoggerOptions'; + +export class LogsAPI { + private static _instance?: LogsAPI; + + private constructor() {} + + public static getInstance(): LogsAPI { + if (!this._instance) { + this._instance = new LogsAPI(); + } + + return this._instance; + } + + public setGlobalLoggerProvider(provider: LoggerProvider): LoggerProvider { + if (_global[GLOBAL_LOGS_API_KEY]) { + return this.getLoggerProvider(); + } + + _global[GLOBAL_LOGS_API_KEY] = makeGetter( + API_BACKWARDS_COMPATIBILITY_VERSION, + provider, + NOOP_LOGGER_PROVIDER + ); + + return provider; + } + + /** + * Returns the global logger provider. + * + * @returns LoggerProvider + */ + public getLoggerProvider(): LoggerProvider { + return ( + _global[GLOBAL_LOGS_API_KEY]?.(API_BACKWARDS_COMPATIBILITY_VERSION) ?? + NOOP_LOGGER_PROVIDER + ); + } + + /** + * Returns a logger from the global logger provider. + * + * @returns Logger + */ + public getLogger(name: string, version?: string, options?: LoggerOptions): Logger { + return this.getLoggerProvider().getLogger(name, version, options); + } + + /** Remove the global logger provider */ + public disable(): void { + delete _global[GLOBAL_LOGS_API_KEY]; + } +} diff --git a/experimental/packages/api-logs/src/index.ts b/experimental/packages/api-logs/src/index.ts new file mode 100644 index 0000000000..cf22a2e5eb --- /dev/null +++ b/experimental/packages/api-logs/src/index.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +export * from './types/Logger'; +export * from './types/LoggerProvider'; +export * from './types/LogRecord'; +export * from './types/LogEvent'; +export * from './types/LoggerOptions'; + +import { LogsAPI } from './api/logs'; +export const logs = LogsAPI.getInstance(); diff --git a/experimental/packages/api-logs/src/internal/global-utils.ts b/experimental/packages/api-logs/src/internal/global-utils.ts new file mode 100644 index 0000000000..705139aeda --- /dev/null +++ b/experimental/packages/api-logs/src/internal/global-utils.ts @@ -0,0 +1,55 @@ +/* + * 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 { LoggerProvider } from '../types/LoggerProvider'; +import { _globalThis } from '../platform'; + +export const GLOBAL_LOGS_API_KEY = Symbol.for( + 'io.opentelemetry.js.api.logs' +); + +type Get = (version: number) => T; +type OtelGlobal = Partial<{ + [GLOBAL_LOGS_API_KEY]: Get; +}>; + +export const _global = _globalThis as OtelGlobal; + +/** + * Make a function which accepts a version integer and returns the instance of an API if the version + * is compatible, or a fallback version (usually NOOP) if it is not. + * + * @param requiredVersion Backwards compatibility version which is required to return the instance + * @param instance Instance which should be returned if the required version is compatible + * @param fallback Fallback instance, usually NOOP, which will be returned if the required version is not compatible + */ +export function makeGetter( + requiredVersion: number, + instance: T, + fallback: T +): Get { + return (version: number): T => + version === requiredVersion ? instance : fallback; +} + +/** + * A number which should be incremented each time a backwards incompatible + * change is made to the API. This number is used when an API package + * attempts to access the global API to ensure it is getting a compatible + * version. If the global API is not compatible with the API package + * attempting to get it, a NOOP API implementation will be returned. + */ +export const API_BACKWARDS_COMPATIBILITY_VERSION = 1; diff --git a/experimental/packages/api-logs/src/platform/browser/globalThis.ts b/experimental/packages/api-logs/src/platform/browser/globalThis.ts new file mode 100644 index 0000000000..1dece570f3 --- /dev/null +++ b/experimental/packages/api-logs/src/platform/browser/globalThis.ts @@ -0,0 +1,35 @@ +/* + * 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. + */ + +// Updates to this file should also be replicated to @opentelemetry/api and +// @opentelemetry/core too. + +/** + * - globalThis (New standard) + * - self (Will return the current window instance for supported browsers) + * - window (fallback for older browser implementations) + * - global (NodeJS implementation) + * - (When all else fails) + */ + +/** only globals that common to node and browsers are allowed */ +// eslint-disable-next-line node/no-unsupported-features/es-builtins, no-undef +export const _globalThis: typeof globalThis = + typeof globalThis === 'object' ? globalThis : + typeof self === 'object' ? self : + typeof window === 'object' ? window : + typeof global === 'object' ? global : + {} as typeof globalThis; diff --git a/experimental/packages/api-logs/src/platform/browser/index.ts b/experimental/packages/api-logs/src/platform/browser/index.ts new file mode 100644 index 0000000000..e9d6ebed71 --- /dev/null +++ b/experimental/packages/api-logs/src/platform/browser/index.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './globalThis'; diff --git a/experimental/packages/api-logs/src/platform/index.ts b/experimental/packages/api-logs/src/platform/index.ts new file mode 100644 index 0000000000..cdaf8858ce --- /dev/null +++ b/experimental/packages/api-logs/src/platform/index.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './node'; diff --git a/experimental/packages/api-logs/src/platform/node/globalThis.ts b/experimental/packages/api-logs/src/platform/node/globalThis.ts new file mode 100644 index 0000000000..36e97e2732 --- /dev/null +++ b/experimental/packages/api-logs/src/platform/node/globalThis.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ + +/** only globals that common to node and browsers are allowed */ +// eslint-disable-next-line node/no-unsupported-features/es-builtins +export const _globalThis = typeof globalThis === 'object' ? globalThis : global; diff --git a/experimental/packages/api-logs/src/platform/node/index.ts b/experimental/packages/api-logs/src/platform/node/index.ts new file mode 100644 index 0000000000..e9d6ebed71 --- /dev/null +++ b/experimental/packages/api-logs/src/platform/node/index.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './globalThis'; diff --git a/experimental/packages/api-logs/src/types/LogEvent.ts b/experimental/packages/api-logs/src/types/LogEvent.ts new file mode 100644 index 0000000000..7b37572c6c --- /dev/null +++ b/experimental/packages/api-logs/src/types/LogEvent.ts @@ -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 { Attributes } from '@opentelemetry/api'; + +export interface LogEvent { + /** + * The time when the event occurred as UNIX Epoch time in nanoseconds. + */ + timestamp?: number; + + /** + * The name of the event. + */ + name: string; + + /** + * The domain the event belongs to. + */ + domain?: string; + + /** + * Additional attributes that describe the event. + */ + attributes?: Attributes; + + /** + * 8 least significant bits are the trace flags as defined in W3C Trace Context specification. + */ + traceFlags?: number; + + /** + * A unique identifier for a trace. + */ + traceId?: string; + + /** + * A unique identifier for a span within a trace. + */ + spanId?: string; +} diff --git a/experimental/packages/api-logs/src/types/LogRecord.ts b/experimental/packages/api-logs/src/types/LogRecord.ts new file mode 100644 index 0000000000..132900c54a --- /dev/null +++ b/experimental/packages/api-logs/src/types/LogRecord.ts @@ -0,0 +1,59 @@ +/* + * 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 { Attributes } from '@opentelemetry/api'; + +export interface LogRecord { + /** + * The time when the log record occurred as UNIX Epoch time in nanoseconds. + */ + timestamp?: number; + + /** + * Numerical value of the severity. + */ + severityNumber?: number; + + /** + * The severity text. + */ + severityText?: string; + + /** + * A value containing the body of the log record. + */ + body?: string; + + /** + * Attributes that define the log record. + */ + attributes?: Attributes; + + /** + * 8 least significant bits are the trace flags as defined in W3C Trace Context specification. + */ + traceFlags?: number; + + /** + * A unique identifier for a trace. + */ + traceId?: string; + + /** + * A unique identifier for a span within a trace. + */ + spanId?: string; +} diff --git a/experimental/packages/api-logs/src/types/Logger.ts b/experimental/packages/api-logs/src/types/Logger.ts new file mode 100644 index 0000000000..b30f3aff93 --- /dev/null +++ b/experimental/packages/api-logs/src/types/Logger.ts @@ -0,0 +1,34 @@ +/* + * 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 { LogRecord } from './LogRecord'; +import { LogEvent } from './LogEvent'; + +export interface Logger { + /** + * Emit a log record. This method should only be used by log appenders. + * + * @param logRecord + */ + emitLogRecord(logRecord: LogRecord): void; + + /** + * Emit an event. This method should only be used by instrumentations emitting events. + * + * @param event + */ + emitEvent(event: LogEvent): void; +} diff --git a/experimental/packages/api-logs/src/types/LoggerOptions.ts b/experimental/packages/api-logs/src/types/LoggerOptions.ts new file mode 100644 index 0000000000..9b2fe06fc8 --- /dev/null +++ b/experimental/packages/api-logs/src/types/LoggerOptions.ts @@ -0,0 +1,42 @@ +/* + * 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 { Attributes } from '@opentelemetry/api'; + +export interface LoggerOptions { + /** + * The schemaUrl of the tracer or instrumentation library + * @default '' + */ + schemaUrl?: string; + + /** + * The default domain for events created by the Logger. + * + * The combination of event name and event domain uiquely identifies an event. + * By supplying an event domain, it is possible to use the same event name across + * different domains / use cases. + * + * The default domain can be overridden when emitting an individual event. + * @default '' + */ + eventDomain?: string; + + /** + * The instrumentation scope attributes to associate with emitted telemetry + */ + scopeAttributes?: Attributes; +} diff --git a/experimental/packages/api-logs/src/types/LoggerProvider.ts b/experimental/packages/api-logs/src/types/LoggerProvider.ts new file mode 100644 index 0000000000..e79aa1ce09 --- /dev/null +++ b/experimental/packages/api-logs/src/types/LoggerProvider.ts @@ -0,0 +1,34 @@ +/* + * 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 { Logger } from './Logger'; +import { LoggerOptions } from './LoggerOptions'; + +/** + * A registry for creating named {@link Logger}s. + */ +export interface LoggerProvider { + /** + * Returns a Logger, creating one if one with the given name, version, and + * schemaUrl pair is not already created. + * + * @param name The name of the logger or instrumentation library. + * @param version The version of the logger or instrumentation library. + * @param options The options of the logger or instrumentation library. + * @returns Logger A Logger with the given name and version + */ + getLogger(name: string, version?: string, options?: LoggerOptions): Logger; +} diff --git a/experimental/packages/api-logs/test/api/api.test.ts b/experimental/packages/api-logs/test/api/api.test.ts new file mode 100644 index 0000000000..3548e08184 --- /dev/null +++ b/experimental/packages/api-logs/test/api/api.test.ts @@ -0,0 +1,69 @@ +/* + * 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 { Logger, logs } from '../../src'; +import { NoopLogger } from '../../src/NoopLogger'; +import { NoopLoggerProvider } from '../../src/NoopLoggerProvider'; + +describe('API', () => { + const dummyLogger = new NoopLogger(); + + it('should expose a logger provider via getLoggerProvider', () => { + const provider = logs.getLoggerProvider(); + assert.ok(provider); + assert.strictEqual(typeof provider, 'object'); + }); + + describe('GlobalLoggerProvider', () => { + beforeEach(() => { + logs.disable(); + }); + + it('should use the global logger provider', () => { + logs.setGlobalLoggerProvider(new TestLoggerProvider()); + const logger = logs.getLoggerProvider().getLogger('name'); + assert.deepStrictEqual(logger, dummyLogger); + }); + + it('should not allow overriding global provider if already set', () => { + const provider1 = new TestLoggerProvider(); + const provider2 = new TestLoggerProvider(); + logs.setGlobalLoggerProvider(provider1); + assert.equal(logs.getLoggerProvider(), provider1); + logs.setGlobalLoggerProvider(provider2); + assert.equal(logs.getLoggerProvider(), provider1); + }); + }); + + describe('getLogger', () => { + beforeEach(() => { + logs.disable(); + }); + + it('should return a logger instance from global provider', () => { + logs.setGlobalLoggerProvider(new TestLoggerProvider()); + const logger = logs.getLogger('myLogger'); + assert.deepStrictEqual(logger, dummyLogger); + }); + }); + + class TestLoggerProvider extends NoopLoggerProvider { + override getLogger(): Logger { + return dummyLogger; + } + } +}); diff --git a/experimental/packages/api-logs/test/index-webpack.ts b/experimental/packages/api-logs/test/index-webpack.ts new file mode 100644 index 0000000000..061a48ccfa --- /dev/null +++ b/experimental/packages/api-logs/test/index-webpack.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ +const testsContext = require.context('.', true, /test$/); +testsContext.keys().forEach(testsContext); + +const srcContext = require.context('.', true, /src$/); +srcContext.keys().forEach(srcContext); diff --git a/experimental/packages/api-logs/test/internal/global.test.ts b/experimental/packages/api-logs/test/internal/global.test.ts new file mode 100644 index 0000000000..8ac9c48cf3 --- /dev/null +++ b/experimental/packages/api-logs/test/internal/global.test.ts @@ -0,0 +1,76 @@ +/* + * 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 { _global, GLOBAL_LOGS_API_KEY } from '../../src/internal/global-utils'; +import { NoopLoggerProvider } from '../../src/NoopLoggerProvider'; + +const api1 = require('../../src') as typeof import('../../src'); + +// clear cache and load a second instance of the api +for (const key of Object.keys(require.cache)) { + delete require.cache[key]; +} +const api2 = require('../../src') as typeof import('../../src'); + +describe('Global Utils', () => { + // prove they are separate instances + assert.notStrictEqual(api1, api2); + // that return separate noop instances to start + assert.notStrictEqual( + api1.logs.getLoggerProvider(), + api2.logs.getLoggerProvider() + ); + + beforeEach(() => { + api1.logs.disable(); + api2.logs.disable(); + }); + + it('should change the global logger provider', () => { + const original = api1.logs.getLoggerProvider(); + const newLoggerProvider = new NoopLoggerProvider(); + api1.logs.setGlobalLoggerProvider(newLoggerProvider); + assert.notStrictEqual(api1.logs.getLoggerProvider(), original); + assert.strictEqual(api1.logs.getLoggerProvider(), newLoggerProvider); + }); + + it('should load an instance from one which was set in the other', () => { + api1.logs.setGlobalLoggerProvider(new NoopLoggerProvider()); + assert.strictEqual( + api1.logs.getLoggerProvider(), + api2.logs.getLoggerProvider() + ); + }); + + it('should disable both if one is disabled', () => { + const original = api1.logs.getLoggerProvider(); + + api1.logs.setGlobalLoggerProvider(new NoopLoggerProvider()); + + assert.notStrictEqual(original, api1.logs.getLoggerProvider()); + api2.logs.disable(); + assert.strictEqual(original, api1.logs.getLoggerProvider()); + }); + + it('should return the module NoOp implementation if the version is a mismatch', () => { + const original = api1.logs.getLoggerProvider(); + api1.logs.setGlobalLoggerProvider(new NoopLoggerProvider()); + const afterSet = _global[GLOBAL_LOGS_API_KEY]!(-1); + + assert.strictEqual(original, afterSet); + }); +}); diff --git a/experimental/packages/api-logs/test/noop-implementations/noop-logger-provider.test.ts b/experimental/packages/api-logs/test/noop-implementations/noop-logger-provider.test.ts new file mode 100644 index 0000000000..e696c77b01 --- /dev/null +++ b/experimental/packages/api-logs/test/noop-implementations/noop-logger-provider.test.ts @@ -0,0 +1,31 @@ +/* + * 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 { NoopLogger } from '../../src/NoopLogger'; +import { NoopLoggerProvider } from '../../src/NoopLoggerProvider'; + +describe('NoopLoggerProvider', () => { + it('should not crash', () => { + const loggerProvider = new NoopLoggerProvider(); + + assert.ok(loggerProvider.getLogger('logger-name') instanceof NoopLogger); + assert.ok(loggerProvider.getLogger('logger-name', 'v1') instanceof NoopLogger); + assert.ok(loggerProvider.getLogger('logger-name', 'v1', { + schemaUrl: 'https://opentelemetry.io/schemas/1.7.0' + }) instanceof NoopLogger); + }); +}); diff --git a/experimental/packages/api-logs/test/noop-implementations/noop-logger.test.ts b/experimental/packages/api-logs/test/noop-implementations/noop-logger.test.ts new file mode 100644 index 0000000000..6360e7b7dd --- /dev/null +++ b/experimental/packages/api-logs/test/noop-implementations/noop-logger.test.ts @@ -0,0 +1,36 @@ +/* + * 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 { NoopLogger } from '../../src/NoopLogger'; +import { NoopLoggerProvider } from '../../src/NoopLoggerProvider'; + +describe('NoopLogger', () => { + it('constructor should not crash', () => { + const logger = new NoopLoggerProvider().getLogger('test-noop'); + assert(logger instanceof NoopLogger); + }); + + it('calling emitEvent should not crash', () => { + const logger = new NoopLoggerProvider().getLogger('test-noop'); + logger.emitEvent({ name: 'event-name', domain: 'event-domain' }); + }); + + it('calling emitLogRecord should not crash', () => { + const logger = new NoopLoggerProvider().getLogger('test-noop'); + logger.emitLogRecord({ severityNumber: 1, body: 'log body' }); + }); +}); diff --git a/experimental/packages/api-logs/tsconfig.all.json b/experimental/packages/api-logs/tsconfig.all.json new file mode 100644 index 0000000000..06c5491334 --- /dev/null +++ b/experimental/packages/api-logs/tsconfig.all.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "references": [ + { "path": "./tsconfig.json" }, + { "path": "./tsconfig.esm.json" }, + { "path": "./tsconfig.esnext.json" } + ] +} diff --git a/experimental/packages/api-logs/tsconfig.docs.json b/experimental/packages/api-logs/tsconfig.docs.json new file mode 100644 index 0000000000..18c131e2b9 --- /dev/null +++ b/experimental/packages/api-logs/tsconfig.docs.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "rootDir": ".", + "outDir": "build" + }, + "include": [ + "src/**/*.ts" + ], + "typedocOptions": { + "name": "OpenTelemetry Logs API for JavaScript", + "out": "docs/out", + "mode": "file", + "hideGenerator": true + } +} diff --git a/experimental/packages/api-logs/tsconfig.esm.json b/experimental/packages/api-logs/tsconfig.esm.json new file mode 100644 index 0000000000..379f547a46 --- /dev/null +++ b/experimental/packages/api-logs/tsconfig.esm.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.base.esm.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build/esm", + "tsBuildInfoFile": "build/esm/tsconfig.esm.tsbuildinfo" + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/experimental/packages/api-logs/tsconfig.esnext.json b/experimental/packages/api-logs/tsconfig.esnext.json new file mode 100644 index 0000000000..cb78dd6ff3 --- /dev/null +++ b/experimental/packages/api-logs/tsconfig.esnext.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.base.esnext.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build/esnext", + "tsBuildInfoFile": "build/esnext/tsconfig.esnext.tsbuildinfo" + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/experimental/packages/api-logs/tsconfig.json b/experimental/packages/api-logs/tsconfig.json new file mode 100644 index 0000000000..ed9d0830bd --- /dev/null +++ b/experimental/packages/api-logs/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "build" + }, + "include": [ + "src/**/*.ts", + "test/**/*.ts" + ] +} diff --git a/tsconfig.json b/tsconfig.json index cdbf4c4272..4e977f5424 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -88,6 +88,9 @@ { "path": "packages/template" }, + { + "path": "experimental/packages/api-logs" + }, { "path": "experimental/packages/exporter-trace-otlp-grpc" }, From 32cb123690c43c4226b4b907168070a1c6e707cc Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 8 Sep 2022 16:06:46 -0400 Subject: [PATCH 12/77] Add metrics packages to generated docs (#3239) --- CHANGELOG.md | 4 +++- tsconfig.json | 16 +++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48de348db0..cbada38319 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,13 +12,15 @@ All notable changes to this project will be documented in this file. ### :books: (Refine Doc) +* docs(metrics): add missing metrics packages to SDK reference documentation [#3239](https://github.com/open-telemetry/opentelemetry-js/pull/3239) @dyladan + ### :house: (Internal) ## 1.6.0 ### :rocket: (Enhancement) -* perf(opentelemetry-core): improve hexToBase64 performance [#3178](https://github.com/open-telemetry/opentelemetry-js/pull/3178) +* perf(opentelemetry-core): improve hexToBase64 performance [#3178](https://github.com/open-telemetry/opentelemetry-js/pull/3178) @seemk * feat(sdk-trace-base): move Sampler declaration into sdk-trace-base [#3088](https://github.com/open-telemetry/opentelemetry-js/pull/3088) @legendecas * fix(grpc-instrumentation): added grpc attributes in instrumentation [#3127](https://github.com/open-telemetry/opentelemetry-js/pull/3127) @andrewzenkov * feat: support latest `@opentelemetry/api` [#3177](https://github.com/open-telemetry/opentelemetry-js/pull/3177) @dyladan diff --git a/tsconfig.json b/tsconfig.json index 4e977f5424..9f3cd60df8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,22 +4,28 @@ "typedocOptions": { "entryPointStrategy": "packages", "entryPoints": [ + "experimental/packages/exporter-trace-otlp-grpc", + "experimental/packages/exporter-trace-otlp-http", + "experimental/packages/exporter-trace-otlp-proto", + "experimental/packages/opentelemetry-api-metrics", "experimental/packages/opentelemetry-exporter-metrics-otlp-grpc", "experimental/packages/opentelemetry-exporter-metrics-otlp-http", "experimental/packages/opentelemetry-exporter-metrics-otlp-proto", "experimental/packages/opentelemetry-exporter-prometheus", - "experimental/packages/opentelemetry-instrumentation", "experimental/packages/opentelemetry-instrumentation-fetch", "experimental/packages/opentelemetry-instrumentation-grpc", "experimental/packages/opentelemetry-instrumentation-http", "experimental/packages/opentelemetry-instrumentation-xml-http-request", + "experimental/packages/opentelemetry-instrumentation", + "experimental/packages/opentelemetry-sdk-metrics", "experimental/packages/opentelemetry-sdk-node", - "packages/exporter-trace-otlp-grpc", - "packages/exporter-trace-otlp-http", - "packages/exporter-trace-otlp-proto", + "experimental/packages/otlp-exporter-base", + "experimental/packages/otlp-grpc-exporter-base", + "experimental/packages/otlp-proto-exporter-base", + "experimental/packages/otlp-transformer", "packages/opentelemetry-context-async-hooks", - "packages/opentelemetry-context-zone", "packages/opentelemetry-context-zone-peer-dep", + "packages/opentelemetry-context-zone", "packages/opentelemetry-core", "packages/opentelemetry-exporter-jaeger", "packages/opentelemetry-exporter-zipkin", From 58181296319099042cc1860a70f572a7a475435a Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Sat, 10 Sep 2022 05:39:40 -0400 Subject: [PATCH 13/77] feat: anchored clock (#3134) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marc Pichler Co-authored-by: Gerhard Stöbich --- CHANGELOG.md | 3 + .../src/common/anchored-clock.ts | 67 +++++++++++++++++++ packages/opentelemetry-core/src/index.ts | 1 + .../test/common/anchored-clock.test.ts | 29 ++++++++ .../opentelemetry-sdk-trace-base/src/Span.ts | 37 ++++++---- .../src/Tracer.ts | 35 +++++++--- 6 files changed, 150 insertions(+), 22 deletions(-) create mode 100644 packages/opentelemetry-core/src/common/anchored-clock.ts create mode 100644 packages/opentelemetry-core/test/common/anchored-clock.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index cbada38319..7633d06998 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ All notable changes to this project will be documented in this file. ### :bug: (Bug Fix) +* fix(sdk-trace-base): make span start times resistant to hrtime clock drift + [#3129](https://github.com/open-telemetry/opentelemetry-js/issues/3129) + ### :books: (Refine Doc) * docs(metrics): add missing metrics packages to SDK reference documentation [#3239](https://github.com/open-telemetry/opentelemetry-js/pull/3239) @dyladan diff --git a/packages/opentelemetry-core/src/common/anchored-clock.ts b/packages/opentelemetry-core/src/common/anchored-clock.ts new file mode 100644 index 0000000000..a47fe796b7 --- /dev/null +++ b/packages/opentelemetry-core/src/common/anchored-clock.ts @@ -0,0 +1,67 @@ +/* + * 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. + */ + +export interface Clock { + /** + * Return the current time in milliseconds from some epoch such as the Unix epoch or process start + */ + now(): number; +} + + +/** + * A utility for returning wall times anchored to a given point in time. Wall time measurements will + * not be taken from the system, but instead are computed by adding a monotonic clock time + * to the anchor point. + * + * This is needed because the system time can change and result in unexpected situations like + * spans ending before they are started. Creating an anchored clock for each local root span + * ensures that span timings and durations are accurate while preventing span times from drifting + * too far from the system clock. + * + * Only creating an anchored clock once per local trace ensures span times are correct relative + * to each other. For example, a child span will never have a start time before its parent even + * if the system clock is corrected during the local trace. + * + * Heavily inspired by the OTel Java anchored clock + * https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/AnchoredClock.java + */ +export class AnchoredClock implements Clock { + private _monotonicClock: Clock; + private _epochMillis: number; + private _performanceMillis: number; + + /** + * Create a new AnchoredClock anchored to the current time returned by systemClock. + * + * @param systemClock should be a clock that returns the number of milliseconds since January 1 1970 such as Date + * @param monotonicClock should be a clock that counts milliseconds monotonically such as window.performance or perf_hooks.performance + */ + public constructor(systemClock: Clock, monotonicClock: Clock) { + this._monotonicClock = monotonicClock; + this._epochMillis = systemClock.now(); + this._performanceMillis = monotonicClock.now(); + } + + /** + * Returns the current time by adding the number of milliseconds since the + * AnchoredClock was created to the creation epoch time + */ + public now(): number { + const delta = this._monotonicClock.now() - this._performanceMillis; + return this._epochMillis + delta; + } +} diff --git a/packages/opentelemetry-core/src/index.ts b/packages/opentelemetry-core/src/index.ts index 9316774752..fd8d3c6778 100644 --- a/packages/opentelemetry-core/src/index.ts +++ b/packages/opentelemetry-core/src/index.ts @@ -15,6 +15,7 @@ */ export * from './baggage/propagation/W3CBaggagePropagator'; +export * from './common/anchored-clock'; export * from './common/attributes'; export * from './common/global-error-handler'; export * from './common/logging-error-handler'; diff --git a/packages/opentelemetry-core/test/common/anchored-clock.test.ts b/packages/opentelemetry-core/test/common/anchored-clock.test.ts new file mode 100644 index 0000000000..44f45be35c --- /dev/null +++ b/packages/opentelemetry-core/test/common/anchored-clock.test.ts @@ -0,0 +1,29 @@ +/* + * 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 assert = require('assert'); +import { AnchoredClock, otperformance } from '../../src'; + +describe('AnchoredClock', () => { + it('should keep time', done => { + const clock = new AnchoredClock(Date, otperformance); + setTimeout(() => { + // after about 100ms, the clocks are within 10ms of each other + assert.ok(Math.abs(Date.now() - clock.now()) < 10); + done(); + }, 100); + }); +}); diff --git a/packages/opentelemetry-sdk-trace-base/src/Span.ts b/packages/opentelemetry-sdk-trace-base/src/Span.ts index 00859d7d55..fe0b0d0470 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Span.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Span.ts @@ -15,24 +15,25 @@ */ import * as api from '@opentelemetry/api'; +import { Context, SpanAttributeValue } from '@opentelemetry/api'; import { - isAttributeValue, - hrTime, + Clock, hrTimeDuration, InstrumentationLibrary, + isAttributeValue, isTimeInput, - timeInputToHrTime, + otperformance, sanitizeAttributes, + timeInputToHrTime } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; +import { ExceptionEventName } from './enums'; import { ReadableSpan } from './export/ReadableSpan'; +import { SpanProcessor } from './SpanProcessor'; import { TimedEvent } from './TimedEvent'; import { Tracer } from './Tracer'; -import { SpanProcessor } from './SpanProcessor'; import { SpanLimits } from './types'; -import { SpanAttributeValue, Context } from '@opentelemetry/api'; -import { ExceptionEventName } from './enums'; /** * This class represents a span. @@ -59,8 +60,13 @@ export class Span implements api.Span, ReadableSpan { private readonly _spanProcessor: SpanProcessor; private readonly _spanLimits: SpanLimits; private readonly _attributeValueLengthLimit: number; + private readonly _clock: Clock; - /** Constructs a new Span instance. */ + /** + * Constructs a new Span instance. + * + * @deprecated calling Span constructor directly is not supported. Please use tracer.startSpan. + * */ constructor( parentTracer: Tracer, context: Context, @@ -69,14 +75,16 @@ export class Span implements api.Span, ReadableSpan { kind: api.SpanKind, parentSpanId?: string, links: api.Link[] = [], - startTime: api.TimeInput = hrTime() + startTime?: api.TimeInput, + clock: Clock = otperformance, ) { + this._clock = clock; this.name = spanName; this._spanContext = spanContext; this.parentSpanId = parentSpanId; this.kind = kind; this.links = links; - this.startTime = timeInputToHrTime(startTime); + this.startTime = timeInputToHrTime(startTime ?? clock.now()); this.resource = parentTracer.resource; this.instrumentationLibrary = parentTracer.instrumentationLibrary; this._spanLimits = parentTracer.getSpanLimits(); @@ -103,7 +111,7 @@ export class Span implements api.Span, ReadableSpan { if ( Object.keys(this.attributes).length >= - this._spanLimits.attributeCountLimit! && + this._spanLimits.attributeCountLimit! && !Object.prototype.hasOwnProperty.call(this.attributes, key) ) { return this; @@ -147,7 +155,7 @@ export class Span implements api.Span, ReadableSpan { attributesOrStartTime = undefined; } if (typeof startTime === 'undefined') { - startTime = hrTime(); + startTime = this._clock.now(); } const attributes = sanitizeAttributes(attributesOrStartTime); @@ -171,15 +179,16 @@ export class Span implements api.Span, ReadableSpan { return this; } - end(endTime: api.TimeInput = hrTime()): void { + end(endTime?: api.TimeInput): void { if (this._isSpanEnded()) { api.diag.error('You can only call end() on a span once.'); return; } this._ended = true; - this.endTime = timeInputToHrTime(endTime); + this.endTime = timeInputToHrTime(endTime ?? this._clock.now()); this._duration = hrTimeDuration(this.startTime, this.endTime); + if (this._duration[0] < 0) { api.diag.warn( 'Inconsistent start and end time, startTime > endTime', @@ -195,7 +204,7 @@ export class Span implements api.Span, ReadableSpan { return this._ended === false; } - recordException(exception: api.Exception, time: api.TimeInput = hrTime()): void { + recordException(exception: api.Exception, time: api.TimeInput = this._clock.now()): void { const attributes: api.SpanAttributes = {}; if (typeof exception === 'string') { attributes[SemanticAttributes.EXCEPTION_MESSAGE] = exception; diff --git a/packages/opentelemetry-sdk-trace-base/src/Tracer.ts b/packages/opentelemetry-sdk-trace-base/src/Tracer.ts index b77b5346b5..4af02e2494 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Tracer.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Tracer.ts @@ -19,6 +19,8 @@ import { InstrumentationLibrary, sanitizeAttributes, isTracingSuppressed, + AnchoredClock, + otperformance, } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; import { BasicTracerProvider } from './BasicTracerProvider'; @@ -67,17 +69,31 @@ export class Tracer implements api.Tracer { options: api.SpanOptions = {}, context = api.context.active() ): api.Span { - if (isTracingSuppressed(context)) { - api.diag.debug('Instrumentation suppressed, returning Noop Span'); - return api.trace.wrapSpanContext(api.INVALID_SPAN_CONTEXT); - } - // remove span from context in case a root span is requested via options if (options.root) { context = api.trace.deleteSpan(context); } + const parentSpan = api.trace.getSpan(context); + let clock: AnchoredClock | undefined; + if (parentSpan) { + clock = (parentSpan as any)['_clock']; + } + + if (!clock) { + clock = new AnchoredClock(Date, otperformance); + if (parentSpan) { + (parentSpan as any)['_clock'] = clock; + } + } + + if (isTracingSuppressed(context)) { + api.diag.debug('Instrumentation suppressed, returning Noop Span'); + const nonRecordingSpan = api.trace.wrapSpanContext(api.INVALID_SPAN_CONTEXT); + (nonRecordingSpan as any)['_clock'] = clock; + return nonRecordingSpan; + } - const parentSpanContext = api.trace.getSpanContext(context); + const parentSpanContext = parentSpan?.spanContext(); const spanId = this._idGenerator.generateSpanId(); let traceId; let traceState; @@ -117,7 +133,9 @@ export class Tracer implements api.Tracer { const spanContext = { traceId, spanId, traceFlags, traceState }; if (samplingResult.decision === api.SamplingDecision.NOT_RECORD) { api.diag.debug('Recording is off, propagating context in a non-recording span'); - return api.trace.wrapSpanContext(spanContext); + const nonRecordingSpan = api.trace.wrapSpanContext(spanContext); + (nonRecordingSpan as any)['_clock'] = clock; + return nonRecordingSpan; } const span = new Span( @@ -128,7 +146,8 @@ export class Tracer implements api.Tracer { spanKind, parentSpanId, links, - options.startTime + options.startTime, + clock, ); // Set initial span attributes. The attributes object may have been mutated // by the sampler, so we sanitize the merged attributes before setting them. From be24d698f932f681a5f754a8920c71dc111e5e64 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Mon, 12 Sep 2022 15:34:25 +0200 Subject: [PATCH 14/77] chore(sdk-metrics): remove accidental export of the SDK Meter class (#3243) --- experimental/CHANGELOG.md | 1 + experimental/packages/opentelemetry-sdk-metrics/src/index.ts | 4 ---- .../opentelemetry-sdk-metrics/test/MeterProvider.test.ts | 3 ++- .../test/state/MeterSharedState.test.ts | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 9c3307b0b4..9f65421cd2 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -38,6 +38,7 @@ All notable changes to experimental packages in this project will be documented * `NoopObservableMetric` * `NoopObservableUpDownCounterMetric` * `NoopUpDownCounterMetric` +* chore(sdk-metrics): remove accidental export of the SDK `Meter` class [#3243](https://github.com/open-telemetry/opentelemetry-js/pull/3243) @pichlermarc ### :rocket: (Enhancement) diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/index.ts b/experimental/packages/opentelemetry-sdk-metrics/src/index.ts index e5e1ab6ed2..30ce7a09d9 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/index.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/index.ts @@ -67,10 +67,6 @@ export { InstrumentType, } from './InstrumentDescriptor'; -export { - Meter, -} from './Meter'; - export { MeterProvider, MeterProviderOptions, diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts index e8c42bf798..a7e6ac12fb 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts @@ -15,7 +15,7 @@ */ import * as assert from 'assert'; -import { Meter, MeterProvider, InstrumentType, DataPointType } from '../src'; +import { MeterProvider, InstrumentType, DataPointType } from '../src'; import { assertScopeMetrics, assertMetricData, @@ -25,6 +25,7 @@ import { import { TestMetricReader } from './export/TestMetricReader'; import * as sinon from 'sinon'; import { View } from '../src/view/View'; +import { Meter } from '../src/Meter'; describe('MeterProvider', () => { afterEach(() => { diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts index dc7651f83a..21f2dce7fd 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts @@ -17,7 +17,6 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import { - Meter, MeterProvider, DataPointType, View, @@ -29,6 +28,7 @@ import { assertMetricData, defaultInstrumentationScope, defaultResource, sleep } import { TestDeltaMetricReader, TestMetricReader } from '../export/TestMetricReader'; import { MeterSharedState } from '../../src/state/MeterSharedState'; import { CollectionResult } from '../../src/export/MetricData'; +import { Meter } from '../../src/Meter'; describe('MeterSharedState', () => { afterEach(() => { From b73c29dcff65d2c9db9c8f6ccbdaabb14b5622bd Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Mon, 12 Sep 2022 16:31:18 +0200 Subject: [PATCH 15/77] feat(sdk-metrics): align MetricReader with specification and other language implementations (#3225) Co-authored-by: Daniel Dyla --- experimental/CHANGELOG.md | 1 + .../test/metricsHelper.ts | 10 -- .../test/metricsHelper.ts | 10 -- .../test/metricsHelper.ts | 10 -- .../src/PrometheusExporter.ts | 13 +-- .../test/PrometheusSerializer.test.ts | 13 +-- .../src/export/AggregationSelector.ts | 3 + .../src/export/MetricExporter.ts | 9 +- .../src/export/MetricReader.ts | 43 ++++++++- .../export/PeriodicExportingMetricReader.ts | 46 +++------- .../opentelemetry-sdk-metrics/src/index.ts | 1 + .../test/export/MetricReader.test.ts | 47 +++++++++- .../PeriodicExportingMetricReader.test.ts | 92 +++++++++++++++++-- .../test/export/TestMetricReader.ts | 28 +----- .../test/export/utils.ts | 58 ++++++++++++ 15 files changed, 262 insertions(+), 122 deletions(-) create mode 100644 experimental/packages/opentelemetry-sdk-metrics/test/export/utils.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 9f65421cd2..555fe718b3 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -38,6 +38,7 @@ All notable changes to experimental packages in this project will be documented * `NoopObservableMetric` * `NoopObservableUpDownCounterMetric` * `NoopUpDownCounterMetric` +* feat(sdk-metrics): align MetricReader with specification and other language implementations [#3225](https://github.com/open-telemetry/opentelemetry-js/pull/3225) @pichlermarc * chore(sdk-metrics): remove accidental export of the SDK `Meter` class [#3243](https://github.com/open-telemetry/opentelemetry-js/pull/3243) @pichlermarc ### :rocket: (Enhancement) diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts index 0ca7df3226..58922addc3 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts @@ -20,8 +20,6 @@ import * as assert from 'assert'; import * as grpc from '@grpc/grpc-js'; import { VERSION } from '@opentelemetry/core'; import { - Aggregation, - AggregationTemporality, ExplicitBucketHistogramAggregation, MeterProvider, MetricReader, @@ -30,14 +28,6 @@ import { import { IKeyValue, IMetric, IResource } from '@opentelemetry/otlp-transformer'; class TestMetricReader extends MetricReader { - selectAggregation() { - return Aggregation.Default(); - } - - selectAggregationTemporality() { - return AggregationTemporality.CUMULATIVE; - } - protected onForceFlush(): Promise { return Promise.resolve(undefined); } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts index 8cb3811f81..0b15459815 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts @@ -27,8 +27,6 @@ import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; import { InstrumentationScope, VERSION } from '@opentelemetry/core'; import { - Aggregation, - AggregationTemporality, ExplicitBucketHistogramAggregation, MeterProvider, MetricReader, @@ -57,14 +55,6 @@ class TestMetricReader extends MetricReader { protected onShutdown(): Promise { return Promise.resolve(undefined); } - - selectAggregation() { - return Aggregation.Default(); - } - - selectAggregationTemporality() { - return AggregationTemporality.CUMULATIVE; - } } export const HISTOGRAM_AGGREGATION_VIEW = new View({ diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts index 3a69427f90..2f62a8ba2c 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts @@ -24,8 +24,6 @@ import { import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; import { - Aggregation, - AggregationTemporality, ExplicitBucketHistogramAggregation, MeterProvider, MetricReader, @@ -35,14 +33,6 @@ import { IExportMetricsServiceRequest, IKeyValue, IMetric } from '@opentelemetry import { Stream } from 'stream'; export class TestMetricReader extends MetricReader { - selectAggregation() { - return Aggregation.Default(); - } - - selectAggregationTemporality() { - return AggregationTemporality.CUMULATIVE; - } - protected onForceFlush(): Promise { return Promise.resolve(undefined); } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts index 675472ec56..42b051e301 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts @@ -55,7 +55,10 @@ export class PrometheusExporter extends MetricReader { * @param callback Callback to be called after a server was started */ constructor(config: ExporterConfig = {}, callback?: () => void) { - super(); + super({ + aggregationSelector: _instrumentType => Aggregation.Default(), + aggregationTemporalitySelector: _instrumentType => AggregationTemporality.CUMULATIVE + }); this._host = config.host || process.env.OTEL_EXPORTER_PROMETHEUS_HOST || @@ -90,14 +93,6 @@ export class PrometheusExporter extends MetricReader { } } - selectAggregation(): Aggregation { - return Aggregation.Default(); - } - - selectAggregationTemporality(): AggregationTemporality { - return AggregationTemporality.CUMULATIVE; - } - override async onForceFlush(): Promise { /** do nothing */ } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts index 00e082a861..1ae4ab8f53 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts @@ -40,15 +40,10 @@ const attributes = { class TestMetricReader extends MetricReader { constructor() { - super(); - } - - selectAggregationTemporality() { - return AggregationTemporality.CUMULATIVE; - } - - selectAggregation() { - return Aggregation.Default(); + super({ + aggregationTemporalitySelector: _instrumentType => AggregationTemporality.CUMULATIVE, + aggregationSelector: _instrumentType => Aggregation.Default() + }); } async onForceFlush() {} diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts index 8a372d0e74..b0ef5f36ad 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts @@ -27,3 +27,6 @@ export type AggregationSelector = (instrumentType: InstrumentType) => Aggregatio * Aggregation temporality selector based on metric instrument types. */ export type AggregationTemporalitySelector = (instrumentType: InstrumentType) => AggregationTemporality; + +export const DEFAULT_AGGREGATION_SELECTOR: AggregationSelector = _instrumentType => Aggregation.Default(); +export const DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR: AggregationTemporalitySelector = _instrumentType => AggregationTemporality.CUMULATIVE; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts index 782a39ccb8..8e4eb7bd54 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts @@ -20,6 +20,7 @@ import { ExportResult, } from '@opentelemetry/core'; import { InstrumentType } from '../InstrumentDescriptor'; +import { Aggregation } from '../view/Aggregation'; /** * An interface that allows different metric services to export recorded data @@ -44,7 +45,13 @@ export interface PushMetricExporter { * Select the {@link AggregationTemporality} for the given * {@link InstrumentType} for this exporter. */ - selectAggregationTemporality(instrumentType: InstrumentType): AggregationTemporality; + selectAggregationTemporality?(instrumentType: InstrumentType): AggregationTemporality; + + /** + * Select the {@link Aggregation} for the given + * {@link InstrumentType} for this exporter. + */ + selectAggregation?(instrumentType: InstrumentType): Aggregation; /** * Returns a promise which resolves when the last exportation is completed. diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts index 3037384fcf..acf22d46f0 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts @@ -20,8 +20,32 @@ import { MetricProducer } from './MetricProducer'; import { CollectionResult } from './MetricData'; import { callWithTimeout } from '../utils'; import { InstrumentType } from '../InstrumentDescriptor'; -import { CollectionOptions, ForceFlushOptions, ShutdownOptions } from '../types'; +import { + CollectionOptions, + ForceFlushOptions, + ShutdownOptions +} from '../types'; import { Aggregation } from '../view/Aggregation'; +import { + AggregationSelector, + AggregationTemporalitySelector, + DEFAULT_AGGREGATION_SELECTOR, + DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR +} from './AggregationSelector'; + +export interface MetricReaderOptions { + /** + * Aggregation selector based on metric instrument types. If no views are + * configured for a metric instrument, a per-metric-reader aggregation is + * selected with this selector. + */ + aggregationSelector?: AggregationSelector; + /** + * Aggregation temporality selector based on metric instrument types. If + * not configured, cumulative is used for all instruments. + */ + aggregationTemporalitySelector?: AggregationTemporalitySelector; +} /** * A registered reader of metrics that, when linked to a {@link MetricProducer}, offers global @@ -33,6 +57,15 @@ export abstract class MetricReader { private _shutdown = false; // MetricProducer used by this instance. private _metricProducer?: MetricProducer; + private readonly _aggregationTemporalitySelector: AggregationTemporalitySelector; + private readonly _aggregationSelector: AggregationSelector; + + constructor(options?: MetricReaderOptions) { + this._aggregationSelector = options?.aggregationSelector ?? + DEFAULT_AGGREGATION_SELECTOR; + this._aggregationTemporalitySelector = options?.aggregationTemporalitySelector ?? + DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR; + } /** * Set the {@link MetricProducer} used by this instance. @@ -51,13 +84,17 @@ export abstract class MetricReader { * Select the {@link Aggregation} for the given {@link InstrumentType} for this * reader. */ - abstract selectAggregation(instrumentType: InstrumentType): Aggregation; + selectAggregation(instrumentType: InstrumentType): Aggregation { + return this._aggregationSelector(instrumentType); + } /** * Select the {@link AggregationTemporality} for the given * {@link InstrumentType} for this reader. */ - abstract selectAggregationTemporality(instrumentType: InstrumentType): AggregationTemporality; + selectAggregationTemporality(instrumentType: InstrumentType): AggregationTemporality { + return this._aggregationTemporalitySelector(instrumentType); + } /** * Handle once the SDK has initialized this {@link MetricReader} diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts index 4d2206cda0..e4f78d1cf0 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts @@ -21,20 +21,13 @@ import { unrefTimer } from '@opentelemetry/core'; import { MetricReader } from './MetricReader'; -import { AggregationTemporality } from './AggregationTemporality'; -import { InstrumentType } from '../InstrumentDescriptor'; import { PushMetricExporter } from './MetricExporter'; -import { callWithTimeout, TimeoutError } from '../utils'; -import { Aggregation } from '../view/Aggregation'; -import { AggregationSelector } from './AggregationSelector'; +import { + callWithTimeout, + TimeoutError +} from '../utils'; export type PeriodicExportingMetricReaderOptions = { - /** - * Aggregation selector based on metric instrument types. If no views are - * configured for a metric instrument, a per-metric-reader aggregation is - * selected with this selector. - */ - aggregationSelector?: AggregationSelector; /** * The backing exporter for the metric reader. */ @@ -50,21 +43,21 @@ export type PeriodicExportingMetricReaderOptions = { exportTimeoutMillis?: number; }; -const DEFAULT_AGGREGATION_SELECTOR: AggregationSelector = Aggregation.Default; - /** * {@link MetricReader} which collects metrics based on a user-configurable time interval, and passes the metrics to - * the configured {@link MetricExporter} + * the configured {@link PushMetricExporter} */ export class PeriodicExportingMetricReader extends MetricReader { private _interval?: ReturnType; private _exporter: PushMetricExporter; private readonly _exportInterval: number; private readonly _exportTimeout: number; - private readonly _aggregationSelector: AggregationSelector; constructor(options: PeriodicExportingMetricReaderOptions) { - super(); + super({ + aggregationSelector: options.exporter.selectAggregation?.bind(options.exporter), + aggregationTemporalitySelector: options.exporter.selectAggregationTemporality?.bind(options.exporter) + }); if (options.exportIntervalMillis !== undefined && options.exportIntervalMillis <= 0) { throw Error('exportIntervalMillis must be greater than 0'); @@ -83,7 +76,6 @@ export class PeriodicExportingMetricReader extends MetricReader { this._exportInterval = options.exportIntervalMillis ?? 60000; this._exportTimeout = options.exportTimeoutMillis ?? 30000; this._exporter = options.exporter; - this._aggregationSelector = options.aggregationSelector ?? DEFAULT_AGGREGATION_SELECTOR; } private async _runOnce(): Promise { @@ -98,9 +90,9 @@ export class PeriodicExportingMetricReader extends MetricReader { if (result.code !== ExportResultCode.SUCCESS) { reject( result.error ?? - new Error( - `PeriodicExportingMetricReader: metrics export failed (error ${result.error})` - ) + new Error( + `PeriodicExportingMetricReader: metrics export failed (error ${result.error})` + ) ); } else { resolve(); @@ -137,18 +129,4 @@ export class PeriodicExportingMetricReader extends MetricReader { await this._exporter.shutdown(); } - - /** - * @inheritdoc - */ - selectAggregation(instrumentType: InstrumentType): Aggregation { - return this._aggregationSelector(instrumentType); - } - - /** - * @inheritdoc - */ - selectAggregationTemporality(instrumentType: InstrumentType): AggregationTemporality { - return this._exporter.selectAggregationTemporality(instrumentType); - } } diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/index.ts b/experimental/packages/opentelemetry-sdk-metrics/src/index.ts index 30ce7a09d9..0d82d420a5 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/index.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/index.ts @@ -47,6 +47,7 @@ export { export { MetricReader, + MetricReaderOptions } from './export/MetricReader'; export { diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts index 27a54d867a..32c00c24d4 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts @@ -18,8 +18,23 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import { MeterProvider } from '../../src/MeterProvider'; import { assertRejects } from '../test-utils'; -import { emptyResourceMetrics, TestMetricProducer } from './TestMetricProducer'; +import { + emptyResourceMetrics, + TestMetricProducer +} from './TestMetricProducer'; import { TestMetricReader } from './TestMetricReader'; +import { + Aggregation, + AggregationTemporality +} from '../../src'; +import { + DEFAULT_AGGREGATION_SELECTOR, + DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR, +} from '../../src/export/AggregationSelector'; +import { + assertAggregationSelector, + assertAggregationTemporalitySelector +} from './utils'; describe('MetricReader', () => { describe('setMetricProducer', () => { @@ -80,4 +95,34 @@ describe('MetricReader', () => { await reader.shutdown(); }); }); + + describe('selectAggregation', () => { + it('should override default when not provided with a selector', () => { + assertAggregationSelector(new TestMetricReader(), DEFAULT_AGGREGATION_SELECTOR); + assertAggregationSelector(new TestMetricReader({}), DEFAULT_AGGREGATION_SELECTOR); + }); + + it('should override default when provided with a selector', () => { + const reader = new TestMetricReader({ + aggregationSelector: _instrumentType => Aggregation.Sum() + }); + assertAggregationSelector(reader, _instrumentType => Aggregation.Sum()); + reader.shutdown(); + }); + }); + + describe('selectAggregationTemporality', () => { + it('should override default when not provided with a selector', () => { + assertAggregationTemporalitySelector(new TestMetricReader(), DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR); + assertAggregationTemporalitySelector(new TestMetricReader({}), DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR); + }); + + it('should override default when provided with a selector', () => { + const reader = new TestMetricReader({ + aggregationTemporalitySelector: _instrumentType => AggregationTemporality.DELTA + }); + assertAggregationTemporalitySelector(reader, _instrumentType => AggregationTemporality.DELTA); + reader.shutdown(); + }); + }); }); diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts index 77489f1e23..9e3ac30826 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts @@ -16,14 +16,32 @@ import { PeriodicExportingMetricReader } from '../../src/export/PeriodicExportingMetricReader'; import { AggregationTemporality } from '../../src/export/AggregationTemporality'; -import { InstrumentType, PushMetricExporter } from '../../src'; +import { + Aggregation, + InstrumentType, + PushMetricExporter +} from '../../src'; import { ResourceMetrics } from '../../src/export/MetricData'; import * as assert from 'assert'; import * as sinon from 'sinon'; import { TimeoutError } from '../../src/utils'; -import { ExportResult, ExportResultCode } from '@opentelemetry/core'; +import { + ExportResult, + ExportResultCode +} from '@opentelemetry/core'; import { assertRejects } from '../test-utils'; -import { emptyResourceMetrics, TestMetricProducer } from './TestMetricProducer'; +import { + emptyResourceMetrics, + TestMetricProducer +} from './TestMetricProducer'; +import { + assertAggregationSelector, + assertAggregationTemporalitySelector +} from './utils'; +import { + DEFAULT_AGGREGATION_SELECTOR, + DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR +} from '../../src/export/AggregationSelector'; const MAX_32_BIT_INT = 2 ** 31 - 1; @@ -43,9 +61,9 @@ class TestMetricExporter implements PushMetricExporter { } setTimeout(() => { if (this.failureResult) { - resultCallback({code: ExportResultCode.FAILED, error: new Error('some error') }); + resultCallback({ code: ExportResultCode.FAILED, error: new Error('some error') }); } else { - resultCallback({code: ExportResultCode.SUCCESS }); + resultCallback({ code: ExportResultCode.SUCCESS }); } }, this.exportTime); } @@ -75,15 +93,17 @@ class TestMetricExporter implements PushMetricExporter { } return this._batches.slice(0, numberOfExports); } +} +class TestDeltaMetricExporter extends TestMetricExporter { selectAggregationTemporality(_instrumentType: InstrumentType): AggregationTemporality { - return AggregationTemporality.CUMULATIVE; + return AggregationTemporality.DELTA; } } -class TestDeltaMetricExporter extends TestMetricExporter { - override selectAggregationTemporality(_instrumentType: InstrumentType): AggregationTemporality { - return AggregationTemporality.DELTA; +class TestDropMetricExporter extends TestMetricExporter { + selectAggregation(_instrumentType: InstrumentType): Aggregation { + return Aggregation.Drop(); } } @@ -287,6 +307,60 @@ describe('PeriodicExportingMetricReader', () => { }); }); + describe('selectAggregationTemporality', () => { + it('should default to Cumulative with no exporter preference', () => { + // Adding exporter without preference. + const exporter = new TestMetricExporter(); + const reader = new PeriodicExportingMetricReader({ + exporter: exporter, + exportIntervalMillis: MAX_32_BIT_INT, + }); + + assertAggregationTemporalitySelector(reader, DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR); + reader.shutdown(); + }); + + it('should default to exporter preference', () => { + // Adding exporter with DELTA preference. + const exporter = new TestDeltaMetricExporter(); + const reader = new PeriodicExportingMetricReader({ + exporter: exporter, + exportIntervalMillis: MAX_32_BIT_INT, + }); + + assertAggregationTemporalitySelector(reader, exporter.selectAggregationTemporality); + reader.shutdown(); + }); + }); + + describe('selectAggregation', () => { + it('should use default aggregation with no exporter preference', () => { + // Adding exporter without preference. + const exporter = new TestMetricExporter(); + const reader = new PeriodicExportingMetricReader({ + exporter: exporter, + exportIntervalMillis: MAX_32_BIT_INT, + }); + + // check if the default selector is used. + assertAggregationSelector(reader, DEFAULT_AGGREGATION_SELECTOR); + reader.shutdown(); + }); + + it('should default to exporter preference', () => { + // Adding exporter with Drop Aggregation preference. + const exporter = new TestDropMetricExporter(); + const reader = new PeriodicExportingMetricReader({ + exporter: exporter, + exportIntervalMillis: MAX_32_BIT_INT, + }); + + // check if the exporter's selector is used. + assertAggregationSelector(reader, exporter.selectAggregation); + reader.shutdown(); + }); + }); + describe('shutdown', () => { afterEach(() => { sinon.restore(); diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts index e708e1d2e0..40ae90e153 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts @@ -15,32 +15,16 @@ */ import { - Aggregation, - AggregationSelector, AggregationTemporality, - AggregationTemporalitySelector, - InstrumentType, MetricReader, } from '../../src'; import { MetricCollector } from '../../src/state/MetricCollector'; - -export interface TestMetricReaderOptions { - aggregationTemporalitySelector?: AggregationTemporalitySelector; - aggregationSelector?: AggregationSelector; -} +import { MetricReaderOptions } from '../../src/export/MetricReader'; /** * A test metric reader that implements no-op onForceFlush() and onShutdown() handlers. */ export class TestMetricReader extends MetricReader { - private _aggregationTemporalitySelector: AggregationTemporalitySelector; - private _aggregationSelector: AggregationSelector; - - constructor(options?: TestMetricReaderOptions) { - super(); - this._aggregationTemporalitySelector = options?.aggregationTemporalitySelector ?? (() => AggregationTemporality.CUMULATIVE); - this._aggregationSelector = options?.aggregationSelector ?? Aggregation.Default; - } protected onForceFlush(): Promise { return Promise.resolve(undefined); @@ -50,21 +34,13 @@ export class TestMetricReader extends MetricReader { return Promise.resolve(undefined); } - selectAggregationTemporality(instrumentType: InstrumentType) { - return this._aggregationTemporalitySelector(instrumentType); - } - - selectAggregation(instrumentType: InstrumentType) { - return this._aggregationSelector(instrumentType); - } - getMetricCollector(): MetricCollector { return this['_metricProducer'] as MetricCollector; } } export class TestDeltaMetricReader extends TestMetricReader { - constructor(options: TestMetricReaderOptions = {}) { + constructor(options: MetricReaderOptions = {}) { super({ ...options, aggregationTemporalitySelector: () => AggregationTemporality.DELTA, diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/utils.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/utils.ts new file mode 100644 index 0000000000..cd8a9cc7ae --- /dev/null +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/utils.ts @@ -0,0 +1,58 @@ +/* + * 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 { + AggregationSelector, + AggregationTemporalitySelector, + InstrumentType, + MetricReader +} from '../../src'; +import * as assert from 'assert'; + +const instrumentTypes = [ + InstrumentType.COUNTER, + InstrumentType.OBSERVABLE_COUNTER, + InstrumentType.UP_DOWN_COUNTER, + InstrumentType.OBSERVABLE_UP_DOWN_COUNTER, + InstrumentType.HISTOGRAM, + InstrumentType.OBSERVABLE_GAUGE +]; + +/** + * Check if AggregationSelectors behave in the same way. + * @param reader + * @param expectedSelector + */ +export function assertAggregationSelector(reader: MetricReader, expectedSelector: AggregationSelector) { + for (const instrumentType of instrumentTypes) { + assert.strictEqual(reader.selectAggregation(instrumentType), + expectedSelector(instrumentType), + `incorrect aggregation selection for ${InstrumentType[instrumentType]}`); + } +} + +/** + * Check if AggregationTemporalitySelectors behave in the same way. + * @param reader + * @param expectedSelector + */ +export function assertAggregationTemporalitySelector(reader: MetricReader, expectedSelector: AggregationTemporalitySelector) { + for (const instrumentType of instrumentTypes) { + assert.strictEqual(reader.selectAggregationTemporality(instrumentType), + expectedSelector(instrumentType), + `incorrect aggregation temporality selection for ${InstrumentType[instrumentType]}`); + } +} From f9f7fedb7716c855d835ce8f50088301cc898ae3 Mon Sep 17 00:00:00 2001 From: Tomer Ghelber <98252780+tomerghelber-tm@users.noreply.github.com> Date: Mon, 12 Sep 2022 18:34:56 +0300 Subject: [PATCH 16/77] feat(opentelemetry-api-metrics): Adding generics to `create{metricType}` (#3170) Co-authored-by: Daniel Dyla --- experimental/CHANGELOG.md | 1 + .../src/types/Meter.ts | 35 ++++-- .../src/types/Metric.ts | 30 ++--- .../src/types/ObservableResult.ts | 8 +- .../test/types/Metric.test.ts | 109 ++++++++++++++++++ 5 files changed, 154 insertions(+), 29 deletions(-) create mode 100644 experimental/packages/opentelemetry-api-metrics/test/types/Metric.test.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 555fe718b3..413ffbfe6b 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -67,6 +67,7 @@ All notable changes to experimental packages in this project will be documented * feat: support latest `@opentelemetry/api` [#3177](https://github.com/open-telemetry/opentelemetry-js/pull/3177) @dyladan * feat(sdk-metrics-base): add per metric-reader aggregation support [#3153](https://github.com/open-telemetry/opentelemetry-js/pull/3153) @legendecas * chore(deps): update prometheus example dependencies to 0.32 [#3126](https://github.com/open-telemetry/opentelemetry-js/pull/3216) @avzis +* feature(opentelemetry-api-metrics): Adding generics to `create{metricType}` [#3151](https://github.com/open-telemetry/opentelemetry-js/issues/3151) @tomerghelber-tm ### :bug: (Bug Fix) diff --git a/experimental/packages/opentelemetry-api-metrics/src/types/Meter.ts b/experimental/packages/opentelemetry-api-metrics/src/types/Meter.ts index 3931f01622..1904c48871 100644 --- a/experimental/packages/opentelemetry-api-metrics/src/types/Meter.ts +++ b/experimental/packages/opentelemetry-api-metrics/src/types/Meter.ts @@ -18,6 +18,7 @@ import { BatchObservableCallback, Counter, Histogram, + MetricAttributes, MetricOptions, Observable, ObservableCounter, @@ -49,7 +50,10 @@ export interface Meter { * @param name the name of the metric. * @param [options] the metric options. */ - createHistogram(name: string, options?: MetricOptions): Histogram; + createHistogram( + name: string, + options?: MetricOptions + ): Histogram; /** * Creates a new `Counter` metric. Generally, this kind of metric when the @@ -58,7 +62,10 @@ export interface Meter { * @param name the name of the metric. * @param [options] the metric options. */ - createCounter(name: string, options?: MetricOptions): Counter; + createCounter( + name: string, + options?: MetricOptions + ): Counter; /** * Creates a new `UpDownCounter` metric. UpDownCounter is a synchronous @@ -77,7 +84,7 @@ export interface Meter { * @param name the name of the metric. * @param [options] the metric options. */ - createUpDownCounter(name: string, options?: MetricOptions): UpDownCounter; + createUpDownCounter(name: string, options?: MetricOptions): UpDownCounter; /** * Creates a new `ObservableGauge` metric. @@ -87,10 +94,10 @@ export interface Meter { * @param name the name of the metric. * @param [options] the metric options. */ - createObservableGauge( + createObservableGauge( name: string, options?: MetricOptions - ): ObservableGauge; + ): ObservableGauge; /** * Creates a new `ObservableCounter` metric. @@ -100,10 +107,10 @@ export interface Meter { * @param name the name of the metric. * @param [options] the metric options. */ - createObservableCounter( + createObservableCounter( name: string, options?: MetricOptions - ): ObservableCounter; + ): ObservableCounter; /** * Creates a new `ObservableUpDownCounter` metric. @@ -113,10 +120,10 @@ export interface Meter { * @param name the name of the metric. * @param [options] the metric options. */ - createObservableUpDownCounter( + createObservableUpDownCounter( name: string, options?: MetricOptions - ): ObservableUpDownCounter; + ): ObservableUpDownCounter; /** * Sets up a function that will be called whenever a metric collection is @@ -132,7 +139,10 @@ export interface Meter { * @param callback the batch observable callback * @param observables the observables associated with this batch observable callback */ - addBatchObservableCallback(callback: BatchObservableCallback, observables: Observable[]): void; + addBatchObservableCallback( + callback: BatchObservableCallback, + observables: Observable[] + ): void; /** * Removes a callback previously registered with {@link Meter.addBatchObservableCallback}. @@ -143,5 +153,8 @@ export interface Meter { * @param callback the batch observable callback * @param observables the observables associated with this batch observable callback */ - removeBatchObservableCallback(callback: BatchObservableCallback, observables: Observable[]): void; + removeBatchObservableCallback( + callback: BatchObservableCallback, + observables: Observable[] + ): void; } diff --git a/experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts b/experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts index dcf779bc69..6ca013766f 100644 --- a/experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts +++ b/experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts @@ -61,25 +61,25 @@ export enum ValueType { *
  • count the number of 5xx errors.
  • *
      */ -export interface Counter { +export interface Counter { /** * Increment value of counter by the input. Inputs may not be negative. */ - add(value: number, attributes?: MetricAttributes, context?: Context): void; + add(value: number, attributes?: AttributesTypes, context?: Context): void; } -export interface UpDownCounter { +export interface UpDownCounter { /** * Increment value of counter by the input. Inputs may be negative. */ - add(value: number, attributes?: MetricAttributes, context?: Context): void; + add(value: number, attributes?: AttributesTypes, context?: Context): void; } -export interface Histogram { +export interface Histogram { /** * Records a measurement. Value of the measurement must not be negative. */ - record(value: number, attributes?: MetricAttributes, context?: Context): void; + record(value: number, attributes?: AttributesTypes, context?: Context): void; } // api.SpanAttributes instead of api.Attributes is used here for api package backward compatibility. @@ -101,27 +101,29 @@ export type MetricAttributeValue = SpanAttributeValue; /** * The observable callback for Observable instruments. */ -export type ObservableCallback = (observableResult: ObservableResult) => void | Promise; +export type ObservableCallback = + (observableResult: ObservableResult) => void | Promise; /** * The observable callback for a batch of Observable instruments. */ -export type BatchObservableCallback = (observableResult: BatchObservableResult) => void | Promise; +export type BatchObservableCallback = + (observableResult: BatchObservableResult) => void | Promise; -export interface Observable { +export interface Observable { /** * Sets up a function that will be called whenever a metric collection is initiated. * * If the function is already in the list of callbacks for this Observable, the function is not added a second time. */ - addCallback(callback: ObservableCallback): void; + addCallback(callback: ObservableCallback): void; /** * Removes a callback previously registered with {@link Observable.addCallback}. */ - removeCallback(callback: ObservableCallback): void; + removeCallback(callback: ObservableCallback): void; } -export type ObservableCounter = Observable; -export type ObservableUpDownCounter = Observable; -export type ObservableGauge = Observable; +export type ObservableCounter = Observable; +export type ObservableUpDownCounter = Observable; +export type ObservableGauge = Observable; diff --git a/experimental/packages/opentelemetry-api-metrics/src/types/ObservableResult.ts b/experimental/packages/opentelemetry-api-metrics/src/types/ObservableResult.ts index a38755982d..3bc4bc9c11 100644 --- a/experimental/packages/opentelemetry-api-metrics/src/types/ObservableResult.ts +++ b/experimental/packages/opentelemetry-api-metrics/src/types/ObservableResult.ts @@ -19,7 +19,7 @@ import { MetricAttributes, Observable } from './Metric'; /** * Interface that is being used in callback function for Observable Metric. */ -export interface ObservableResult { +export interface ObservableResult { /** * Observe a measurement of the value associated with the given attributes. * @@ -28,13 +28,13 @@ export interface ObservableResult { * one values associated with the same attributes values, SDK may pick the * last one or simply drop the entire observable result. */ - observe(value: number, attributes?: MetricAttributes): void; + observe(value: number, attributes?: AttributesTypes): void; } /** * Interface that is being used in batch observable callback function. */ -export interface BatchObservableResult { +export interface BatchObservableResult { /** * Observe a measurement of the value associated with the given attributes. * @@ -44,5 +44,5 @@ export interface BatchObservableResult { * one values associated with the same attributes values, SDK may pick the * last one or simply drop the entire observable result. */ - observe(metric: Observable, value: number, attributes?: MetricAttributes): void; + observe(metric: Observable, value: number, attributes?: AttributesTypes): void; } diff --git a/experimental/packages/opentelemetry-api-metrics/test/types/Metric.test.ts b/experimental/packages/opentelemetry-api-metrics/test/types/Metric.test.ts new file mode 100644 index 0000000000..a499db168f --- /dev/null +++ b/experimental/packages/opentelemetry-api-metrics/test/types/Metric.test.ts @@ -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 { Counter, UpDownCounter, Histogram } from '../../src'; + +describe('Metric', () => { + describe('Counter', () =>{ + it('enable not to define any type', () => { + const counter: Counter = { + add(_value: number, _attribute: unknown) {} + }; + counter.add(1, { 'some-attribute': 'value' }); + }); + + it('enable to use with type', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: Counter = { + add(_value: number, _attribute: Attributes) {} + }; + counter.add(1, { 'some-attribute': 'value' }); + }); + + it('disable wrong attributes by typing', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: Counter = { + add(_value: number, _attribute: Attributes) {} + }; + // @ts-expect-error Expacting the type of Attributes + counter.add(1, { 'another-attribute': 'value' }); + }); + }); + + describe('UpDownCounter', () =>{ + it('enable not to define any type', () => { + const counter: UpDownCounter = { + add(_value: number, _attribute: unknown) {} + }; + counter.add(1, { 'some-attribute': 'value' }); + }); + + it('enable to use with type', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: UpDownCounter = { + add(_value: number, _attribute: Attributes) {} + }; + counter.add(1, { 'some-attribute': 'value' }); + }); + + it('disable wrong attributes by typing', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: UpDownCounter = { + add(_value: number, _attribute: Attributes) {} + }; + // @ts-expect-error Expacting the type of Attributes + counter.add(1, { 'another-attribute': 'value' }); + }); + }); + + describe('Histogram', () =>{ + it('enable not to define any type', () => { + const counter: Histogram = { + record(_value: number, _attribute: unknown) {} + }; + counter.record(1, { 'some-attribute': 'value' }); + }); + + it('enable to use with type', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: Histogram = { + record(_value: number, _attribute: Attributes) {} + }; + counter.record(1, { 'some-attribute': 'value' }); + }); + + it('disable wrong attributes by typing', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: Histogram = { + record(_value: number, _attribute: Attributes) {} + }; + // @ts-expect-error Expacting the type of Attributes + counter.record(1, { 'another-attribute': 'value' }); + }); + }); +}); From c1ef97de3e7f198cff5d681fcd0f5fe3193967e6 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Mon, 12 Sep 2022 19:49:44 +0200 Subject: [PATCH 17/77] chore: upgrade linkinator to 4.0.3 (#3241) Co-authored-by: Daniel Dyla --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 59bc7ae95c..3488c1e1e8 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "gh-pages": "4.0.0", "lerna": "5.4.3", "lerna-changelog": "2.2.0", - "linkinator": "3.0.3", + "linkinator": "4.0.3", "markdownlint-cli": "0.29.0", "semver": "7.3.5", "typedoc": "0.22.10", From 0f178d1e2e9b3aed81789820944452c153543198 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 12 Sep 2022 14:10:48 -0400 Subject: [PATCH 18/77] Merge api repository into main (#3245) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mayur Kale Co-authored-by: Daniel Dyla Co-authored-by: Naseem Co-authored-by: Renovate Bot Co-authored-by: Bartlomiej Obecny Co-authored-by: Valentin Marchaud Co-authored-by: Gerhard Stöbich Co-authored-by: shivkanya9146 <62445341+shivkanya9146@users.noreply.github.com> Co-authored-by: legendecas Co-authored-by: Mark Wolff Co-authored-by: Bryan Clement Co-authored-by: dengliming Co-authored-by: srjames90 Co-authored-by: Michael Goin Co-authored-by: Mark Co-authored-by: Matthew Wear Co-authored-by: Andrew Co-authored-by: Srikanth Chekuri Co-authored-by: Paul Draper Co-authored-by: Amir Blum Co-authored-by: Nev <54870357+MSNev@users.noreply.github.com> Co-authored-by: Taavo-Taur "t2t2" Tammur Co-authored-by: Rauno Viskus Co-authored-by: Karen Xu Co-authored-by: Adam Dobrawy Co-authored-by: Trent Mick Co-authored-by: Severin Neumann Co-authored-by: James <45812677+JamesJHPark@users.noreply.github.com> Co-authored-by: Tyghe Vallard Co-authored-by: Sam Co-authored-by: Morgan Roderick <20321+mroderick@users.noreply.github.com> Co-authored-by: Phillip Carter --- api/.commitlintrc.yml | 29 ++ api/.editorconfig | 11 + api/.eslintrc.js | 69 +++++ api/.gitattributes | 39 +++ api/.github/CODEOWNERS | 15 ++ api/.github/workflows/codeql-analysis.yml | 34 +++ api/.github/workflows/docs.yaml | 27 ++ api/.github/workflows/lint.yaml | 37 +++ api/.github/workflows/release-please.yml | 33 +++ api/.github/workflows/test.yaml | 58 ++++ api/.gitignore | 88 ++++++ api/.markdownlint.json | 7 + api/.npmignore | 4 + api/CHANGELOG.md | 207 ++++++++++++++ api/LICENSE | 201 ++++++++++++++ api/README.md | 140 ++++++++++ api/docs/context.md | 234 ++++++++++++++++ api/docs/library-author.md | 3 + api/docs/propagation.md | 5 + api/docs/sdk-registration.md | 28 ++ api/docs/tracing.md | 214 +++++++++++++++ api/karma.base.js | 31 +++ api/karma.conf.js | 8 + api/karma.webpack.js | 43 +++ api/package.json | 90 +++++++ api/renovate.json | 25 ++ api/scripts/version-update.js | 48 ++++ api/src/api/context.ts | 99 +++++++ api/src/api/diag.ts | 139 ++++++++++ api/src/api/propagation.ts | 122 +++++++++ api/src/api/trace.ts | 113 ++++++++ api/src/baggage/context-helpers.ts | 53 ++++ api/src/baggage/internal/baggage-impl.ts | 62 +++++ api/src/baggage/internal/symbol.ts | 20 ++ api/src/baggage/types.ts | 97 +++++++ api/src/baggage/utils.ts | 57 ++++ api/src/common/Attributes.ts | 37 +++ api/src/common/Exception.ts | 47 ++++ api/src/common/Time.ts | 35 +++ api/src/context/NoopContextManager.ts | 45 ++++ api/src/context/context.ts | 85 ++++++ api/src/context/types.ts | 79 ++++++ api/src/diag/ComponentLogger.ts | 70 +++++ api/src/diag/consoleLogger.ts | 92 +++++++ api/src/diag/index.ts | 18 ++ api/src/diag/internal/logLevelLogger.ts | 51 ++++ api/src/diag/internal/noopLogger.ts | 34 +++ api/src/diag/types.ts | 98 +++++++ api/src/index.ts | 88 ++++++ api/src/internal/global-utils.ts | 102 +++++++ api/src/internal/semver.ts | 140 ++++++++++ api/src/platform/browser/globalThis.ts | 35 +++ api/src/platform/browser/index.ts | 17 ++ api/src/platform/index.ts | 17 ++ api/src/platform/node/globalThis.ts | 19 ++ api/src/platform/node/index.ts | 17 ++ api/src/propagation/NoopTextMapPropagator.ts | 33 +++ api/src/propagation/TextMapPropagator.ts | 137 ++++++++++ api/src/trace/NonRecordingSpan.ts | 75 ++++++ api/src/trace/NoopTracer.ts | 105 ++++++++ api/src/trace/NoopTracerProvider.ts | 36 +++ api/src/trace/ProxyTracer.ts | 76 ++++++ api/src/trace/ProxyTracerProvider.ts | 64 +++++ api/src/trace/Sampler.ts | 55 ++++ api/src/trace/SamplingResult.ts | 58 ++++ api/src/trace/SpanOptions.ts | 43 +++ api/src/trace/attributes.ts | 27 ++ api/src/trace/context-utils.ts | 85 ++++++ api/src/trace/internal/tracestate-impl.ts | 110 ++++++++ .../trace/internal/tracestate-validators.ts | 45 ++++ api/src/trace/internal/utils.ts | 23 ++ api/src/trace/invalid-span-constants.ts | 26 ++ api/src/trace/link.ts | 40 +++ api/src/trace/span.ts | 129 +++++++++ api/src/trace/span_context.ts | 69 +++++ api/src/trace/span_kind.ts | 45 ++++ api/src/trace/spancontext-utils.ts | 50 ++++ api/src/trace/status.ts | 40 +++ api/src/trace/trace_flags.ts | 21 ++ api/src/trace/trace_state.ts | 59 ++++ api/src/trace/tracer.ts | 100 +++++++ api/src/trace/tracer_options.ts | 25 ++ api/src/trace/tracer_provider.ts | 37 +++ api/test/api/api.test.ts | 253 ++++++++++++++++++ api/test/baggage/Baggage.test.ts | 161 +++++++++++ api/test/context/NoopContextManager.test.ts | 138 ++++++++++ api/test/diag/ComponentLogger.test.ts | 61 +++++ api/test/diag/consoleLogger.test.ts | 218 +++++++++++++++ api/test/diag/logLevel.test.ts | 236 ++++++++++++++++ api/test/diag/logger.test.ts | 126 +++++++++ api/test/index-webpack.ts | 20 ++ api/test/internal/global.test.ts | 155 +++++++++++ api/test/internal/semver.test.ts | 148 ++++++++++ api/test/internal/version.test.ts | 30 +++ .../noop-implementations/noop-span.test.ts | 54 ++++ .../noop-tracer-provider.test.ts | 31 +++ .../noop-implementations/noop-tracer.test.ts | 84 ++++++ .../proxy-tracer.test.ts | 189 +++++++++++++ api/test/trace/spancontext-utils.test.ts | 70 +++++ api/test/trace/tracestate-validators.test.ts | 92 +++++++ api/test/trace/tracestate.test.ts | 139 ++++++++++ api/tsconfig.esm.json | 13 + api/tsconfig.json | 39 +++ api/webpack.node-polyfills.js | 52 ++++ 104 files changed, 7538 insertions(+) create mode 100644 api/.commitlintrc.yml create mode 100644 api/.editorconfig create mode 100644 api/.eslintrc.js create mode 100644 api/.gitattributes create mode 100644 api/.github/CODEOWNERS create mode 100644 api/.github/workflows/codeql-analysis.yml create mode 100644 api/.github/workflows/docs.yaml create mode 100644 api/.github/workflows/lint.yaml create mode 100644 api/.github/workflows/release-please.yml create mode 100644 api/.github/workflows/test.yaml create mode 100644 api/.gitignore create mode 100644 api/.markdownlint.json create mode 100644 api/.npmignore create mode 100644 api/CHANGELOG.md create mode 100644 api/LICENSE create mode 100644 api/README.md create mode 100644 api/docs/context.md create mode 100644 api/docs/library-author.md create mode 100644 api/docs/propagation.md create mode 100644 api/docs/sdk-registration.md create mode 100644 api/docs/tracing.md create mode 100644 api/karma.base.js create mode 100644 api/karma.conf.js create mode 100644 api/karma.webpack.js create mode 100644 api/package.json create mode 100644 api/renovate.json create mode 100644 api/scripts/version-update.js create mode 100644 api/src/api/context.ts create mode 100644 api/src/api/diag.ts create mode 100644 api/src/api/propagation.ts create mode 100644 api/src/api/trace.ts create mode 100644 api/src/baggage/context-helpers.ts create mode 100644 api/src/baggage/internal/baggage-impl.ts create mode 100644 api/src/baggage/internal/symbol.ts create mode 100644 api/src/baggage/types.ts create mode 100644 api/src/baggage/utils.ts create mode 100644 api/src/common/Attributes.ts create mode 100644 api/src/common/Exception.ts create mode 100644 api/src/common/Time.ts create mode 100644 api/src/context/NoopContextManager.ts create mode 100644 api/src/context/context.ts create mode 100644 api/src/context/types.ts create mode 100644 api/src/diag/ComponentLogger.ts create mode 100644 api/src/diag/consoleLogger.ts create mode 100644 api/src/diag/index.ts create mode 100644 api/src/diag/internal/logLevelLogger.ts create mode 100644 api/src/diag/internal/noopLogger.ts create mode 100644 api/src/diag/types.ts create mode 100644 api/src/index.ts create mode 100644 api/src/internal/global-utils.ts create mode 100644 api/src/internal/semver.ts create mode 100644 api/src/platform/browser/globalThis.ts create mode 100644 api/src/platform/browser/index.ts create mode 100644 api/src/platform/index.ts create mode 100644 api/src/platform/node/globalThis.ts create mode 100644 api/src/platform/node/index.ts create mode 100644 api/src/propagation/NoopTextMapPropagator.ts create mode 100644 api/src/propagation/TextMapPropagator.ts create mode 100644 api/src/trace/NonRecordingSpan.ts create mode 100644 api/src/trace/NoopTracer.ts create mode 100644 api/src/trace/NoopTracerProvider.ts create mode 100644 api/src/trace/ProxyTracer.ts create mode 100644 api/src/trace/ProxyTracerProvider.ts create mode 100644 api/src/trace/Sampler.ts create mode 100644 api/src/trace/SamplingResult.ts create mode 100644 api/src/trace/SpanOptions.ts create mode 100644 api/src/trace/attributes.ts create mode 100644 api/src/trace/context-utils.ts create mode 100644 api/src/trace/internal/tracestate-impl.ts create mode 100644 api/src/trace/internal/tracestate-validators.ts create mode 100644 api/src/trace/internal/utils.ts create mode 100644 api/src/trace/invalid-span-constants.ts create mode 100644 api/src/trace/link.ts create mode 100644 api/src/trace/span.ts create mode 100644 api/src/trace/span_context.ts create mode 100644 api/src/trace/span_kind.ts create mode 100644 api/src/trace/spancontext-utils.ts create mode 100644 api/src/trace/status.ts create mode 100644 api/src/trace/trace_flags.ts create mode 100644 api/src/trace/trace_state.ts create mode 100644 api/src/trace/tracer.ts create mode 100644 api/src/trace/tracer_options.ts create mode 100644 api/src/trace/tracer_provider.ts create mode 100644 api/test/api/api.test.ts create mode 100644 api/test/baggage/Baggage.test.ts create mode 100644 api/test/context/NoopContextManager.test.ts create mode 100644 api/test/diag/ComponentLogger.test.ts create mode 100644 api/test/diag/consoleLogger.test.ts create mode 100644 api/test/diag/logLevel.test.ts create mode 100644 api/test/diag/logger.test.ts create mode 100644 api/test/index-webpack.ts create mode 100644 api/test/internal/global.test.ts create mode 100644 api/test/internal/semver.test.ts create mode 100644 api/test/internal/version.test.ts create mode 100644 api/test/noop-implementations/noop-span.test.ts create mode 100644 api/test/noop-implementations/noop-tracer-provider.test.ts create mode 100644 api/test/noop-implementations/noop-tracer.test.ts create mode 100644 api/test/proxy-implementations/proxy-tracer.test.ts create mode 100644 api/test/trace/spancontext-utils.test.ts create mode 100644 api/test/trace/tracestate-validators.test.ts create mode 100644 api/test/trace/tracestate.test.ts create mode 100644 api/tsconfig.esm.json create mode 100644 api/tsconfig.json create mode 100644 api/webpack.node-polyfills.js diff --git a/api/.commitlintrc.yml b/api/.commitlintrc.yml new file mode 100644 index 0000000000..1a5e5ac793 --- /dev/null +++ b/api/.commitlintrc.yml @@ -0,0 +1,29 @@ +extends: + - '@commitlint/config-conventional' +rules: + header-max-length: [1, 'always', 72] + type-enum: + - 2 + - always + - - ci + - feat + - fix + - docs + - style + - refactor + - perf + - test + - revert + - chore +help: | + **Possible types**: + `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle CI, BrowserStack, SauceLabs) + `feat`: Adds a new feature. + `fix`: Solves a bug. + `docs`: Adds or alters documentation. (example scopes: readme, worker, code_of_conduct, contributors) + `style`: Improves formatting, white-space. + `refactor`: Rewrites code without feature, performance or bug changes. + `perf`: Improves performance. + `test`: Adds or modifies tests. (example scopes: functionals, unit-tests) + `revert`: Changes that reverting other changes + `chore`: No production code change. Updating grunt tasks etc; diff --git a/api/.editorconfig b/api/.editorconfig new file mode 100644 index 0000000000..f68e97b033 --- /dev/null +++ b/api/.editorconfig @@ -0,0 +1,11 @@ +# http://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/api/.eslintrc.js b/api/.eslintrc.js new file mode 100644 index 0000000000..c78e7b660d --- /dev/null +++ b/api/.eslintrc.js @@ -0,0 +1,69 @@ +module.exports = { + plugins: [ + "@typescript-eslint", + "header", + "node" + ], + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + parser: "@typescript-eslint/parser", + parserOptions: { + "project": "./tsconfig.json" + }, + rules: { + "quotes": [2, "single", { "avoidEscape": true }], + "@typescript-eslint/no-floating-promises": 2, + "@typescript-eslint/no-this-alias": "off", + "brace-style": ["error", "1tbs"], + "eqeqeq": [ + "error", + "smart" + ], + "prefer-rest-params": "off", + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": "memberLike", + "modifiers": ["private", "protected"], + "format": ["camelCase"], + "leadingUnderscore": "require" + } + ], + "no-console": "error", + "no-shadow": "off", + "@typescript-eslint/no-shadow": ["warn"], + "@typescript-eslint/no-unused-vars": ["error", {"argsIgnorePattern": "^_", "args": "after-used"}], + "@typescript-eslint/no-inferrable-types": ["error", { ignoreProperties: true }], + "@typescript-eslint/no-empty-function": ["off"], + "@typescript-eslint/ban-types": ["warn", { + "types": { + "Function": null, + } + }], + "@typescript-eslint/no-shadow": ["warn"], + "arrow-parens": ["error", "as-needed"], + "node/no-deprecated-api": ["warn"], + "header/header": [2, "block", [{ + pattern: / \* Copyright The OpenTelemetry Authors[\r\n]+ \*[\r\n]+ \* Licensed under the Apache License, Version 2\.0 \(the \"License\"\);[\r\n]+ \* you may not use this file except in compliance with the License\.[\r\n]+ \* You may obtain a copy of the License at[\r\n]+ \*[\r\n]+ \* https:\/\/www\.apache\.org\/licenses\/LICENSE-2\.0[\r\n]+ \*[\r\n]+ \* Unless required by applicable law or agreed to in writing, software[\r\n]+ \* distributed under the License is distributed on an \"AS IS\" BASIS,[\r\n]+ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.[\r\n]+ \* See the License for the specific language governing permissions and[\r\n]+ \* limitations under the License\./gm, + template: + `\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n ` + }]] + }, + overrides: [ + { + "files": ["test/**/*.ts"], + "rules": { + "no-empty": "off", + "@typescript-eslint/ban-ts-ignore": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-floating-promises": 1, + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-var-requires": "off", + "@typescript-eslint/no-shadow": ["off"], + "@typescript-eslint/no-floating-promises": ["off"], + "@typescript-eslint/no-non-null-assertion": ["off"], + "@typescript-eslint/explicit-module-boundary-types": ["off"] + } + } + ] +}; diff --git a/api/.gitattributes b/api/.gitattributes new file mode 100644 index 0000000000..0113e927b8 --- /dev/null +++ b/api/.gitattributes @@ -0,0 +1,39 @@ +## This .gitattributes file automatically formats the EOL character in certain filetypes within the repository + +## Source code +# JavaScript, TypeScript, c, and h source files +*.js text eol=lf +*.ts text eol=lf +*.h text eol=lf diff=cpp +*.c text eol=lf diff=cpp + +# Shell scripts +*.sh text eol=lf +*.bash text eol=lf + +# Windows batch and PowerShell scripts +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf + +##### Other file types ##### + +## Text files and documentation +*.txt text +README* text +RELEASING* text +CHANGELOG* text +CONTRIBUTING* text +INSTALL* text +LICENSE* text + +## Non-text documentation +*.html text diff=html +*.pdf binary +*.json text eol=lf +*.rtf binary + +## Git Properties +.gitignore text +.gitmodules text +.gitattributes text diff --git a/api/.github/CODEOWNERS b/api/.github/CODEOWNERS new file mode 100644 index 0000000000..744582a847 --- /dev/null +++ b/api/.github/CODEOWNERS @@ -0,0 +1,15 @@ +##################################################### +# +# List of approvers for OpenTelemetry JS SDK +# +##################################################### +# +# Learn about membership in OpenTelemetry community: +# https://github.com/open-telemetry/community/blob/master/community-membership.md +# +# +# Learn about CODEOWNERS file format: +# https://help.github.com/en/articles/about-code-owners +# + +* @open-telemetry/javascript-approvers diff --git a/api/.github/workflows/codeql-analysis.yml b/api/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000000..c9efc6332b --- /dev/null +++ b/api/.github/workflows/codeql-analysis.yml @@ -0,0 +1,34 @@ +name: "CodeQL" + +on: + workflow_dispatch: + schedule: + # ┌───────────── minute (0 - 59) + # │ ┌───────────── hour (0 - 23) + # │ │ ┌───────────── day of the month (1 - 31) + # │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) + # │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) + # │ │ │ │ │ + # │ │ │ │ │ + # │ │ │ │ │ + # * * * * * + - cron: '30 1 * * *' + +jobs: + CodeQL-Build: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: javascript + + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/api/.github/workflows/docs.yaml b/api/.github/workflows/docs.yaml new file mode 100644 index 0000000000..4dae75bbf6 --- /dev/null +++ b/api/.github/workflows/docs.yaml @@ -0,0 +1,27 @@ +name: Deploy API Documentation + +on: + release: + types: [published] + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v2 + + - name: Install root dependencies + run: npm install --ignore-scripts + + - name: Build 🔧 + run: | + npm run compile + npm run docs + + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@releases/v3 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH: gh-pages # The branch the action should deploy to. + FOLDER: docs/out # The folder the action should deploy. diff --git a/api/.github/workflows/lint.yaml b/api/.github/workflows/lint.yaml new file mode 100644 index 0000000000..aba62bd293 --- /dev/null +++ b/api/.github/workflows/lint.yaml @@ -0,0 +1,37 @@ +name: Lint + +on: + push: + branches: + - main + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Lint markdown files + uses: docker://avtodev/markdown-lint:v1 + with: + args: "./**/*.md -i ./CHANGELOG.md" + + - name: Install dependencies + run: npm install + + - name: Build 🔧 + run: npm run compile + + - name: Lint + run: npm run lint + + - name: Check for Circular Dependencies + run: npm run cycle-check + + - name: Generate Documentation 📜 + run: npm run docs + + - name: Test Docs + run: npm run docs:test diff --git a/api/.github/workflows/release-please.yml b/api/.github/workflows/release-please.yml new file mode 100644 index 0000000000..f4f136910d --- /dev/null +++ b/api/.github/workflows/release-please.yml @@ -0,0 +1,33 @@ +on: + push: + branches: + - main +name: release-please +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: GoogleCloudPlatform/release-please-action@v2 + id: release + with: + token: ${{secrets.RELEASE_PR_TOKEN}} + release-type: node + package-name: "@opentelemetry/api" + # The logic below handles the npm publication: + - uses: actions/checkout@v2 + # these if statements ensure that a publication only occurs when + # a new release is created: + if: ${{ steps.release.outputs.release_created }} + - uses: actions/setup-node@v1 + with: + node-version: 14 + registry-url: 'https://registry.npmjs.org' + if: ${{ steps.release.outputs.release_created }} + - run: npm install + if: ${{ steps.release.outputs.release_created }} + - run: npm run compile + if: ${{ steps.release.outputs.release_created }} + - run: npm publish --tag next + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + if: ${{ steps.release.outputs.release_created }} diff --git a/api/.github/workflows/test.yaml b/api/.github/workflows/test.yaml new file mode 100644 index 0000000000..75f3998fc0 --- /dev/null +++ b/api/.github/workflows/test.yaml @@ -0,0 +1,58 @@ +name: Unit Tests +on: + push: + branches: + - main + pull_request: + +jobs: + unit-test: + strategy: + fail-fast: false + matrix: + node: ["8", "10", "12", "14", "16"] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + + - name: Install Dependencies + run: npm install + + - name: Compile 🔧 + run: npm run compile + + - name: Unit tests + run: npm run test + + - name: Report Coverage + run: npm run codecov + if: ${{ matrix.node == '14' }} + + browser-tests: + runs-on: ubuntu-latest + container: + image: circleci/node:12-browsers + steps: + - name: Permission Setup + run: sudo chmod -R 777 /github /__w + + - name: Checkout + uses: actions/checkout@v2 + + - name: Install Dependencies + run: npm install + + - name: Compile 🔧 + run: npm run compile + + - name: Unit tests + run: npm run test:browser + + - name: Report Coverage + run: npm run codecov:browser diff --git a/api/.gitignore b/api/.gitignore new file mode 100644 index 0000000000..10aac0eb73 --- /dev/null +++ b/api/.gitignore @@ -0,0 +1,88 @@ +# version.ts file is autogenerated at compile time +src/version.ts + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ +build/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# next.js build output +.next + +# lock files +yarn.lock +package-lock.json + +# generated gh-pages files +docs/out + +.nyc_output + +#lerna +.changelog +package.json.lerna_backup + +# OS generated files +.DS_Store + +# VsCode configs +.vscode/ + +#Visual Studio +.vs/ + +#IDEA +.idea +*.iml diff --git a/api/.markdownlint.json b/api/.markdownlint.json new file mode 100644 index 0000000000..6208ac19f1 --- /dev/null +++ b/api/.markdownlint.json @@ -0,0 +1,7 @@ +{ + "MD013": false, + "MD024": false, + "MD033": false, + "MD041": false, + "MD026": false +} diff --git a/api/.npmignore b/api/.npmignore new file mode 100644 index 0000000000..9505ba9450 --- /dev/null +++ b/api/.npmignore @@ -0,0 +1,4 @@ +/bin +/coverage +/doc +/test diff --git a/api/CHANGELOG.md b/api/CHANGELOG.md new file mode 100644 index 0000000000..139f4a33fa --- /dev/null +++ b/api/CHANGELOG.md @@ -0,0 +1,207 @@ +# CHANGELOG + +All notable changes to this project will be documented in this file. + +## [1.2.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.1.0...v1.2.0) (2022-08-09) + +### Features + +* Add getActiveSpan to trace API ([#163](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/163)) ([17ccb3a](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/17ccb3a4e385bc5769ded6fc742c9782a93244a5)) +* deprecate Sampler ([#166](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/166)) ([313b2e2](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/313b2e2225f246a6a9518ec4da6942f7d61babce)) + +## [1.1.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.0.4...v1.1.0) (2022-01-25) + +### Features + +* add tracestate implementation to api ([#147](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/147)) ([82842c7](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/82842c7097614e6ece99e73838ac5e94ff5460b7)) +* define common attributes type ([#142](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/142)) ([ae9bead](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/ae9bead17750d35dec4b63cfae098087666abc85)) +* **trace:** add optional schema url to TracerProvider.getTracer ([#129](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/129)) ([aa65fc6](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/aa65fc66809d45090d6e4951c265386d17ccc6f6)) + +### Bug Fixes + +* export tracer options ([#154](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/154)) ([b125324](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/b125324438fb2f24eb80c7c6673afc8cfc99575e)) + +### [1.0.4](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.0.3...v1.0.4) (2021-12-18) + +### Bug Fixes + +* align globalThis fallbacks with otel-core ([#126](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/126)) ([3507de7](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/3507de7c3b95396696657c021953b0b24a63a029)) + +### [1.0.3](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.0.2...v1.0.3) (2021-08-30) + +### Bug Fixes + +* remove all circular dependencies ([#119](https://www.github.com/open-telemetry/opentelemetry-js-api/issues/119)) ([a8083e8](https://www.github.com/open-telemetry/opentelemetry-js-api/commit/a8083e84b23227828745da80fd5fe512357dd34b)) + +## 1.0.2 + +### :bug: Bug Fix + +* [#105](https://github.com/open-telemetry/opentelemetry-js-api/pull/105) fix: set delegate after successful registration ([@Flarna](https://github.com/Flarna)) +* [#94](https://github.com/open-telemetry/opentelemetry-js-api/pull/94) fix: enforce strict equality on prerelease versions ([@dyladan](https://github.com/dyladan)) + +### :memo: Documentation + +* [#106](https://github.com/open-telemetry/opentelemetry-js-api/pull/106) docs: fix crash in README example ([@trentm](https://github.com/trentm)) +* [#101](https://github.com/open-telemetry/opentelemetry-js-api/pull/101) docs: Format example for tracer.startActiveSpan ([@ad-m](https://github.com/ad-m)) +* [#99](https://github.com/open-telemetry/opentelemetry-js-api/pull/99) chore: fix link to API docs ([@dyladan](https://github.com/dyladan)) + +### :house: Internal + +* [#109](https://github.com/open-telemetry/opentelemetry-js-api/pull/109) internal: add missing approvers from core ([@dyladan](https://github.com/dyladan)) +* [#103](https://github.com/open-telemetry/opentelemetry-js-api/pull/103) chore: reuse NoopTracer in ProxyTracer ([@Flarna](https://github.com/Flarna)) + +### Committers: 4 + +* Adam Dobrawy ([@ad-m](https://github.com/ad-m)) +* Daniel Dyla ([@dyladan](https://github.com/dyladan)) +* Gerhard Stöbich ([@Flarna](https://github.com/Flarna)) +* Trent Mick ([@trentm](https://github.com/trentm)) + +## 1.0.1 + +### :bug: Bug Fix + +* [#96](https://github.com/open-telemetry/opentelemetry-js-api/pull/96) chore: remove circular dependency ([@dyladan](https://github.com/dyladan)) + +### Committers: 1 + +* Daniel Dyla ([@dyladan](https://github.com/dyladan)) + +## 1.0.0 + +### :memo: Documentation + +* [#89](https://github.com/open-telemetry/opentelemetry-js-api/pull/89) chore: update upgrade guidelines ([@dyladan](https://github.com/dyladan)) + +### :house: Internal + +* [#90](https://github.com/open-telemetry/opentelemetry-js-api/pull/90) chore: enable typescript 4.3 noImplicitOverride option ([@Flarna](https://github.com/Flarna)) + +### Committers: 2 + +* Daniel Dyla ([@dyladan](https://github.com/dyladan)) +* Gerhard Stöbich ([@Flarna](https://github.com/Flarna)) + +## 0.21.0 + +### :boom: Breaking Change + +* [#78](https://github.com/open-telemetry/opentelemetry-js-api/pull/78) feat: unify signatures of `with` and `bind` ([@Rauno56](https://github.com/Rauno56)) +* [#46](https://github.com/open-telemetry/opentelemetry-js-api/pull/46) chore: do not export singletons ([@dyladan](https://github.com/dyladan)) + +### :rocket: Enhancement + +* [#81](https://github.com/open-telemetry/opentelemetry-js-api/pull/81) chore: function overloads implementation of startActiveSpan in noop t… ([@naseemkullah](https://github.com/naseemkullah)) + +### :house: Internal + +* [#84](https://github.com/open-telemetry/opentelemetry-js-api/pull/84) chore: remove unused backwards compatibility folder ([@Flarna](https://github.com/Flarna)) +* [#85](https://github.com/open-telemetry/opentelemetry-js-api/pull/85) chore: add node:16 to the test matrix ([@Rauno56](https://github.com/Rauno56)) +* [#63](https://github.com/open-telemetry/opentelemetry-js-api/pull/63) feat: debug log global registrations and logger overwrites ([@Rauno56](https://github.com/Rauno56)) +* [#75](https://github.com/open-telemetry/opentelemetry-js-api/pull/75) Add CodeQL Security Scan ([@xukaren](https://github.com/xukaren)) +* [#79](https://github.com/open-telemetry/opentelemetry-js-api/pull/79) chore: fix eslint config ([@Rauno56](https://github.com/Rauno56)) + +### Committers: 5 + +* Daniel Dyla ([@dyladan](https://github.com/dyladan)) +* Gerhard Stöbich ([@Flarna](https://github.com/Flarna)) +* Karen Xu ([@xukaren](https://github.com/xukaren)) +* Naseem ([@naseemkullah](https://github.com/naseemkullah)) +* Rauno Viskus ([@Rauno56](https://github.com/Rauno56)) + +## 0.20.0 + +### :rocket: Enhancement + +* [#69](https://github.com/open-telemetry/opentelemetry-js-api/pull/69) feat(context): add utils method to remove keys from context ([@vmarchaud](https://github.com/vmarchaud)) +* [#71](https://github.com/open-telemetry/opentelemetry-js-api/pull/71) chore: export baggage ([@dyladan](https://github.com/dyladan)) + +### Committers: 2 + +* Daniel Dyla ([@dyladan](https://github.com/dyladan)) +* Valentin Marchaud ([@vmarchaud](https://github.com/vmarchaud)) + +## 0.19.0 + +### :boom: Breaking Change + +* [#55](https://github.com/open-telemetry/opentelemetry-js-api/pull/55) chore: move baggage methods in propagation namespace ([@vmarchaud](https://github.com/vmarchaud)) +* [#65](https://github.com/open-telemetry/opentelemetry-js-api/pull/65) chore: remove suppress instrumentation ([@dyladan](https://github.com/dyladan)) +* [#60](https://github.com/open-telemetry/opentelemetry-js-api/pull/60) chore: removing timed event ([@obecny](https://github.com/obecny)) +* [#58](https://github.com/open-telemetry/opentelemetry-js-api/pull/58) chore: use spancontext for link ([@dyladan](https://github.com/dyladan)) +* [#47](https://github.com/open-telemetry/opentelemetry-js-api/pull/47) chore: move span method for context in trace API #40 ([@vmarchaud](https://github.com/vmarchaud)) +* [#45](https://github.com/open-telemetry/opentelemetry-js-api/pull/45) chore: rename `span#context()` to `span#spanContext` ([@dyladan](https://github.com/dyladan)) +* [#43](https://github.com/open-telemetry/opentelemetry-js-api/pull/43) chore: renaming noop span to non recording span ([@obecny](https://github.com/obecny)) +* [#32](https://github.com/open-telemetry/opentelemetry-js-api/pull/32) feat!: return boolean success value from setGlobalXXX methods ([@dyladan](https://github.com/dyladan)) + +### :rocket: Enhancement + +* [#62](https://github.com/open-telemetry/opentelemetry-js-api/pull/62) chore: adding component logger ([@obecny](https://github.com/obecny)) +* [#54](https://github.com/open-telemetry/opentelemetry-js-api/pull/54) feat: add tracer.startActiveSpan() ([@naseemkullah](https://github.com/naseemkullah)) +* [#58](https://github.com/open-telemetry/opentelemetry-js-api/pull/58) chore: use spancontext for link ([@dyladan](https://github.com/dyladan)) +* [#51](https://github.com/open-telemetry/opentelemetry-js-api/pull/51) feat: add function to wrap SpanContext in NonRecordingSpan #49 ([@dyladan](https://github.com/dyladan)) + +### :memo: Documentation + +* [#64](https://github.com/open-telemetry/opentelemetry-js-api/pull/64) chore: document the reason for symbol.for ([@dyladan](https://github.com/dyladan)) +* [#44](https://github.com/open-telemetry/opentelemetry-js-api/pull/44) chore: updating readme headline and fixing links ([@obecny](https://github.com/obecny)) + +### Committers: 6 + +* Bartlomiej Obecny ([@obecny](https://github.com/obecny)) +* Daniel Dyla ([@dyladan](https://github.com/dyladan)) +* Gerhard Stöbich ([@Flarna](https://github.com/Flarna)) +* Naseem ([@naseemkullah](https://github.com/naseemkullah)) +* Valentin Marchaud ([@vmarchaud](https://github.com/vmarchaud)) +* t2t2 ([@t2t2](https://github.com/t2t2)) + +## 1.0.0-rc.0 + +### :memo: Documentation + +* [#20](https://github.com/open-telemetry/opentelemetry-js-api/pull/20) docs: document latest manual tracing ([@dyladan](https://github.com/dyladan)) +* [#18](https://github.com/open-telemetry/opentelemetry-js-api/pull/18) chore: deploy docs on a release ([@dyladan](https://github.com/dyladan)) +* [#19](https://github.com/open-telemetry/opentelemetry-js-api/pull/19) docs: fix readme links ([@dyladan](https://github.com/dyladan)) + +### Committers: 1 + +* Daniel Dyla ([@dyladan](https://github.com/dyladan)) + +## 0.18.1 + +### :bug: Bug Fix + +* [#16](https://github.com/open-telemetry/opentelemetry-js-api/pull/16) fix: Reverse the direction of the semver check ([@dyladan](https://github.com/dyladan)) + +### Committers: 1 + +* Daniel Dyla ([@dyladan](https://github.com/dyladan)) + +## v0.18.0 + +### :boom: Breaking Change + +* [#9](https://github.com/open-telemetry/opentelemetry-js-api/pull/9) chore: refactor diag logger ([@dyladan](https://github.com/dyladan)) + +### :rocket: Enhancement + +* [#10](https://github.com/open-telemetry/opentelemetry-js-api/pull/10) Use semver to determine API compatibility ([@dyladan](https://github.com/dyladan)) + +### :house: Internal + +* [#12](https://github.com/open-telemetry/opentelemetry-js-api/pull/12) chore: don't disable rule eqeqeq ([@Flarna](https://github.com/Flarna)) +* [#8](https://github.com/open-telemetry/opentelemetry-js-api/pull/8) chore: remove nycrc in favor of tsconfig reporting ([@dyladan](https://github.com/dyladan)) +* [#3](https://github.com/open-telemetry/opentelemetry-js-api/pull/3) chore: add test workflow ([@dyladan](https://github.com/dyladan)) +* [#4](https://github.com/open-telemetry/opentelemetry-js-api/pull/4) chore: remove package lock ([@dyladan](https://github.com/dyladan)) +* [#2](https://github.com/open-telemetry/opentelemetry-js-api/pull/2) chore: add lint workflow ([@dyladan](https://github.com/dyladan)) + +### Committers: 2 + +* Daniel Dyla ([@dyladan](https://github.com/dyladan)) +* Gerhard Stöbich ([@Flarna](https://github.com/Flarna)) + +## v0.17.0 + +Versions previous to `0.18.0` were developed in another repository. +To see previous changelog entries see the [CHANGELOG.md](https://github.com/open-telemetry/opentelemetry-js/blob/main/CHANGELOG.md). diff --git a/api/LICENSE b/api/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/api/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + 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. diff --git a/api/README.md b/api/README.md new file mode 100644 index 0000000000..363cfac136 --- /dev/null +++ b/api/README.md @@ -0,0 +1,140 @@ + +--- +

      + + API Documentation +   •   + Getting In Touch (GitHub Discussions) + +

      + +

      + + GitHub release (latest by date including pre-releases) + + + Codecov Status + + + license + +
      + + Build Status + + + Build Status + +

      + +--- + +# OpenTelemetry API for JavaScript + +[![NPM Published Version][npm-img]][npm-url] + +This package provides everything needed to interact with the OpenTelemetry API, including all TypeScript interfaces, enums, and no-op implementations. It is intended for use both on the server and in the browser. + +The methods in this package perform no operations by default. This means they can be safely called by a library or end-user application whether there is an SDK registered or not. In order to generate and export telemetry data, you will also need an SDK such as the [OpenTelemetry JS SDK][opentelemetry-js]. + +## Tracing Quick Start + +### You Will Need + +- An application you wish to instrument +- [OpenTelemetry JS SDK][opentelemetry-js] +- Node.js >=8.5.0 (14+ is preferred) or an ECMAScript 5+ compatible browser + +**Note:** ECMAScript 5+ compatibility is for this package only. Please refer to the documentation for the SDK you are using to determine its minimum ECMAScript version. + +**Note for library authors:** Only your end users will need an OpenTelemetry SDK. If you wish to support OpenTelemetry in your library, you only need to use the OpenTelemetry API. For more information, please read the [tracing documentation][docs-tracing]. + +### Install Dependencies + +```sh +npm install @opentelemetry/api @opentelemetry/sdk-trace-base +``` + +### Trace Your Application + +In order to get started with tracing, you will need to first register an SDK. The SDK you are using may provide a convenience method which calls the registration methods for you, but if you would like to call them directly they are documented here: [sdk registration methods][docs-sdk-registration]. + +Once you have registered an SDK, you can start and end spans. A simple example of basic SDK registration and tracing a simple operation is below. The example should export spans to the console once per second. For more information, see the [tracing documentation][docs-tracing]. + +```javascript +const { trace } = require("@opentelemetry/api"); +const { BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor } = require("@opentelemetry/sdk-trace-base"); + +// Create and register an SDK +const provider = new BasicTracerProvider(); +provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); +trace.setGlobalTracerProvider(provider); + +// Acquire a tracer from the global tracer provider which will be used to trace the application +const name = 'my-application-name'; +const version = '0.1.0'; +const tracer = trace.getTracer(name, version); + +// Trace your application by creating spans +async function operation() { + const span = tracer.startSpan("do operation"); + + // mock some work by sleeping 1 second + await new Promise((resolve, reject) => { + setTimeout(resolve, 1000); + }) + + span.end(); +} + +async function main() { + while (true) { + await operation(); + } +} + +main(); +``` + +## Version Compatibility + +Because the npm installer and node module resolution algorithm could potentially allow two or more copies of any given package to exist within the same `node_modules` structure, the OpenTelemetry API takes advantage of a variable on the `global` object to store the global API. When an API method in the API package is called, it checks if this `global` API exists and proxies calls to it if and only if it is a compatible API version. This means if a package has a dependency on an OpenTelemetry API version which is not compatible with the API used by the end user, the package will receive a no-op implementation of the API. + +## Upgrade Guidelines + +### 0.21.0 to 1.0.0 + +No breaking changes + +### 0.20.0 to 0.21.0 + +- [#78](https://github.com/open-telemetry/opentelemetry-js-api/issues/78) `api.context.bind` arguments reversed and `context` is now a required argument. +- [#46](https://github.com/open-telemetry/opentelemetry-js-api/issues/46) Noop classes and singletons are no longer exported. To create a noop span it is recommended to use `api.trace.wrapSpanContext` with `INVALID_SPAN_CONTEXT` instead of using the `NOOP_TRACER`. + +### 1.0.0-rc.3 to 0.20.0 + +- Removing `TimedEvent` which was not part of spec +- `HttpBaggage` renamed to `HttpBaggagePropagator` +- [#45](https://github.com/open-telemetry/opentelemetry-js-api/pull/45) `Span#context` renamed to `Span#spanContext` +- [#47](https://github.com/open-telemetry/opentelemetry-js-api/pull/47) `getSpan`/`setSpan`/`getSpanContext`/`setSpanContext` moved to `trace` namespace +- [#55](https://github.com/open-telemetry/opentelemetry-js-api/pull/55) `getBaggage`/`setBaggage`/`createBaggage` moved to `propagation` namespace + +## Useful links + +- For more information on OpenTelemetry, visit: +- For more about OpenTelemetry JavaScript: +- For help or feedback on this project, join us in [GitHub Discussions][discussions-url] + +## License + +Apache 2.0 - See [LICENSE][license-url] for more information. + +[opentelemetry-js]: https://github.com/open-telemetry/opentelemetry-js + +[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions +[license-url]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/LICENSE +[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat +[npm-url]: https://www.npmjs.com/package/@opentelemetry/api +[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi.svg +[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/tracing.md +[docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/sdk-registration.md diff --git a/api/docs/context.md b/api/docs/context.md new file mode 100644 index 0000000000..4f3d8bd2bb --- /dev/null +++ b/api/docs/context.md @@ -0,0 +1,234 @@ +# Context + +In order for OpenTelemetry to work, it must store and propagate important telemetry data. +For example, when a request is received and a span is started it must be available to a component which creates its child span. +To solve this problem, OpenTelemetry stores the span in the Context. +This document describes the OpenTelemetry context API for JavaScript and how it is used. + +_Context Specification: _ + +_Context API Reference: _ + +- [Context Manager](#context-manager) +- [Root Context](#root-context) +- [Context Keys](#context-keys) +- [Basic Operations](#basic-operations) + - [Get Entry](#get-entry) + - [Set Entry](#set-entry) + - [Delete Entry](#delete-entry) +- [Active Context](#active-context) + - [Get Active Context](#get-active-context) + - [Set Active Context](#set-active-context) + - [Example](#example) + +## Context Manager + +The context API depends on a context manager to work. +The examples in this document will assume you have already configured a context manager. +Typically the context manager is provided by your SDK, however it is possible to register one directly like this: + +```typescript +import * as api from "@opentelemetry/api"; +import { AsyncHooksContextManager } from "@opentelemetry/context-async-hooks"; + +const contextManager = new AsyncHooksContextManager(); +contextManager.enable(); +api.context.setGlobalContextManager(contextManager); +``` + +## Root Context + +The `ROOT_CONTEXT` is the empty context. +If no context is active, the `ROOT_CONTEXT` is active. +Active context is explained below [Active Context](#active-context). + +## Context Keys + +Context entries are key-value pairs. +Keys can be created by calling `api.createContextKey(description)`. + +```typescript +import * as api from "@opentelemetry/api"; + +const key1 = api.createContextKey("My first key"); +const key2 = api.createContextKey("My second key"); +``` + +## Basic Operations + +### Get Entry + +Entries are accessed using the `context.getValue(key)` method. + +```typescript +import * as api from "@opentelemetry/api"; + +const key = api.createContextKey("some key"); +// ROOT_CONTEXT is the empty context +const ctx = api.ROOT_CONTEXT; + +const value = ctx.getValue(key); +``` + +### Set Entry + +Entries are created by using the `context.setValue(key, value)` method. +Setting a context entry creates a new context with all the entries of the previous context, but with the new entry. +Setting a context entry does not modify the previous context. + +```typescript +import * as api from "@opentelemetry/api"; + +const key = api.createContextKey("some key"); +const ctx = api.ROOT_CONTEXT; + +// add a new entry +const ctx2 = ctx.setValue(key, "context 2"); + +// ctx2 contains the new entry +console.log(ctx2.getValue(key)) // "context 2" + +// ctx is unchanged +console.log(ctx.getValue(key)) // undefined +``` + +### Delete Entry + +Entries are removed by calling `context.deleteValue(key)`. +Deleting a context entry creates a new context with all the entries of the previous context, but without the entry identified by the key. +Deleting a context entry does not modify the previous context. + +```typescript +import * as api from "@opentelemetry/api"; + +const key = api.createContextKey("some key"); +const ctx = api.ROOT_CONTEXT; +const ctx2 = ctx.setValue(key, "context 2"); + +// remove the entry +const ctx3 = ctx.deleteValue(key); + +// ctx3 does not contain the entry +console.log(ctx3.getValue(key)) // undefined + +// ctx2 is unchanged +console.log(ctx2.getValue(key)) // "context 2" +// ctx is unchanged +console.log(ctx.getValue(key)) // undefined +``` + +## Active Context + +**IMPORTANT**: This assumes you have configured a Context Manager. +Without one, `api.context.active()` will _ALWAYS_ return the `ROOT_CONTEXT`. + +The active context is the context which is returned by `api.context.active()`. +The context object contains entries which allow tracing components which are tracing a single thread of execution to communicate with each other and ensure the trace is successfully created. +For example, when a span is created it may be added to the context. +Later, when another span is created it may use the span from the context as its parent span. +This is accomplished through the use of mechanisms like [async_hooks](https://nodejs.org/api/async_hooks.html) or [AsyncLocalStorage](https://nodejs.org/api/async_context.html#async_context_class_asynclocalstorage) in node, or [zone.js](https://github.com/angular/zone.js/) on the web in order to propagate the context through a single execution. +If no context is active, the `ROOT_CONTEXT` is returned, which is just the empty context object. + +### Get Active Context + +The active context is the context which is returned by `api.context.active()`. + +```typescript +import * as api from "@opentelemetry/api"; + +// Returns the active context +// If no context is active, the ROOT_CONTEXT is returned +const ctx = api.context.active(); +``` + +### Set Active Context + +A context can be made active by use of `api.context.with(ctx, callback)`. +During execution of the `callback`, the context passed to `with` will be returned by `context.active`. + +```typescript +import * as api from "@opentelemetry/api"; + +const key = api.createContextKey("Key to store a value"); +const ctx = api.context.active(); + +api.context.with(ctx.setValue(key, "context 2"), async () => { + // "context 2" is active + console.log(api.context.active().getValue(key)) // "context 2" +}); +``` + +The return value of `api.context.with(context, callback)` is the return value of the callback. +The callback is always called synchronously. + +```typescript +import * as api from "@opentelemetry/api"; + +const name = await api.context.with(api.context.active(), async () => { + const row = await db.getSomeValue(); + return row["name"]; +}); + +console.log(name); // name returned by the db +``` + +Active context executions may be nested. + +```typescript +import * as api from "@opentelemetry/api"; + +const key = api.createContextKey("Key to store a value"); +const ctx = api.context.active(); + +// No context is active +console.log(api.context.active().getValue(key)); // undefined + +api.context.with(ctx.setValue(key, "context 2"), () => { + // "context 2" is active + console.log(api.context.active().getValue(key)) // "context 2" + api.context.with(ctx.setValue(key, "context 3"), () => { + // "context 3" is active + console.log(api.context.active().getValue(key)) // "context 3" + }); + // "context 2" is active + console.log(api.context.active().getValue(key)) // "context 2" +}); + +// No context is active +console.log(api.context.active().getValue(key)); // undefined +``` + +### Example + +This more complex example illustrates how the context is not modified, but new context objects are created. + +```typescript +import * as api from "@opentelemetry/api"; + +const key = api.createContextKey("Key to store a value"); + +const ctx = api.context.active(); // Returns ROOT_CONTEXT when no context is active +const ctx2 = ctx.setValue(key, "context 2"); // does not modify ctx + +console.log(ctx.getValue(key)) //? undefined +console.log(ctx2.getValue(key)) //? "context 2" + +const ret = api.context.with(ctx2, () => { + const ctx3 = api.context.active().setValue(key, "context 3"); + + console.log(api.context.active().getValue(key)); //? "context 2" + console.log(ctx.getValue(key)) //? undefined + console.log(ctx2.getValue(key)) //? "context 2" + console.log(ctx3.getValue(key)) //? "context 3" + + api.context.with(ctx3, () => { + console.log(api.context.active().getValue(key)); //? "context 3" + }); + console.log(api.context.active().getValue(key)); //? "context 2" + + return "return value" +}); + +// The value returned by the callback is returned to the caller +console.log(ret); //? "return value" +``` diff --git a/api/docs/library-author.md b/api/docs/library-author.md new file mode 100644 index 0000000000..44e5f1e97e --- /dev/null +++ b/api/docs/library-author.md @@ -0,0 +1,3 @@ +# OpenTelemetry for Library Authors + +TODO diff --git a/api/docs/propagation.md b/api/docs/propagation.md new file mode 100644 index 0000000000..1cb3928bde --- /dev/null +++ b/api/docs/propagation.md @@ -0,0 +1,5 @@ +# Propagation + +TODO + +_Propagation API reference: _ diff --git a/api/docs/sdk-registration.md b/api/docs/sdk-registration.md new file mode 100644 index 0000000000..2d6490c9bb --- /dev/null +++ b/api/docs/sdk-registration.md @@ -0,0 +1,28 @@ +# SDK Registration Methods + +These methods are used to register a compatible OpenTelemetry SDK. Some SDKs like the [OpenTelemetry JS SDK][opentelemetry-js] provide convenience methods which call these registration methods for you. + +- [Trace API Documentation][trace-api-docs] +- [Propagation API Documentation][propagation-api-docs] +- [Context API Documentation][context-api-docs] + +```javascript +const api = require("@opentelemetry/api"); + +/* Register a global TracerProvider */ +api.trace.setGlobalTracerProvider(tracerProvider); +/* returns tracerProvider (no-op if a working provider has not been initialized) */ +api.trace.getTracerProvider(); +/* returns a tracer from the registered global tracer provider (no-op if a working provider has not been initialized) */ +api.trace.getTracer(name, version); + +/* Register a global Propagator */ +api.propagation.setGlobalPropagator(httpTraceContextPropagator); + +/* Register a global Context Manager */ +api.context.setGlobalContextManager(asyncHooksContextManager); +``` + +[trace-api-docs]: https://open-telemetry.github.io/opentelemetry-js-api/classes/traceapi.html +[propagation-api-docs]: https://open-telemetry.github.io/opentelemetry-js-api/classes/propagationapi.html +[context-api-docs]: https://open-telemetry.github.io/opentelemetry-js-api/classes/contextapi.html diff --git a/api/docs/tracing.md b/api/docs/tracing.md new file mode 100644 index 0000000000..ba13dc22a1 --- /dev/null +++ b/api/docs/tracing.md @@ -0,0 +1,214 @@ +# Tracing + +This quick start is for end users of OpenTelemetry who wish to manually trace their applications. If you are a library author, please see the [Library Authors Guide](library-author.md). If you wish to automatically instrument your application, see the automatic instrumentation documentation for the SDK you wish to use. + +For a high-level overview of OpenTelemetry tracing in general and definitions of some common terms, you can refer to the [OpenTelemetry Specification Overview][spec-overview] + +_Trace API Specification: _ + +_Trace API Reference: _ + +- [Acquiring a Tracer](#acquiring-a-tracer) +- [Starting and Ending a Span](#starting-and-ending-a-span) +- [Describing a Span](#describing-a-span) + - [Span Relationships](#span-relationships) + - [Span Attributes](#span-attributes) + - [Span Kind](#span-kind) + - [Client](#client) + - [Server](#server) + - [Internal](#internal) + - [Producer](#producer) + - [Consumer](#consumer) + - [Semantic Conventions](#semantic-conventions) + +## Acquiring a Tracer + +In OpenTelemetry, tracing operations are performed using methods on a _tracer_. You can get a tracer by calling [`getTracer`](https://open-telemetry.github.io/opentelemetry-js-api/classes/traceapi.html#gettracer) on the global tracer provider. `getTracer` takes the name and version of the application or library acquiring the tracer, and provides a tracer which can be used to trace operations. + +```typescript +import { trace } from '@opentelemetry/api'; + +const tracer = trace.getTracer("my-application", "0.1.0"); +``` + +## Starting and Ending a Span + +In OpenTelemetry, all _traces_ are composed of [`Spans`](https://open-telemetry.github.io/opentelemetry-js-api/interfaces/span.html). A span describes a single operation with a start time and and end time like a database request, outgoing remote request, or a function invocation. These spans are linked together by parent-child relationships to form a tree. The resultant tree is your trace, and the root of the tree is commonly called the _root span_. + +You can create a span by calling [`Tracer#startSpan`](https://open-telemetry.github.io/opentelemetry-js-api/interfaces/tracer.html#startspan). The only required argument to `startSpan` is the _span name_, which should describe the operation being performed with low cardinality. + +```typescript +const span = tracer.startSpan("my-span-name"); + +// do some work + +// When a span is ended, it will be exported to a tracing backend +// via the currently registered SDK. +span.end(); +``` + +Most of the time, spans will be used as part of a function which responds to some event like a web request. The following example shows what it might look like to manually trace a function which responds to a get request using an imaginary http server framework. + +```typescript +async function onGet(request, response) { + const span = tracer.startSpan("onGet"); + try { + // Do some work here + + response.send(); + + // If we get here and nothing has thrown, the request completed successfully + span.setStatus({ code: SpanStatusCode.OK }); + } catch (err) { + // When we catch an error, we want to show that an error occurred + span.setStatus({ + code: SpanStatusCode.ERROR, + message: err.message, + }); + } finally { + // Every span must be ended or it will not be exported + span.end(); + } +} + +server.on("GET", "/user/:id", onGet); +``` + +## Describing a Span + +Using span relationships, attributes, kind, and the related [semantic conventions](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions), we can more accurately describe the span in a way our tracing backend will more easily understand. The following example uses these mechanisms, which are described below. + +```typescript +import { NetTransportValues SemanticAttributes } from '@opentelemetry/semantic-conventions'; +import { trace, context, SpanKind, SpanStatusCode } from '@opentelemetry/api'; + +async function onGet(request, response) { + // HTTP semantic conventions determine the span name and attributes for this span + const span = tracer.startSpan(`GET /user/:id`, { + // attributes can be added when the span is started + attributes: { + // Attributes from the HTTP trace semantic conventions + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md + [SemanticAttributes.HTTP_METHOD]: "GET", + [SemanticAttributes.HTTP_FLAVOR]: "1.1", + [SemanticAttributes.HTTP_URL]: request.url, + [SemanticAttributes.NET_PEER_IP]: "192.0.2.5", + }, + // This span represents a remote incoming synchronous request + kind: SpanKind.SERVER + }); + + const userId = request.params.id; + + // Create a new context from the current context which has the span "active" + const ctx = trace.setSpan(context.active(), span); + + // Call getUser with the newly created context + // + // context.with calls a function with an associated "active" context. Within + // the function, calling context.active() returns the currently active context. + // If there is no active context, the ROOT_CONTEXT will be returned, which + // has no key-value pairs. + // + // context.with requires at least 2 arguments: a context and a function to be called. + // If a third argument is provided, it will be bound to `this` `this` inside the function. + // Any additional parameters are used as arguments when calling the function. + // + // Return value is the value returned from getUser + // | Context to be used as the "active" context + // | | Function to be called + // | | | Object assigned to this during function execution + // | | | | Passed as the first argument to getUser + // | | | | | + // V V V V V + const user = await context.with(ctx, getUser, undefined, userId); + + // Attributes may also be added after the span is started. + // http.status_code is required by the HTTP trace semantic conventions + span.setAttribute("http.status_code", 200); + + response.send(user.toJson()); + span.setStatus({ + code: SpanStatusCode.OK, + }); + span.end(); + + // Attributes MAY NOT be added after the span ends + span.setAttribute("my.attribute", false); // this does nothing +} + +async function getUser(userId) { + // when this span is created, it will automatically use the span from the context as its parent + const span = tracer.startSpan("SELECT ShopDb.Users", { + attributes: { + // Attributes from the database trace semantic conventions + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md + [SemanticAttributes.DB_SYSTEM]: "mysql", + [SemanticAttributes.DB_CONNECTION_STRING]: "Server=shopdb.example.com;Database=ShopDb;Uid=billing_user;TableCache=true;UseCompression=True;MinimumPoolSize=10;MaximumPoolSize=50;", + [SemanticAttributes.DB_USER]: "app_user", + [SemanticAttributes.NET_PEER_NAME]: "shopdb.example.com", + [SemanticAttributes.NET_PEER_IP]: "192.0.2.12", + [SemanticAttributes.NET_PEER_PORT]: 3306, + [SemanticAttributes.NET_TRANSPORT]: NetTransportValues.IP_TCP, + [SemanticAttributes.DB_NAME]: "ShopDb", + [SemanticAttributes.DB_STATEMENT]: `Select * from Users WHERE user_id = ${userId}`, + [SemanticAttributes.DB_OPERATION]: "SELECT", + [SemanticAttributes.DB_SQL_TABLE]: "Users", + }, + kind: SpanKind.CLIENT, + }); + const user = await db.select("Users", { id: userId }); + + span.setStatus({ + code: SpanStatusCode.OK, + }); + span.end(); + return user; +} + +server.on("GET", "/user/:id", onGet); +``` + +### Span Relationships + +One of the most important aspects of spans is their relationships to each other. For instance, if one span describes an incoming request which makes a database call, it is recommended to trace the database call as a separate span which is a child of the original request span. In order to do this, when we create a span we can tell OpenTelemetry which span to use as its parent using a mechanism called _Context_. + +Context is a very important part of the OpenTelemetry API which cannot be adequately explained in a single paragraph. To read more about context, see the [context documentation](context.md). + +### Span Attributes + +While name, start time, end time, and status are the minimum information required to trace an operation, most of the time they will not be enough information on their own to effectively observe an application. To solve this, OpenTelemetry uses _Span Attributes_. Span attributes are an object with string keys and string, number, or boolean values which describe the span. For example, we can use the span attributes to add route and http response code information to the example above. + +### Span Kind + +When a span is created, it is one of `Client`, `Server`, `Internal`, `Producer`, or `Consumer`. This span kind provides a hint to the tracing backend as to how the trace should be assembled. According to the OpenTelemetry specification, the parent of a server span is always a client span, and the child of a client span is always a server span. Similarly, the parent of a consumer span is always a producer and the child of a producer span is always a consumer. If not provided, the span kind is assumed to be internal. + +For more information regarding SpanKind, see . + +#### Client + +Client spans represent a synchronous outgoing remote call such as an outgoing HTTP request or database call. Note that in this context, "synchronous" does not refer to `async/await`, but to the fact that it is not queued for later processing. + +#### Server + +Server spans represent a synchronous incoming remote call such as an incoming HTTP request or remote procedure call. + +#### Internal + +Internal spans represent operations which do not cross a process boundary. Things like instrumenting a function call or an express middleware may use internal spans. + +#### Producer + +Producer spans represent the creation of a job which may be asynchronously processed later. It may be a remote job such as one inserted into a job queue or a local job handled by an event listener. + +#### Consumer + +Consumer spans represent the processing of a job created by a producer and may start long after the producer span has already ended. + +### Semantic Conventions + +One problem with span names and attributes is recognizing, categorizing, and analyzing them in your tracing backend. Between different applications, libraries, and tracing backends there might be different names and expected values for various attributes. For example, your application may use `http.status` to describe the HTTP status code, but a library you use may use `http.status_code`. In order to solve this problem, OpenTelemetry uses a library of semantic conventions which describe the name and attributes which should be used for specific types of spans. The use of semantic conventions is always recommended where applicable, but they are merely conventions. For example, you may find that some name other than the name suggested by the semantic conventions more accurately describes your span, you may decide not to include a span attribute which is suggested by semantic conventions for privacy reasons, or you may wish to add a custom attribute which isn't covered by semantic conventions. All of these cases are fine, but please keep in mind that if you stray from the semantic conventions, the categorization of spans in your tracing backend may be affected. + +_See the current trace semantic conventions in the OpenTelemetry Specification repository: _ + +[spec-overview]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md diff --git a/api/karma.base.js b/api/karma.base.js new file mode 100644 index 0000000000..cbae813f7b --- /dev/null +++ b/api/karma.base.js @@ -0,0 +1,31 @@ +/*! + * 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 + * + * 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. + */ + +module.exports = { + listenAddress: 'localhost', + hostname: 'localhost', + browsers: ['ChromeHeadless'], + frameworks: ['mocha'], + coverageIstanbulReporter: { + reports: ['html', 'json'], + dir: '.nyc_output', + fixWebpackSourcePaths: true + }, + reporters: ['spec', 'coverage-istanbul'], + files: ['test/index-webpack.ts'], + preprocessors: { 'test/index-webpack.ts': ['webpack'] }, + webpackMiddleware: { noInfo: true } +}; diff --git a/api/karma.conf.js b/api/karma.conf.js new file mode 100644 index 0000000000..c6dacb9a68 --- /dev/null +++ b/api/karma.conf.js @@ -0,0 +1,8 @@ +const karmaWebpackConfig = require('./karma.webpack'); +const karmaBaseConfig = require('./karma.base'); + +module.exports = (config) => { + config.set(Object.assign({}, karmaBaseConfig, { + webpack: karmaWebpackConfig + })) +}; \ No newline at end of file diff --git a/api/karma.webpack.js b/api/karma.webpack.js new file mode 100644 index 0000000000..bc8eb3a790 --- /dev/null +++ b/api/karma.webpack.js @@ -0,0 +1,43 @@ +/*! + * 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 + * + * 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. + */ + +const webpackNodePolyfills = require('./webpack.node-polyfills.js'); + +// This is the webpack configuration for browser Karma tests with coverage. +module.exports = { + mode: 'development', + target: 'web', + output: { filename: 'bundle.js' }, + resolve: { extensions: ['.ts', '.js'] }, + devtool: 'inline-source-map', + module: { + rules: [ + { test: /\.ts$/, use: 'ts-loader' }, + { + enforce: 'post', + exclude: /(node_modules|\.test\.[tj]sx?$)/, + test: /\.ts$/, + use: { + loader: 'istanbul-instrumenter-loader', + options: { esModules: true } + } + }, + // This setting configures Node polyfills for the browser that will be + // added to the webpack bundle for Karma tests. + { parser: { node: webpackNodePolyfills } } + ] + } +}; diff --git a/api/package.json b/api/package.json new file mode 100644 index 0000000000..c0a475d890 --- /dev/null +++ b/api/package.json @@ -0,0 +1,90 @@ +{ + "name": "@opentelemetry/api", + "version": "1.2.0", + "description": "Public API for OpenTelemetry", + "main": "build/src/index.js", + "module": "build/esm/index.js", + "types": "build/src/index.d.ts", + "browser": { + "./src/platform/index.ts": "./src/platform/browser/index.ts", + "./build/esm/platform/index.js": "./build/esm/platform/browser/index.js", + "./build/src/platform/index.js": "./build/src/platform/browser/index.js" + }, + "repository": "https://github.com/open-telemetry/opentelemetry-js-api.git", + "scripts": { + "clean": "tsc --build --clean tsconfig.json tsconfig.esm.json", + "codecov:browser": "nyc report --reporter=json && codecov -f coverage/*.json -p .", + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p .", + "precompile": "npm run version", + "compile": "tsc --build tsconfig.json tsconfig.esm.json", + "docs": "typedoc", + "docs:deploy": "gh-pages --dist docs/out", + "docs:test": "linkinator docs/out --silent && linkinator docs/*.md *.md --markdown --silent", + "lint:fix": "eslint src test --ext .ts --fix", + "lint": "eslint src test --ext .ts", + "test:browser": "nyc karma start --single-run", + "test": "nyc ts-mocha -p tsconfig.json test/**/*.test.ts", + "cycle-check": "dpdm --exit-code circular:1 src/index.ts", + "version": "node scripts/version-update.js", + "prewatch": "npm run version", + "watch": "tsc --build --watch" + }, + "keywords": [ + "opentelemetry", + "nodejs", + "browser", + "tracing", + "profiling", + "stats", + "monitoring" + ], + "author": "OpenTelemetry Authors", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + }, + "files": [ + "build/esm/**/*.js", + "build/esm/**/*.js.map", + "build/esm/**/*.d.ts", + "build/src/**/*.js", + "build/src/**/*.js.map", + "build/src/**/*.d.ts", + "LICENSE", + "README.md" + ], + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "@types/mocha": "8.2.2", + "@types/node": "14.17.4", + "@types/sinon": "10.0.2", + "@types/webpack-env": "1.16.0", + "@typescript-eslint/eslint-plugin": "5.0.0", + "@typescript-eslint/parser": "5.0.0", + "codecov": "3.8.2", + "dpdm": "3.7.1", + "eslint": "7.32.0", + "eslint-plugin-header": "3.1.1", + "eslint-plugin-node": "11.1.0", + "gh-pages": "3.2.0", + "istanbul-instrumenter-loader": "3.0.1", + "karma": "5.2.3", + "karma-chrome-launcher": "3.1.0", + "karma-coverage-istanbul-reporter": "3.0.3", + "karma-mocha": "2.0.1", + "karma-spec-reporter": "0.0.32", + "karma-webpack": "4.0.2", + "lerna-changelog": "1.0.1", + "linkinator": "2.13.6", + "mocha": "7.2.0", + "nyc": "15.1.0", + "sinon": "11.1.1", + "ts-loader": "8.2.0", + "ts-mocha": "8.0.0", + "typedoc": "0.21.2", + "typescript": "4.3.5", + "webpack": "4.46.0" + } +} diff --git a/api/renovate.json b/api/renovate.json new file mode 100644 index 0000000000..f78c11be4a --- /dev/null +++ b/api/renovate.json @@ -0,0 +1,25 @@ +{ + "extends": [ + "config:base" + ], + "packageRules": [ + { + "groupName": "all non-major dependencies", + "updateTypes": ["patch", "minor"], + "groupSlug": "all-minor-patch" + } + ], + "ignoreDeps": [ + "gcp-metadata", + "got", + "mocha" + ], + "assignees": [ + "@dyladan", + "@vmarchaud" + ], + "schedule": [ + "before 3am on Friday" + ], + "labels": ["dependencies"] +} diff --git a/api/scripts/version-update.js b/api/scripts/version-update.js new file mode 100644 index 0000000000..4e22aa900b --- /dev/null +++ b/api/scripts/version-update.js @@ -0,0 +1,48 @@ +/* + * 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. + */ + +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +const appRoot = process.cwd(); + +const packageJsonUrl = path.resolve(`${appRoot}/package.json`); +const pjson = require(packageJsonUrl); + +const content = `/* + * 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. + */ + +// this is autogenerated file, see scripts/version-update.js +export const VERSION = '${pjson.version}'; +`; + +const fileUrl = path.join(appRoot, "src", "version.ts") + +fs.writeFileSync(fileUrl, content); \ No newline at end of file diff --git a/api/src/api/context.ts b/api/src/api/context.ts new file mode 100644 index 0000000000..6631dea8f1 --- /dev/null +++ b/api/src/api/context.ts @@ -0,0 +1,99 @@ +/* + * 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 { NoopContextManager } from '../context/NoopContextManager'; +import { Context, ContextManager } from '../context/types'; +import { + getGlobal, + registerGlobal, + unregisterGlobal, +} from '../internal/global-utils'; +import { DiagAPI } from './diag'; + +const API_NAME = 'context'; +const NOOP_CONTEXT_MANAGER = new NoopContextManager(); + +/** + * Singleton object which represents the entry point to the OpenTelemetry Context API + */ +export class ContextAPI { + private static _instance?: ContextAPI; + + /** Empty private constructor prevents end users from constructing a new instance of the API */ + private constructor() {} + + /** Get the singleton instance of the Context API */ + public static getInstance(): ContextAPI { + if (!this._instance) { + this._instance = new ContextAPI(); + } + + return this._instance; + } + + /** + * Set the current context manager. + * + * @returns true if the context manager was successfully registered, else false + */ + public setGlobalContextManager(contextManager: ContextManager): boolean { + return registerGlobal(API_NAME, contextManager, DiagAPI.instance()); + } + + /** + * Get the currently active context + */ + public active(): Context { + return this._getContextManager().active(); + } + + /** + * Execute a function with an active context + * + * @param context context to be active during function execution + * @param fn function to execute in a context + * @param thisArg optional receiver to be used for calling fn + * @param args optional arguments forwarded to fn + */ + public with ReturnType>( + context: Context, + fn: F, + thisArg?: ThisParameterType, + ...args: A + ): ReturnType { + return this._getContextManager().with(context, fn, thisArg, ...args); + } + + /** + * Bind a context to a target function or event emitter + * + * @param context context to bind to the event emitter or function. Defaults to the currently active context + * @param target function or event emitter to bind + */ + public bind(context: Context, target: T): T { + return this._getContextManager().bind(context, target); + } + + private _getContextManager(): ContextManager { + return getGlobal(API_NAME) || NOOP_CONTEXT_MANAGER; + } + + /** Disable and remove the global context manager */ + public disable() { + this._getContextManager().disable(); + unregisterGlobal(API_NAME, DiagAPI.instance()); + } +} diff --git a/api/src/api/diag.ts b/api/src/api/diag.ts new file mode 100644 index 0000000000..3fd1027a62 --- /dev/null +++ b/api/src/api/diag.ts @@ -0,0 +1,139 @@ +/* + * 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 { DiagComponentLogger } from '../diag/ComponentLogger'; +import { createLogLevelDiagLogger } from '../diag/internal/logLevelLogger'; +import { + ComponentLoggerOptions, + DiagLogFunction, + DiagLogger, + DiagLogLevel, +} from '../diag/types'; +import { + getGlobal, + registerGlobal, + unregisterGlobal, +} from '../internal/global-utils'; + +const API_NAME = 'diag'; + +/** + * Singleton object which represents the entry point to the OpenTelemetry internal + * diagnostic API + */ +export class DiagAPI implements DiagLogger { + private static _instance?: DiagAPI; + + /** Get the singleton instance of the DiagAPI API */ + public static instance(): DiagAPI { + if (!this._instance) { + this._instance = new DiagAPI(); + } + + return this._instance; + } + + /** + * Private internal constructor + * @private + */ + private constructor() { + function _logProxy(funcName: keyof DiagLogger): DiagLogFunction { + return function (...args) { + const logger = getGlobal('diag'); + // shortcut if logger not set + if (!logger) return; + return logger[funcName](...args); + }; + } + + // Using self local variable for minification purposes as 'this' cannot be minified + const self = this; + + // DiagAPI specific functions + + self.setLogger = ( + logger: DiagLogger, + logLevel: DiagLogLevel = DiagLogLevel.INFO + ) => { + if (logger === self) { + // There isn't much we can do here. + // Logging to the console might break the user application. + // Try to log to self. If a logger was previously registered it will receive the log. + const err = new Error( + 'Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation' + ); + self.error(err.stack ?? err.message); + return false; + } + + const oldLogger = getGlobal('diag'); + const newLogger = createLogLevelDiagLogger(logLevel, logger); + // There already is an logger registered. We'll let it know before overwriting it. + if (oldLogger) { + const stack = new Error().stack ?? ''; + oldLogger.warn(`Current logger will be overwritten from ${stack}`); + newLogger.warn( + `Current logger will overwrite one already registered from ${stack}` + ); + } + + return registerGlobal('diag', newLogger, self, true); + }; + + self.disable = () => { + unregisterGlobal(API_NAME, self); + }; + + self.createComponentLogger = (options: ComponentLoggerOptions) => { + return new DiagComponentLogger(options); + }; + + self.verbose = _logProxy('verbose'); + self.debug = _logProxy('debug'); + self.info = _logProxy('info'); + self.warn = _logProxy('warn'); + self.error = _logProxy('error'); + } + + /** + * Set the global DiagLogger and DiagLogLevel. + * If a global diag logger is already set, this will override it. + * + * @param logger - [Optional] The DiagLogger instance to set as the default logger. + * @param logLevel - [Optional] The DiagLogLevel used to filter logs sent to the logger. If not provided it will default to INFO. + * @returns true if the logger was successfully registered, else false + */ + public setLogger!: (logger: DiagLogger, logLevel?: DiagLogLevel) => boolean; + /** + * + */ + public createComponentLogger!: ( + options: ComponentLoggerOptions + ) => DiagLogger; + + // DiagLogger implementation + public verbose!: DiagLogFunction; + public debug!: DiagLogFunction; + public info!: DiagLogFunction; + public warn!: DiagLogFunction; + public error!: DiagLogFunction; + + /** + * Unregister the global logger and return to Noop + */ + public disable!: () => void; +} diff --git a/api/src/api/propagation.ts b/api/src/api/propagation.ts new file mode 100644 index 0000000000..2cd9aec760 --- /dev/null +++ b/api/src/api/propagation.ts @@ -0,0 +1,122 @@ +/* + * 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 } from '../context/types'; +import { + getGlobal, + registerGlobal, + unregisterGlobal, +} from '../internal/global-utils'; +import { NoopTextMapPropagator } from '../propagation/NoopTextMapPropagator'; +import { + defaultTextMapGetter, + defaultTextMapSetter, + TextMapGetter, + TextMapPropagator, + TextMapSetter, +} from '../propagation/TextMapPropagator'; +import { + getBaggage, + setBaggage, + deleteBaggage, +} from '../baggage/context-helpers'; +import { createBaggage } from '../baggage/utils'; +import { DiagAPI } from './diag'; + +const API_NAME = 'propagation'; +const NOOP_TEXT_MAP_PROPAGATOR = new NoopTextMapPropagator(); + +/** + * Singleton object which represents the entry point to the OpenTelemetry Propagation API + */ +export class PropagationAPI { + private static _instance?: PropagationAPI; + + /** Empty private constructor prevents end users from constructing a new instance of the API */ + private constructor() {} + + /** Get the singleton instance of the Propagator API */ + public static getInstance(): PropagationAPI { + if (!this._instance) { + this._instance = new PropagationAPI(); + } + + return this._instance; + } + + /** + * Set the current propagator. + * + * @returns true if the propagator was successfully registered, else false + */ + public setGlobalPropagator(propagator: TextMapPropagator): boolean { + return registerGlobal(API_NAME, propagator, DiagAPI.instance()); + } + + /** + * Inject context into a carrier to be propagated inter-process + * + * @param context Context carrying tracing data to inject + * @param carrier carrier to inject context into + * @param setter Function used to set values on the carrier + */ + public inject( + context: Context, + carrier: Carrier, + setter: TextMapSetter = defaultTextMapSetter + ): void { + return this._getGlobalPropagator().inject(context, carrier, setter); + } + + /** + * Extract context from a carrier + * + * @param context Context which the newly created context will inherit from + * @param carrier Carrier to extract context from + * @param getter Function used to extract keys from a carrier + */ + public extract( + context: Context, + carrier: Carrier, + getter: TextMapGetter = defaultTextMapGetter + ): Context { + return this._getGlobalPropagator().extract(context, carrier, getter); + } + + /** + * Return a list of all fields which may be used by the propagator. + */ + public fields(): string[] { + return this._getGlobalPropagator().fields(); + } + + /** Remove the global propagator */ + public disable() { + unregisterGlobal(API_NAME, DiagAPI.instance()); + } + + public createBaggage = createBaggage; + + public getBaggage = getBaggage; + + public setBaggage = setBaggage; + + public deleteBaggage = deleteBaggage; + + private _getGlobalPropagator(): TextMapPropagator { + return getGlobal(API_NAME) || NOOP_TEXT_MAP_PROPAGATOR; + } +} diff --git a/api/src/api/trace.ts b/api/src/api/trace.ts new file mode 100644 index 0000000000..492c16b5ba --- /dev/null +++ b/api/src/api/trace.ts @@ -0,0 +1,113 @@ +/* + * 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 { + getGlobal, + registerGlobal, + unregisterGlobal, +} from '../internal/global-utils'; +import { ProxyTracerProvider } from '../trace/ProxyTracerProvider'; +import { + isSpanContextValid, + wrapSpanContext, +} from '../trace/spancontext-utils'; +import { Tracer } from '../trace/tracer'; +import { TracerProvider } from '../trace/tracer_provider'; +import { + deleteSpan, + getActiveSpan, + getSpan, + getSpanContext, + setSpan, + setSpanContext, +} from '../trace/context-utils'; +import { DiagAPI } from './diag'; + +const API_NAME = 'trace'; + +/** + * Singleton object which represents the entry point to the OpenTelemetry Tracing API + */ +export class TraceAPI { + private static _instance?: TraceAPI; + + private _proxyTracerProvider = new ProxyTracerProvider(); + + /** Empty private constructor prevents end users from constructing a new instance of the API */ + private constructor() {} + + /** Get the singleton instance of the Trace API */ + public static getInstance(): TraceAPI { + if (!this._instance) { + this._instance = new TraceAPI(); + } + + return this._instance; + } + + /** + * Set the current global tracer. + * + * @returns true if the tracer provider was successfully registered, else false + */ + public setGlobalTracerProvider(provider: TracerProvider): boolean { + const success = registerGlobal( + API_NAME, + this._proxyTracerProvider, + DiagAPI.instance() + ); + if (success) { + this._proxyTracerProvider.setDelegate(provider); + } + return success; + } + + /** + * Returns the global tracer provider. + */ + public getTracerProvider(): TracerProvider { + return getGlobal(API_NAME) || this._proxyTracerProvider; + } + + /** + * Returns a tracer from the global tracer provider. + */ + public getTracer(name: string, version?: string): Tracer { + return this.getTracerProvider().getTracer(name, version); + } + + /** Remove the global tracer provider */ + public disable() { + unregisterGlobal(API_NAME, DiagAPI.instance()); + this._proxyTracerProvider = new ProxyTracerProvider(); + } + + public wrapSpanContext = wrapSpanContext; + + public isSpanContextValid = isSpanContextValid; + + public deleteSpan = deleteSpan; + + public getSpan = getSpan; + + public getActiveSpan = getActiveSpan; + + public getSpanContext = getSpanContext; + + public setSpan = setSpan; + + public setSpanContext = setSpanContext; +} diff --git a/api/src/baggage/context-helpers.ts b/api/src/baggage/context-helpers.ts new file mode 100644 index 0000000000..ae7b4a78e0 --- /dev/null +++ b/api/src/baggage/context-helpers.ts @@ -0,0 +1,53 @@ +/* + * 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 { createContextKey } from '../context/context'; +import { Context } from '../context/types'; +import { Baggage } from './types'; + +/** + * Baggage key + */ +const BAGGAGE_KEY = createContextKey('OpenTelemetry Baggage Key'); + +/** + * Retrieve the current baggage from the given context + * + * @param {Context} Context that manage all context values + * @returns {Baggage} Extracted baggage from the context + */ +export function getBaggage(context: Context): Baggage | undefined { + return (context.getValue(BAGGAGE_KEY) as Baggage) || undefined; +} + +/** + * Store a baggage in the given context + * + * @param {Context} Context that manage all context values + * @param {Baggage} baggage that will be set in the actual context + */ +export function setBaggage(context: Context, baggage: Baggage): Context { + return context.setValue(BAGGAGE_KEY, baggage); +} + +/** + * Delete the baggage stored in the given context + * + * @param {Context} Context that manage all context values + */ +export function deleteBaggage(context: Context): Context { + return context.deleteValue(BAGGAGE_KEY); +} diff --git a/api/src/baggage/internal/baggage-impl.ts b/api/src/baggage/internal/baggage-impl.ts new file mode 100644 index 0000000000..8bd45dd4b9 --- /dev/null +++ b/api/src/baggage/internal/baggage-impl.ts @@ -0,0 +1,62 @@ +/* + * 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 type { Baggage, BaggageEntry } from '../types'; + +export class BaggageImpl implements Baggage { + private _entries: Map; + + constructor(entries?: Map) { + this._entries = entries ? new Map(entries) : new Map(); + } + + getEntry(key: string): BaggageEntry | undefined { + const entry = this._entries.get(key); + if (!entry) { + return undefined; + } + + return Object.assign({}, entry); + } + + getAllEntries(): [string, BaggageEntry][] { + return Array.from(this._entries.entries()).map(([k, v]) => [k, v]); + } + + setEntry(key: string, entry: BaggageEntry): BaggageImpl { + const newBaggage = new BaggageImpl(this._entries); + newBaggage._entries.set(key, entry); + return newBaggage; + } + + removeEntry(key: string): BaggageImpl { + const newBaggage = new BaggageImpl(this._entries); + newBaggage._entries.delete(key); + return newBaggage; + } + + removeEntries(...keys: string[]): BaggageImpl { + const newBaggage = new BaggageImpl(this._entries); + for (const key of keys) { + newBaggage._entries.delete(key); + } + return newBaggage; + } + + clear(): BaggageImpl { + return new BaggageImpl(); + } +} diff --git a/api/src/baggage/internal/symbol.ts b/api/src/baggage/internal/symbol.ts new file mode 100644 index 0000000000..f4213926c9 --- /dev/null +++ b/api/src/baggage/internal/symbol.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Symbol used to make BaggageEntryMetadata an opaque type + */ +export const baggageEntryMetadataSymbol = Symbol('BaggageEntryMetadata'); diff --git a/api/src/baggage/types.ts b/api/src/baggage/types.ts new file mode 100644 index 0000000000..ab6d82e651 --- /dev/null +++ b/api/src/baggage/types.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 { baggageEntryMetadataSymbol } from './internal/symbol'; + +/* + * 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. + */ + +export interface BaggageEntry { + /** `String` value of the `BaggageEntry`. */ + value: string; + /** + * Metadata is an optional string property defined by the W3C baggage specification. + * It currently has no special meaning defined by the specification. + */ + metadata?: BaggageEntryMetadata; +} + +/** + * Serializable Metadata defined by the W3C baggage specification. + * It currently has no special meaning defined by the OpenTelemetry or W3C. + */ +export type BaggageEntryMetadata = { toString(): string } & { + __TYPE__: typeof baggageEntryMetadataSymbol; +}; + +/** + * Baggage represents collection of key-value pairs with optional metadata. + * Each key of Baggage is associated with exactly one value. + * Baggage may be used to annotate and enrich telemetry data. + */ +export interface Baggage { + /** + * Get an entry from Baggage if it exists + * + * @param key The key which identifies the BaggageEntry + */ + getEntry(key: string): BaggageEntry | undefined; + + /** + * Get a list of all entries in the Baggage + */ + getAllEntries(): [string, BaggageEntry][]; + + /** + * Returns a new baggage with the entries from the current bag and the specified entry + * + * @param key string which identifies the baggage entry + * @param entry BaggageEntry for the given key + */ + setEntry(key: string, entry: BaggageEntry): Baggage; + + /** + * Returns a new baggage with the entries from the current bag except the removed entry + * + * @param key key identifying the entry to be removed + */ + removeEntry(key: string): Baggage; + + /** + * Returns a new baggage with the entries from the current bag except the removed entries + * + * @param key keys identifying the entries to be removed + */ + removeEntries(...key: string[]): Baggage; + + /** + * Returns a new baggage with no entries + */ + clear(): Baggage; +} diff --git a/api/src/baggage/utils.ts b/api/src/baggage/utils.ts new file mode 100644 index 0000000000..80b87890f6 --- /dev/null +++ b/api/src/baggage/utils.ts @@ -0,0 +1,57 @@ +/* + * 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 { DiagAPI } from '../api/diag'; +import { BaggageImpl } from './internal/baggage-impl'; +import { baggageEntryMetadataSymbol } from './internal/symbol'; +import { Baggage, BaggageEntry, BaggageEntryMetadata } from './types'; + +const diag = DiagAPI.instance(); + +/** + * Create a new Baggage with optional entries + * + * @param entries An array of baggage entries the new baggage should contain + */ +export function createBaggage( + entries: Record = {} +): Baggage { + return new BaggageImpl(new Map(Object.entries(entries))); +} + +/** + * Create a serializable BaggageEntryMetadata object from a string. + * + * @param str string metadata. Format is currently not defined by the spec and has no special meaning. + * + */ +export function baggageEntryMetadataFromString( + str: string +): BaggageEntryMetadata { + if (typeof str !== 'string') { + diag.error( + `Cannot create baggage metadata from unknown type: ${typeof str}` + ); + str = ''; + } + + return { + __TYPE__: baggageEntryMetadataSymbol, + toString() { + return str; + }, + }; +} diff --git a/api/src/common/Attributes.ts b/api/src/common/Attributes.ts new file mode 100644 index 0000000000..f3bdfe461c --- /dev/null +++ b/api/src/common/Attributes.ts @@ -0,0 +1,37 @@ +/* + * 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. + */ + +/** + * Attributes is a map from string to attribute values. + * + * Note: only the own enumerable keys are counted as valid attribute keys. + */ +export interface Attributes { + [attributeKey: string]: AttributeValue | undefined; +} + +/** + * Attribute values may be any non-nullish primitive value except an object. + * + * null or undefined attribute values are invalid and will result in undefined behavior. + */ +export type AttributeValue = + | string + | number + | boolean + | Array + | Array + | Array; diff --git a/api/src/common/Exception.ts b/api/src/common/Exception.ts new file mode 100644 index 0000000000..5539b7e9f3 --- /dev/null +++ b/api/src/common/Exception.ts @@ -0,0 +1,47 @@ +/* + * 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. + */ + +interface ExceptionWithCode { + code: string | number; + name?: string; + message?: string; + stack?: string; +} + +interface ExceptionWithMessage { + code?: string | number; + message: string; + name?: string; + stack?: string; +} + +interface ExceptionWithName { + code?: string | number; + message?: string; + name: string; + stack?: string; +} + +/** + * Defines Exception. + * + * string or an object with one of (message or name or code) and optional stack + */ +export type Exception = + | ExceptionWithCode + | ExceptionWithMessage + | ExceptionWithName + | string; diff --git a/api/src/common/Time.ts b/api/src/common/Time.ts new file mode 100644 index 0000000000..4ed60a1e70 --- /dev/null +++ b/api/src/common/Time.ts @@ -0,0 +1,35 @@ +/* + * 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. + */ +/** + * Defines High-Resolution Time. + * + * The first number, HrTime[0], is UNIX Epoch time in seconds since 00:00:00 UTC on 1 January 1970. + * The second number, HrTime[1], represents the partial second elapsed since Unix Epoch time represented by first number in nanoseconds. + * For example, 2021-01-01T12:30:10.150Z in UNIX Epoch time in milliseconds is represented as 1609504210150. + * The first number is calculated by converting and truncating the Epoch time in milliseconds to seconds: + * HrTime[0] = Math.trunc(1609504210150 / 1000) = 1609504210. + * The second number is calculated by converting the digits after the decimal point of the subtraction, (1609504210150 / 1000) - HrTime[0], to nanoseconds: + * HrTime[1] = Number((1609504210.150 - HrTime[0]).toFixed(9)) * 1e9 = 150000000. + * This is represented in HrTime format as [1609504210, 150000000]. + */ +export type HrTime = [number, number]; + +/** + * Defines TimeInput. + * + * hrtime, epoch milliseconds, performance.now() or Date + */ +export type TimeInput = HrTime | number | Date; diff --git a/api/src/context/NoopContextManager.ts b/api/src/context/NoopContextManager.ts new file mode 100644 index 0000000000..a62a89d33c --- /dev/null +++ b/api/src/context/NoopContextManager.ts @@ -0,0 +1,45 @@ +/* + * 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 { ROOT_CONTEXT } from './context'; +import * as types from './types'; + +export class NoopContextManager implements types.ContextManager { + active(): types.Context { + return ROOT_CONTEXT; + } + + with ReturnType>( + _context: types.Context, + fn: F, + thisArg?: ThisParameterType, + ...args: A + ): ReturnType { + return fn.call(thisArg, ...args); + } + + bind(_context: types.Context, target: T): T { + return target; + } + + enable(): this { + return this; + } + + disable(): this { + return this; + } +} diff --git a/api/src/context/context.ts b/api/src/context/context.ts new file mode 100644 index 0000000000..825726f36f --- /dev/null +++ b/api/src/context/context.ts @@ -0,0 +1,85 @@ +/* + * 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 } from './types'; + +/** Get a key to uniquely identify a context value */ +export function createContextKey(description: string) { + // The specification states that for the same input, multiple calls should + // return different keys. Due to the nature of the JS dependency management + // system, this creates problems where multiple versions of some package + // could hold different keys for the same property. + // + // Therefore, we use Symbol.for which returns the same key for the same input. + return Symbol.for(description); +} + +class BaseContext implements Context { + private _currentContext!: Map; + + /** + * Construct a new context which inherits values from an optional parent context. + * + * @param parentContext a context from which to inherit values + */ + constructor(parentContext?: Map) { + // for minification + const self = this; + + self._currentContext = parentContext ? new Map(parentContext) : new Map(); + + self.getValue = (key: symbol) => self._currentContext.get(key); + + self.setValue = (key: symbol, value: unknown): Context => { + const context = new BaseContext(self._currentContext); + context._currentContext.set(key, value); + return context; + }; + + self.deleteValue = (key: symbol): Context => { + const context = new BaseContext(self._currentContext); + context._currentContext.delete(key); + return context; + }; + } + + /** + * Get a value from the context. + * + * @param key key which identifies a context value + */ + public getValue!: (key: symbol) => unknown; + + /** + * Create a new context which inherits from this context and has + * the given key set to the given value. + * + * @param key context key for which to set the value + * @param value value to set for the given key + */ + public setValue!: (key: symbol, value: unknown) => Context; + + /** + * Return a new context which inherits from this context but does + * not contain a value for the given key. + * + * @param key context key for which to clear a value + */ + public deleteValue!: (key: symbol) => Context; +} + +/** The root context is used as the default parent context when there is no active context */ +export const ROOT_CONTEXT: Context = new BaseContext(); diff --git a/api/src/context/types.ts b/api/src/context/types.ts new file mode 100644 index 0000000000..19ae6d9d65 --- /dev/null +++ b/api/src/context/types.ts @@ -0,0 +1,79 @@ +/* + * 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. + */ + +export interface Context { + /** + * Get a value from the context. + * + * @param key key which identifies a context value + */ + getValue(key: symbol): unknown; + + /** + * Create a new context which inherits from this context and has + * the given key set to the given value. + * + * @param key context key for which to set the value + * @param value value to set for the given key + */ + setValue(key: symbol, value: unknown): Context; + + /** + * Return a new context which inherits from this context but does + * not contain a value for the given key. + * + * @param key context key for which to clear a value + */ + deleteValue(key: symbol): Context; +} + +export interface ContextManager { + /** + * Get the current active context + */ + active(): Context; + + /** + * Run the fn callback with object set as the current active context + * @param context Any object to set as the current active context + * @param fn A callback to be immediately run within a specific context + * @param thisArg optional receiver to be used for calling fn + * @param args optional arguments forwarded to fn + */ + with ReturnType>( + context: Context, + fn: F, + thisArg?: ThisParameterType, + ...args: A + ): ReturnType; + + /** + * Bind an object as the current context (or a specific one) + * @param [context] Optionally specify the context which you want to assign + * @param target Any object to which a context need to be set + */ + bind(context: Context, target: T): T; + + /** + * Enable context management + */ + enable(): this; + + /** + * Disable context management + */ + disable(): this; +} diff --git a/api/src/diag/ComponentLogger.ts b/api/src/diag/ComponentLogger.ts new file mode 100644 index 0000000000..2253501863 --- /dev/null +++ b/api/src/diag/ComponentLogger.ts @@ -0,0 +1,70 @@ +/* + * 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 { getGlobal } from '../internal/global-utils'; +import { ComponentLoggerOptions, DiagLogger, DiagLogFunction } from './types'; + +/** + * Component Logger which is meant to be used as part of any component which + * will add automatically additional namespace in front of the log message. + * It will then forward all message to global diag logger + * @example + * const cLogger = diag.createComponentLogger({ namespace: '@opentelemetry/instrumentation-http' }); + * cLogger.debug('test'); + * // @opentelemetry/instrumentation-http test + */ +export class DiagComponentLogger implements DiagLogger { + private _namespace: string; + + constructor(props: ComponentLoggerOptions) { + this._namespace = props.namespace || 'DiagComponentLogger'; + } + + public debug(...args: any[]): void { + return logProxy('debug', this._namespace, args); + } + + public error(...args: any[]): void { + return logProxy('error', this._namespace, args); + } + + public info(...args: any[]): void { + return logProxy('info', this._namespace, args); + } + + public warn(...args: any[]): void { + return logProxy('warn', this._namespace, args); + } + + public verbose(...args: any[]): void { + return logProxy('verbose', this._namespace, args); + } +} + +function logProxy( + funcName: keyof DiagLogger, + namespace: string, + args: any +): void { + const logger = getGlobal('diag'); + // shortcut if logger not set + if (!logger) { + return; + } + + args.unshift(namespace); + return logger[funcName](...(args as Parameters)); +} diff --git a/api/src/diag/consoleLogger.ts b/api/src/diag/consoleLogger.ts new file mode 100644 index 0000000000..76e9855732 --- /dev/null +++ b/api/src/diag/consoleLogger.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 { DiagLogger, DiagLogFunction } from './types'; + +type ConsoleMapKeys = 'error' | 'warn' | 'info' | 'debug' | 'trace'; +const consoleMap: { n: keyof DiagLogger; c: ConsoleMapKeys }[] = [ + { n: 'error', c: 'error' }, + { n: 'warn', c: 'warn' }, + { n: 'info', c: 'info' }, + { n: 'debug', c: 'debug' }, + { n: 'verbose', c: 'trace' }, +]; + +/** + * A simple Immutable Console based diagnostic logger which will output any messages to the Console. + * If you want to limit the amount of logging to a specific level or lower use the + * {@link createLogLevelDiagLogger} + */ +export class DiagConsoleLogger implements DiagLogger { + constructor() { + function _consoleFunc(funcName: ConsoleMapKeys): DiagLogFunction { + return function (...args) { + if (console) { + // Some environments only expose the console when the F12 developer console is open + // eslint-disable-next-line no-console + let theFunc = console[funcName]; + if (typeof theFunc !== 'function') { + // Not all environments support all functions + // eslint-disable-next-line no-console + theFunc = console.log; + } + + // One last final check + if (typeof theFunc === 'function') { + return theFunc.apply(console, args); + } + } + }; + } + + for (let i = 0; i < consoleMap.length; i++) { + this[consoleMap[i].n] = _consoleFunc(consoleMap[i].c); + } + } + + /** Log an error scenario that was not expected and caused the requested operation to fail. */ + public error!: DiagLogFunction; + + /** + * Log a warning scenario to inform the developer of an issues that should be investigated. + * The requested operation may or may not have succeeded or completed. + */ + public warn!: DiagLogFunction; + + /** + * Log a general informational message, this should not affect functionality. + * This is also the default logging level so this should NOT be used for logging + * debugging level information. + */ + public info!: DiagLogFunction; + + /** + * Log a general debug message that can be useful for identifying a failure. + * Information logged at this level may include diagnostic details that would + * help identify a failure scenario. Useful scenarios would be to log the execution + * order of async operations + */ + public debug!: DiagLogFunction; + + /** + * Log a detailed (verbose) trace level logging that can be used to identify failures + * where debug level logging would be insufficient, this level of tracing can include + * input and output parameters and as such may include PII information passing through + * the API. As such it is recommended that this level of tracing should not be enabled + * in a production environment. + */ + public verbose!: DiagLogFunction; +} diff --git a/api/src/diag/index.ts b/api/src/diag/index.ts new file mode 100644 index 0000000000..751b5eeda2 --- /dev/null +++ b/api/src/diag/index.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export * from './consoleLogger'; +export * from './types'; diff --git a/api/src/diag/internal/logLevelLogger.ts b/api/src/diag/internal/logLevelLogger.ts new file mode 100644 index 0000000000..e9205b3642 --- /dev/null +++ b/api/src/diag/internal/logLevelLogger.ts @@ -0,0 +1,51 @@ +/* + * 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 { DiagLogFunction, DiagLogger, DiagLogLevel } from '../types'; + +export function createLogLevelDiagLogger( + maxLevel: DiagLogLevel, + logger: DiagLogger +): DiagLogger { + if (maxLevel < DiagLogLevel.NONE) { + maxLevel = DiagLogLevel.NONE; + } else if (maxLevel > DiagLogLevel.ALL) { + maxLevel = DiagLogLevel.ALL; + } + + // In case the logger is null or undefined + logger = logger || {}; + + function _filterFunc( + funcName: keyof DiagLogger, + theLevel: DiagLogLevel + ): DiagLogFunction { + const theFunc = logger[funcName]; + + if (typeof theFunc === 'function' && maxLevel >= theLevel) { + return theFunc.bind(logger); + } + return function () {}; + } + + return { + error: _filterFunc('error', DiagLogLevel.ERROR), + warn: _filterFunc('warn', DiagLogLevel.WARN), + info: _filterFunc('info', DiagLogLevel.INFO), + debug: _filterFunc('debug', DiagLogLevel.DEBUG), + verbose: _filterFunc('verbose', DiagLogLevel.VERBOSE), + }; +} diff --git a/api/src/diag/internal/noopLogger.ts b/api/src/diag/internal/noopLogger.ts new file mode 100644 index 0000000000..0c4e7d13b0 --- /dev/null +++ b/api/src/diag/internal/noopLogger.ts @@ -0,0 +1,34 @@ +/* + * 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 { DiagLogger } from '../types'; + +function noopLogFunction() {} + +/** + * Returns a No-Op Diagnostic logger where all messages do nothing. + * @implements {@link DiagLogger} + * @returns {DiagLogger} + */ +export function createNoopDiagLogger(): DiagLogger { + return { + verbose: noopLogFunction, + debug: noopLogFunction, + info: noopLogFunction, + warn: noopLogFunction, + error: noopLogFunction, + }; +} diff --git a/api/src/diag/types.ts b/api/src/diag/types.ts new file mode 100644 index 0000000000..54bf398d01 --- /dev/null +++ b/api/src/diag/types.ts @@ -0,0 +1,98 @@ +/* + * 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. + */ + +export type DiagLogFunction = (message: string, ...args: unknown[]) => void; + +/** + * Defines an internal diagnostic logger interface which is used to log internal diagnostic + * messages, you can set the default diagnostic logger via the {@link DiagAPI} setLogger function. + * API provided implementations include :- + * - a No-Op {@link createNoopDiagLogger} + * - a {@link DiagLogLevel} filtering wrapper {@link createLogLevelDiagLogger} + * - a general Console {@link DiagConsoleLogger} version. + */ +export interface DiagLogger { + /** Log an error scenario that was not expected and caused the requested operation to fail. */ + error: DiagLogFunction; + + /** + * Log a warning scenario to inform the developer of an issues that should be investigated. + * The requested operation may or may not have succeeded or completed. + */ + warn: DiagLogFunction; + + /** + * Log a general informational message, this should not affect functionality. + * This is also the default logging level so this should NOT be used for logging + * debugging level information. + */ + info: DiagLogFunction; + + /** + * Log a general debug message that can be useful for identifying a failure. + * Information logged at this level may include diagnostic details that would + * help identify a failure scenario. + * For example: Logging the order of execution of async operations. + */ + debug: DiagLogFunction; + + /** + * Log a detailed (verbose) trace level logging that can be used to identify failures + * where debug level logging would be insufficient, this level of tracing can include + * input and output parameters and as such may include PII information passing through + * the API. As such it is recommended that this level of tracing should not be enabled + * in a production environment. + */ + verbose: DiagLogFunction; +} + +/** + * Defines the available internal logging levels for the diagnostic logger, the numeric values + * of the levels are defined to match the original values from the initial LogLevel to avoid + * compatibility/migration issues for any implementation that assume the numeric ordering. + */ +export enum DiagLogLevel { + /** Diagnostic Logging level setting to disable all logging (except and forced logs) */ + NONE = 0, + + /** Identifies an error scenario */ + ERROR = 30, + + /** Identifies a warning scenario */ + WARN = 50, + + /** General informational log message */ + INFO = 60, + + /** General debug log message */ + DEBUG = 70, + + /** + * Detailed trace level logging should only be used for development, should only be set + * in a development environment. + */ + VERBOSE = 80, + + /** Used to set the logging level to include all logging */ + ALL = 9999, +} + +/** + * Defines options for ComponentLogger + */ +export interface ComponentLoggerOptions { + namespace: string; +} diff --git a/api/src/index.ts b/api/src/index.ts new file mode 100644 index 0000000000..72825b0806 --- /dev/null +++ b/api/src/index.ts @@ -0,0 +1,88 @@ +/* + * 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. + */ + +export * from './baggage/types'; +export { baggageEntryMetadataFromString } from './baggage/utils'; +export * from './common/Exception'; +export * from './common/Time'; +export * from './common/Attributes'; +export * from './diag'; +export * from './propagation/TextMapPropagator'; +export * from './trace/attributes'; +export * from './trace/link'; +export * from './trace/ProxyTracer'; +export * from './trace/ProxyTracerProvider'; +export * from './trace/Sampler'; +export * from './trace/SamplingResult'; +export * from './trace/span_context'; +export * from './trace/span_kind'; +export * from './trace/span'; +export * from './trace/SpanOptions'; +export * from './trace/status'; +export * from './trace/trace_flags'; +export * from './trace/trace_state'; +export { createTraceState } from './trace/internal/utils'; +export * from './trace/tracer_provider'; +export * from './trace/tracer'; +export * from './trace/tracer_options'; + +export { + isSpanContextValid, + isValidTraceId, + isValidSpanId, +} from './trace/spancontext-utils'; + +export { + INVALID_SPANID, + INVALID_TRACEID, + INVALID_SPAN_CONTEXT, +} from './trace/invalid-span-constants'; + +export * from './context/context'; +export * from './context/types'; + +import { ContextAPI } from './api/context'; +export type { ContextAPI } from './api/context'; +/** Entrypoint for context API */ +export const context = ContextAPI.getInstance(); + +import { TraceAPI } from './api/trace'; +export type { TraceAPI } from './api/trace'; +/** Entrypoint for trace API */ +export const trace = TraceAPI.getInstance(); + +import { PropagationAPI } from './api/propagation'; +export type { PropagationAPI } from './api/propagation'; +/** Entrypoint for propagation API */ +export const propagation = PropagationAPI.getInstance(); + +import { DiagAPI } from './api/diag'; +export type { DiagAPI } from './api/diag'; + +/** + * Entrypoint for Diag API. + * Defines Diagnostic handler used for internal diagnostic logging operations. + * The default provides a Noop DiagLogger implementation which may be changed via the + * diag.setLogger(logger: DiagLogger) function. + */ +export const diag = DiagAPI.instance(); + +export default { + trace, + context, + propagation, + diag, +}; diff --git a/api/src/internal/global-utils.ts b/api/src/internal/global-utils.ts new file mode 100644 index 0000000000..5306aa503b --- /dev/null +++ b/api/src/internal/global-utils.ts @@ -0,0 +1,102 @@ +/* + * 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 { ContextManager } from '../context/types'; +import { DiagLogger } from '../diag'; +import { _globalThis } from '../platform'; +import { TextMapPropagator } from '../propagation/TextMapPropagator'; +import type { TracerProvider } from '../trace/tracer_provider'; +import { VERSION } from '../version'; +import { isCompatible } from './semver'; + +const major = VERSION.split('.')[0]; +const GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for( + `opentelemetry.js.api.${major}` +); + +const _global = _globalThis as OTelGlobal; + +export function registerGlobal( + type: Type, + instance: OTelGlobalAPI[Type], + diag: DiagLogger, + allowOverride = false +): boolean { + const api = (_global[GLOBAL_OPENTELEMETRY_API_KEY] = _global[ + GLOBAL_OPENTELEMETRY_API_KEY + ] ?? { + version: VERSION, + }); + + if (!allowOverride && api[type]) { + // already registered an API of this type + const err = new Error( + `@opentelemetry/api: Attempted duplicate registration of API: ${type}` + ); + diag.error(err.stack || err.message); + return false; + } + + if (api.version !== VERSION) { + // All registered APIs must be of the same version exactly + const err = new Error( + '@opentelemetry/api: All API registration versions must match' + ); + diag.error(err.stack || err.message); + return false; + } + + api[type] = instance; + diag.debug( + `@opentelemetry/api: Registered a global for ${type} v${VERSION}.` + ); + + return true; +} + +export function getGlobal( + type: Type +): OTelGlobalAPI[Type] | undefined { + const globalVersion = _global[GLOBAL_OPENTELEMETRY_API_KEY]?.version; + if (!globalVersion || !isCompatible(globalVersion)) { + return; + } + return _global[GLOBAL_OPENTELEMETRY_API_KEY]?.[type]; +} + +export function unregisterGlobal(type: keyof OTelGlobalAPI, diag: DiagLogger) { + diag.debug( + `@opentelemetry/api: Unregistering a global for ${type} v${VERSION}.` + ); + const api = _global[GLOBAL_OPENTELEMETRY_API_KEY]; + + if (api) { + delete api[type]; + } +} + +type OTelGlobal = { + [GLOBAL_OPENTELEMETRY_API_KEY]?: OTelGlobalAPI; +}; + +type OTelGlobalAPI = { + version: string; + + diag?: DiagLogger; + trace?: TracerProvider; + context?: ContextManager; + propagation?: TextMapPropagator; +}; diff --git a/api/src/internal/semver.ts b/api/src/internal/semver.ts new file mode 100644 index 0000000000..076f9b9b51 --- /dev/null +++ b/api/src/internal/semver.ts @@ -0,0 +1,140 @@ +/* + * 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 { VERSION } from '../version'; + +const re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/; + +/** + * Create a function to test an API version to see if it is compatible with the provided ownVersion. + * + * The returned function has the following semantics: + * - Exact match is always compatible + * - Major versions must match exactly + * - 1.x package cannot use global 2.x package + * - 2.x package cannot use global 1.x package + * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API + * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects + * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 + * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor + * - Patch and build tag differences are not considered at this time + * + * @param ownVersion version which should be checked against + */ +export function _makeCompatibilityCheck( + ownVersion: string +): (globalVersion: string) => boolean { + const acceptedVersions = new Set([ownVersion]); + const rejectedVersions = new Set(); + + const myVersionMatch = ownVersion.match(re); + if (!myVersionMatch) { + // we cannot guarantee compatibility so we always return noop + return () => false; + } + + const ownVersionParsed = { + major: +myVersionMatch[1], + minor: +myVersionMatch[2], + patch: +myVersionMatch[3], + prerelease: myVersionMatch[4], + }; + + // if ownVersion has a prerelease tag, versions must match exactly + if (ownVersionParsed.prerelease != null) { + return function isExactmatch(globalVersion: string): boolean { + return globalVersion === ownVersion; + }; + } + + function _reject(v: string) { + rejectedVersions.add(v); + return false; + } + + function _accept(v: string) { + acceptedVersions.add(v); + return true; + } + + return function isCompatible(globalVersion: string): boolean { + if (acceptedVersions.has(globalVersion)) { + return true; + } + + if (rejectedVersions.has(globalVersion)) { + return false; + } + + const globalVersionMatch = globalVersion.match(re); + if (!globalVersionMatch) { + // cannot parse other version + // we cannot guarantee compatibility so we always noop + return _reject(globalVersion); + } + + const globalVersionParsed = { + major: +globalVersionMatch[1], + minor: +globalVersionMatch[2], + patch: +globalVersionMatch[3], + prerelease: globalVersionMatch[4], + }; + + // if globalVersion has a prerelease tag, versions must match exactly + if (globalVersionParsed.prerelease != null) { + return _reject(globalVersion); + } + + // major versions must match + if (ownVersionParsed.major !== globalVersionParsed.major) { + return _reject(globalVersion); + } + + if (ownVersionParsed.major === 0) { + if ( + ownVersionParsed.minor === globalVersionParsed.minor && + ownVersionParsed.patch <= globalVersionParsed.patch + ) { + return _accept(globalVersion); + } + + return _reject(globalVersion); + } + + if (ownVersionParsed.minor <= globalVersionParsed.minor) { + return _accept(globalVersion); + } + + return _reject(globalVersion); + }; +} + +/** + * Test an API version to see if it is compatible with this API. + * + * - Exact match is always compatible + * - Major versions must match exactly + * - 1.x package cannot use global 2.x package + * - 2.x package cannot use global 1.x package + * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API + * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects + * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 + * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor + * - Patch and build tag differences are not considered at this time + * + * @param version version of the API requesting an instance of the global API + */ +export const isCompatible = _makeCompatibilityCheck(VERSION); diff --git a/api/src/platform/browser/globalThis.ts b/api/src/platform/browser/globalThis.ts new file mode 100644 index 0000000000..ebea1f48c5 --- /dev/null +++ b/api/src/platform/browser/globalThis.ts @@ -0,0 +1,35 @@ +/* + * 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. + */ + +// Updates to this file should also be replicated to @opentelemetry/api-metrics and +// @opentelemetry/core too. + +/** + * - globalThis (New standard) + * - self (Will return the current window instance for supported browsers) + * - window (fallback for older browser implementations) + * - global (NodeJS implementation) + * - (When all else fails) + */ + +/** only globals that common to node and browsers are allowed */ +// eslint-disable-next-line node/no-unsupported-features/es-builtins, no-undef +export const _globalThis: typeof globalThis = + typeof globalThis === 'object' ? globalThis : + typeof self === 'object' ? self : + typeof window === 'object' ? window : + typeof global === 'object' ? global : + {} as typeof globalThis; diff --git a/api/src/platform/browser/index.ts b/api/src/platform/browser/index.ts new file mode 100644 index 0000000000..e9d6ebed71 --- /dev/null +++ b/api/src/platform/browser/index.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './globalThis'; diff --git a/api/src/platform/index.ts b/api/src/platform/index.ts new file mode 100644 index 0000000000..cdaf8858ce --- /dev/null +++ b/api/src/platform/index.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './node'; diff --git a/api/src/platform/node/globalThis.ts b/api/src/platform/node/globalThis.ts new file mode 100644 index 0000000000..36e97e2732 --- /dev/null +++ b/api/src/platform/node/globalThis.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ + +/** only globals that common to node and browsers are allowed */ +// eslint-disable-next-line node/no-unsupported-features/es-builtins +export const _globalThis = typeof globalThis === 'object' ? globalThis : global; diff --git a/api/src/platform/node/index.ts b/api/src/platform/node/index.ts new file mode 100644 index 0000000000..e9d6ebed71 --- /dev/null +++ b/api/src/platform/node/index.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './globalThis'; diff --git a/api/src/propagation/NoopTextMapPropagator.ts b/api/src/propagation/NoopTextMapPropagator.ts new file mode 100644 index 0000000000..16d90cf970 --- /dev/null +++ b/api/src/propagation/NoopTextMapPropagator.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 { Context } from '../context/types'; +import { TextMapPropagator } from './TextMapPropagator'; + +/** + * No-op implementations of {@link TextMapPropagator}. + */ +export class NoopTextMapPropagator implements TextMapPropagator { + /** Noop inject function does nothing */ + inject(_context: Context, _carrier: unknown): void {} + /** Noop extract function does nothing and returns the input context */ + extract(context: Context, _carrier: unknown): Context { + return context; + } + fields(): string[] { + return []; + } +} diff --git a/api/src/propagation/TextMapPropagator.ts b/api/src/propagation/TextMapPropagator.ts new file mode 100644 index 0000000000..7cb41432cb --- /dev/null +++ b/api/src/propagation/TextMapPropagator.ts @@ -0,0 +1,137 @@ +/* + * 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 } from '../context/types'; + +/** + * Injects `Context` into and extracts it from carriers that travel + * in-band across process boundaries. Encoding is expected to conform to the + * HTTP Header Field semantics. Values are often encoded as RPC/HTTP request + * headers. + * + * The carrier of propagated data on both the client (injector) and server + * (extractor) side is usually an object such as http headers. Propagation is + * usually implemented via library-specific request interceptors, where the + * client-side injects values and the server-side extracts them. + */ +export interface TextMapPropagator { + /** + * Injects values from a given `Context` into a carrier. + * + * OpenTelemetry defines a common set of format values (TextMapPropagator), + * and each has an expected `carrier` type. + * + * @param context the Context from which to extract values to transmit over + * the wire. + * @param carrier the carrier of propagation fields, such as http request + * headers. + * @param setter an optional {@link TextMapSetter}. If undefined, values will be + * set by direct object assignment. + */ + inject( + context: Context, + carrier: Carrier, + setter: TextMapSetter + ): void; + + /** + * Given a `Context` and a carrier, extract context values from a + * carrier and return a new context, created from the old context, with the + * extracted values. + * + * @param context the Context from which to extract values to transmit over + * the wire. + * @param carrier the carrier of propagation fields, such as http request + * headers. + * @param getter an optional {@link TextMapGetter}. If undefined, keys will be all + * own properties, and keys will be accessed by direct object access. + */ + extract( + context: Context, + carrier: Carrier, + getter: TextMapGetter + ): Context; + + /** + * Return a list of all fields which may be used by the propagator. + */ + fields(): string[]; +} + +/** + * A setter is specified by the caller to define a specific method + * to set key/value pairs on the carrier within a propagator. + */ +export interface TextMapSetter { + /** + * Callback used to set a key/value pair on an object. + * + * Should be called by the propagator each time a key/value pair + * should be set, and should set that key/value pair on the propagator. + * + * @param carrier object or class which carries key/value pairs + * @param key string key to modify + * @param value value to be set to the key on the carrier + */ + set(carrier: Carrier, key: string, value: string): void; +} + +/** + * A getter is specified by the caller to define a specific method + * to get the value of a key from a carrier. + */ +export interface TextMapGetter { + /** + * Get a list of all keys available on the carrier. + * + * @param carrier + */ + keys(carrier: Carrier): string[]; + + /** + * Get the value of a specific key from the carrier. + * + * @param carrier + * @param key + */ + get(carrier: Carrier, key: string): undefined | string | string[]; +} + +export const defaultTextMapGetter: TextMapGetter = { + get(carrier, key) { + if (carrier == null) { + return undefined; + } + return carrier[key]; + }, + + keys(carrier) { + if (carrier == null) { + return []; + } + return Object.keys(carrier); + }, +}; + +export const defaultTextMapSetter: TextMapSetter = { + set(carrier, key, value) { + if (carrier == null) { + return; + } + + carrier[key] = value; + }, +}; diff --git a/api/src/trace/NonRecordingSpan.ts b/api/src/trace/NonRecordingSpan.ts new file mode 100644 index 0000000000..a9e5bcaf9b --- /dev/null +++ b/api/src/trace/NonRecordingSpan.ts @@ -0,0 +1,75 @@ +/* + * 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 { Exception } from '../common/Exception'; +import { TimeInput } from '../common/Time'; +import { SpanAttributes } from './attributes'; +import { INVALID_SPAN_CONTEXT } from './invalid-span-constants'; +import { Span } from './span'; +import { SpanContext } from './span_context'; +import { SpanStatus } from './status'; + +/** + * The NonRecordingSpan is the default {@link Span} that is used when no Span + * implementation is available. All operations are no-op including context + * propagation. + */ +export class NonRecordingSpan implements Span { + constructor( + private readonly _spanContext: SpanContext = INVALID_SPAN_CONTEXT + ) {} + + // Returns a SpanContext. + spanContext(): SpanContext { + return this._spanContext; + } + + // By default does nothing + setAttribute(_key: string, _value: unknown): this { + return this; + } + + // By default does nothing + setAttributes(_attributes: SpanAttributes): this { + return this; + } + + // By default does nothing + addEvent(_name: string, _attributes?: SpanAttributes): this { + return this; + } + + // By default does nothing + setStatus(_status: SpanStatus): this { + return this; + } + + // By default does nothing + updateName(_name: string): this { + return this; + } + + // By default does nothing + end(_endTime?: TimeInput): void {} + + // isRecording always returns false for NonRecordingSpan. + isRecording(): boolean { + return false; + } + + // By default does nothing + recordException(_exception: Exception, _time?: TimeInput): void {} +} diff --git a/api/src/trace/NoopTracer.ts b/api/src/trace/NoopTracer.ts new file mode 100644 index 0000000000..d1db93e9cf --- /dev/null +++ b/api/src/trace/NoopTracer.ts @@ -0,0 +1,105 @@ +/* + * 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 { ContextAPI } from '../api/context'; +import { Context } from '../context/types'; +import { getSpanContext, setSpan } from '../trace/context-utils'; +import { NonRecordingSpan } from './NonRecordingSpan'; +import { Span } from './span'; +import { isSpanContextValid } from './spancontext-utils'; +import { SpanOptions } from './SpanOptions'; +import { SpanContext } from './span_context'; +import { Tracer } from './tracer'; + +const context = ContextAPI.getInstance(); + +/** + * No-op implementations of {@link Tracer}. + */ +export class NoopTracer implements Tracer { + // startSpan starts a noop span. + startSpan(name: string, options?: SpanOptions, context?: Context): Span { + const root = Boolean(options?.root); + if (root) { + return new NonRecordingSpan(); + } + + const parentFromContext = context && getSpanContext(context); + + if ( + isSpanContext(parentFromContext) && + isSpanContextValid(parentFromContext) + ) { + return new NonRecordingSpan(parentFromContext); + } else { + return new NonRecordingSpan(); + } + } + + startActiveSpan ReturnType>( + name: string, + fn: F + ): ReturnType; + startActiveSpan ReturnType>( + name: string, + opts: SpanOptions | undefined, + fn: F + ): ReturnType; + startActiveSpan ReturnType>( + name: string, + opts: SpanOptions | undefined, + ctx: Context | undefined, + fn: F + ): ReturnType; + startActiveSpan ReturnType>( + name: string, + arg2?: F | SpanOptions, + arg3?: F | Context, + arg4?: F + ): ReturnType | undefined { + let opts: SpanOptions | undefined; + let ctx: Context | undefined; + let fn: F; + + if (arguments.length < 2) { + return; + } else if (arguments.length === 2) { + fn = arg2 as F; + } else if (arguments.length === 3) { + opts = arg2 as SpanOptions | undefined; + fn = arg3 as F; + } else { + opts = arg2 as SpanOptions | undefined; + ctx = arg3 as Context | undefined; + fn = arg4 as F; + } + + const parentContext = ctx ?? context.active(); + const span = this.startSpan(name, opts, parentContext); + const contextWithSpanSet = setSpan(parentContext, span); + + return context.with(contextWithSpanSet, fn, undefined, span); + } +} + +function isSpanContext(spanContext: any): spanContext is SpanContext { + return ( + typeof spanContext === 'object' && + typeof spanContext['spanId'] === 'string' && + typeof spanContext['traceId'] === 'string' && + typeof spanContext['traceFlags'] === 'number' + ); +} diff --git a/api/src/trace/NoopTracerProvider.ts b/api/src/trace/NoopTracerProvider.ts new file mode 100644 index 0000000000..f4b31b9ac5 --- /dev/null +++ b/api/src/trace/NoopTracerProvider.ts @@ -0,0 +1,36 @@ +/* + * 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 { NoopTracer } from './NoopTracer'; +import { Tracer } from './tracer'; +import { TracerOptions } from './tracer_options'; +import { TracerProvider } from './tracer_provider'; + +/** + * An implementation of the {@link TracerProvider} which returns an impotent + * Tracer for all calls to `getTracer`. + * + * All operations are no-op. + */ +export class NoopTracerProvider implements TracerProvider { + getTracer( + _name?: string, + _version?: string, + _options?: TracerOptions + ): Tracer { + return new NoopTracer(); + } +} diff --git a/api/src/trace/ProxyTracer.ts b/api/src/trace/ProxyTracer.ts new file mode 100644 index 0000000000..a858bdc3ce --- /dev/null +++ b/api/src/trace/ProxyTracer.ts @@ -0,0 +1,76 @@ +/* + * 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 } from '../context/types'; +import { NoopTracer } from './NoopTracer'; +import { Span } from './span'; +import { SpanOptions } from './SpanOptions'; +import { Tracer } from './tracer'; +import { TracerOptions } from './tracer_options'; + +const NOOP_TRACER = new NoopTracer(); + +/** + * Proxy tracer provided by the proxy tracer provider + */ +export class ProxyTracer implements Tracer { + // When a real implementation is provided, this will be it + private _delegate?: Tracer; + + constructor( + private _provider: TracerDelegator, + public readonly name: string, + public readonly version?: string, + public readonly options?: TracerOptions + ) {} + + startSpan(name: string, options?: SpanOptions, context?: Context): Span { + return this._getTracer().startSpan(name, options, context); + } + + startActiveSpan unknown>( + _name: string, + _options: F | SpanOptions, + _context?: F | Context, + _fn?: F + ): ReturnType { + const tracer = this._getTracer(); + return Reflect.apply(tracer.startActiveSpan, tracer, arguments); + } + + /** + * Try to get a tracer from the proxy tracer provider. + * If the proxy tracer provider has no delegate, return a noop tracer. + */ + private _getTracer() { + if (this._delegate) { + return this._delegate; + } + + const tracer = this._provider.getDelegateTracer(this.name, this.version, this.options); + + if (!tracer) { + return NOOP_TRACER; + } + + this._delegate = tracer; + return this._delegate; + } +} + +export interface TracerDelegator { + getDelegateTracer(name: string, version?: string, options?: TracerOptions): Tracer | undefined; +} diff --git a/api/src/trace/ProxyTracerProvider.ts b/api/src/trace/ProxyTracerProvider.ts new file mode 100644 index 0000000000..f7b9c475a2 --- /dev/null +++ b/api/src/trace/ProxyTracerProvider.ts @@ -0,0 +1,64 @@ +/* + * 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 { Tracer } from './tracer'; +import { TracerProvider } from './tracer_provider'; +import { ProxyTracer } from './ProxyTracer'; +import { NoopTracerProvider } from './NoopTracerProvider'; +import { TracerOptions } from './tracer_options'; + +const NOOP_TRACER_PROVIDER = new NoopTracerProvider(); + +/** + * Tracer provider which provides {@link ProxyTracer}s. + * + * Before a delegate is set, tracers provided are NoOp. + * When a delegate is set, traces are provided from the delegate. + * When a delegate is set after tracers have already been provided, + * all tracers already provided will use the provided delegate implementation. + */ +export class ProxyTracerProvider implements TracerProvider { + private _delegate?: TracerProvider; + + /** + * Get a {@link ProxyTracer} + */ + getTracer(name: string, version?: string, options?: TracerOptions): Tracer { + return ( + this.getDelegateTracer(name, version, options) ?? + new ProxyTracer(this, name, version, options) + ); + } + + getDelegate(): TracerProvider { + return this._delegate ?? NOOP_TRACER_PROVIDER; + } + + /** + * Set the delegate tracer provider + */ + setDelegate(delegate: TracerProvider) { + this._delegate = delegate; + } + + getDelegateTracer( + name: string, + version?: string, + options?: TracerOptions + ): Tracer | undefined { + return this._delegate?.getTracer(name, version, options); + } +} diff --git a/api/src/trace/Sampler.ts b/api/src/trace/Sampler.ts new file mode 100644 index 0000000000..b7a1d376ce --- /dev/null +++ b/api/src/trace/Sampler.ts @@ -0,0 +1,55 @@ +/* + * 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 } from '../context/types'; +import { SpanAttributes } from './attributes'; +import { Link } from './link'; +import { SamplingResult } from './SamplingResult'; +import { SpanKind } from './span_kind'; + +/** + * @deprecated use the one declared in @opentelemetry/sdk-trace-base instead. + * This interface represent a sampler. Sampling is a mechanism to control the + * noise and overhead introduced by OpenTelemetry by reducing the number of + * samples of traces collected and sent to the backend. + */ +export interface Sampler { + /** + * Checks whether span needs to be created and tracked. + * + * @param context Parent Context which may contain a span. + * @param traceId of the span to be created. It can be different from the + * traceId in the {@link SpanContext}. Typically in situations when the + * span to be created starts a new trace. + * @param spanName of the span to be created. + * @param spanKind of the span to be created. + * @param attributes Initial set of SpanAttributes for the Span being constructed. + * @param links Collection of links that will be associated with the Span to + * be created. Typically useful for batch operations. + * @returns a {@link SamplingResult}. + */ + shouldSample( + context: Context, + traceId: string, + spanName: string, + spanKind: SpanKind, + attributes: SpanAttributes, + links: Link[] + ): SamplingResult; + + /** Returns the sampler name or short description with the configuration. */ + toString(): string; +} diff --git a/api/src/trace/SamplingResult.ts b/api/src/trace/SamplingResult.ts new file mode 100644 index 0000000000..3038eec077 --- /dev/null +++ b/api/src/trace/SamplingResult.ts @@ -0,0 +1,58 @@ +/* + * 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 { SpanAttributes } from './attributes'; + +/** + * @deprecated use the one declared in @opentelemetry/sdk-trace-base instead. + * A sampling decision that determines how a {@link Span} will be recorded + * and collected. + */ +export enum SamplingDecision { + /** + * `Span.isRecording() === false`, span will not be recorded and all events + * and attributes will be dropped. + */ + NOT_RECORD, + /** + * `Span.isRecording() === true`, but `Sampled` flag in {@link TraceFlags} + * MUST NOT be set. + */ + RECORD, + /** + * `Span.isRecording() === true` AND `Sampled` flag in {@link TraceFlags} + * MUST be set. + */ + RECORD_AND_SAMPLED, +} + +/** + * @deprecated use the one declared in @opentelemetry/sdk-trace-base instead. + * A sampling result contains a decision for a {@link Span} and additional + * attributes the sampler would like to added to the Span. + */ +export interface SamplingResult { + /** + * A sampling decision, refer to {@link SamplingDecision} for details. + */ + decision: SamplingDecision; + /** + * The list of attributes returned by SamplingResult MUST be immutable. + * Caller may call {@link Sampler}.shouldSample any number of times and + * can safely cache the returned value. + */ + attributes?: Readonly; +} diff --git a/api/src/trace/SpanOptions.ts b/api/src/trace/SpanOptions.ts new file mode 100644 index 0000000000..cf368ec287 --- /dev/null +++ b/api/src/trace/SpanOptions.ts @@ -0,0 +1,43 @@ +/* + * 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 { TimeInput } from '../common/Time'; +import { SpanAttributes } from './attributes'; +import { Link } from './link'; +import { SpanKind } from './span_kind'; + +/** + * Options needed for span creation + */ +export interface SpanOptions { + /** + * The SpanKind of a span + * @default {@link SpanKind.INTERNAL} + */ + kind?: SpanKind; + + /** A span's attributes */ + attributes?: SpanAttributes; + + /** {@link Link}s span to other spans */ + links?: Link[]; + + /** A manually specified start time for the created `Span` object. */ + startTime?: TimeInput; + + /** The new span should be a root span. (Ignore parent from context). */ + root?: boolean; +} diff --git a/api/src/trace/attributes.ts b/api/src/trace/attributes.ts new file mode 100644 index 0000000000..01feff0b0a --- /dev/null +++ b/api/src/trace/attributes.ts @@ -0,0 +1,27 @@ +/* + * 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 { Attributes, AttributeValue } from '../common/Attributes'; + +/** + * @deprecated please use {@link Attributes} + */ +export type SpanAttributes = Attributes; + +/** + * @deprecated please use {@link AttributeValue} + */ +export type SpanAttributeValue = AttributeValue; diff --git a/api/src/trace/context-utils.ts b/api/src/trace/context-utils.ts new file mode 100644 index 0000000000..83bd55184c --- /dev/null +++ b/api/src/trace/context-utils.ts @@ -0,0 +1,85 @@ +/* + * 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 { createContextKey } from '../context/context'; +import { Context } from '../context/types'; +import { Span } from './span'; +import { SpanContext } from './span_context'; +import { NonRecordingSpan } from './NonRecordingSpan'; +import { ContextAPI } from '../api/context'; + +/** + * span key + */ +const SPAN_KEY = createContextKey('OpenTelemetry Context Key SPAN'); + +/** + * Return the span if one exists + * + * @param context context to get span from + */ +export function getSpan(context: Context): Span | undefined { + return (context.getValue(SPAN_KEY) as Span) || undefined; +} + +/** + * Gets the span from the current context, if one exists. + */ +export function getActiveSpan(): Span | undefined { + return getSpan(ContextAPI.getInstance().active()); +} + +/** + * Set the span on a context + * + * @param context context to use as parent + * @param span span to set active + */ +export function setSpan(context: Context, span: Span): Context { + return context.setValue(SPAN_KEY, span); +} + +/** + * Remove current span stored in the context + * + * @param context context to delete span from + */ +export function deleteSpan(context: Context): Context { + return context.deleteValue(SPAN_KEY); +} + +/** + * Wrap span context in a NoopSpan and set as span in a new + * context + * + * @param context context to set active span on + * @param spanContext span context to be wrapped + */ +export function setSpanContext( + context: Context, + spanContext: SpanContext +): Context { + return setSpan(context, new NonRecordingSpan(spanContext)); +} + +/** + * Get the span context of the span if it exists. + * + * @param context context to get values from + */ +export function getSpanContext(context: Context): SpanContext | undefined { + return getSpan(context)?.spanContext(); +} diff --git a/api/src/trace/internal/tracestate-impl.ts b/api/src/trace/internal/tracestate-impl.ts new file mode 100644 index 0000000000..4c69a3a97a --- /dev/null +++ b/api/src/trace/internal/tracestate-impl.ts @@ -0,0 +1,110 @@ +/* + * 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 { TraceState } from '../trace_state'; +import { validateKey, validateValue } from './tracestate-validators'; + +const MAX_TRACE_STATE_ITEMS = 32; +const MAX_TRACE_STATE_LEN = 512; +const LIST_MEMBERS_SEPARATOR = ','; +const LIST_MEMBER_KEY_VALUE_SPLITTER = '='; + +/** + * TraceState must be a class and not a simple object type because of the spec + * requirement (https://www.w3.org/TR/trace-context/#tracestate-field). + * + * Here is the list of allowed mutations: + * - New key-value pair should be added into the beginning of the list + * - The value of any key can be updated. Modified keys MUST be moved to the + * beginning of the list. + */ +export class TraceStateImpl implements TraceState { + private _internalState: Map = new Map(); + + constructor(rawTraceState?: string) { + if (rawTraceState) this._parse(rawTraceState); + } + + set(key: string, value: string): TraceStateImpl { + // TODO: Benchmark the different approaches(map vs list) and + // use the faster one. + const traceState = this._clone(); + if (traceState._internalState.has(key)) { + traceState._internalState.delete(key); + } + traceState._internalState.set(key, value); + return traceState; + } + + unset(key: string): TraceStateImpl { + const traceState = this._clone(); + traceState._internalState.delete(key); + return traceState; + } + + get(key: string): string | undefined { + return this._internalState.get(key); + } + + serialize(): string { + return this._keys() + .reduce((agg: string[], key) => { + agg.push(key + LIST_MEMBER_KEY_VALUE_SPLITTER + this.get(key)); + return agg; + }, []) + .join(LIST_MEMBERS_SEPARATOR); + } + + private _parse(rawTraceState: string) { + if (rawTraceState.length > MAX_TRACE_STATE_LEN) return; + this._internalState = rawTraceState + .split(LIST_MEMBERS_SEPARATOR) + .reverse() // Store in reverse so new keys (.set(...)) will be placed at the beginning + .reduce((agg: Map, part: string) => { + const listMember = part.trim(); // Optional Whitespace (OWS) handling + const i = listMember.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER); + if (i !== -1) { + const key = listMember.slice(0, i); + const value = listMember.slice(i + 1, part.length); + if (validateKey(key) && validateValue(value)) { + agg.set(key, value); + } else { + // TODO: Consider to add warning log + } + } + return agg; + }, new Map()); + + // Because of the reverse() requirement, trunc must be done after map is created + if (this._internalState.size > MAX_TRACE_STATE_ITEMS) { + this._internalState = new Map( + Array.from(this._internalState.entries()) + .reverse() // Use reverse same as original tracestate parse chain + .slice(0, MAX_TRACE_STATE_ITEMS) + ); + } + } + + private _keys(): string[] { + return Array.from(this._internalState.keys()).reverse(); + } + + private _clone(): TraceStateImpl { + const traceState = new TraceStateImpl(); + traceState._internalState = new Map(this._internalState); + return traceState; + } +} diff --git a/api/src/trace/internal/tracestate-validators.ts b/api/src/trace/internal/tracestate-validators.ts new file mode 100644 index 0000000000..78fbee8234 --- /dev/null +++ b/api/src/trace/internal/tracestate-validators.ts @@ -0,0 +1,45 @@ +/* + * 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. + */ + +const VALID_KEY_CHAR_RANGE = '[_0-9a-z-*/]'; +const VALID_KEY = `[a-z]${VALID_KEY_CHAR_RANGE}{0,255}`; +const VALID_VENDOR_KEY = `[a-z0-9]${VALID_KEY_CHAR_RANGE}{0,240}@[a-z]${VALID_KEY_CHAR_RANGE}{0,13}`; +const VALID_KEY_REGEX = new RegExp(`^(?:${VALID_KEY}|${VALID_VENDOR_KEY})$`); +const VALID_VALUE_BASE_REGEX = /^[ -~]{0,255}[!-~]$/; +const INVALID_VALUE_COMMA_EQUAL_REGEX = /,|=/; + +/** + * Key is opaque string up to 256 characters printable. It MUST begin with a + * lowercase letter, and can only contain lowercase letters a-z, digits 0-9, + * underscores _, dashes -, asterisks *, and forward slashes /. + * For multi-tenant vendor scenarios, an at sign (@) can be used to prefix the + * vendor name. Vendors SHOULD set the tenant ID at the beginning of the key. + * see https://www.w3.org/TR/trace-context/#key + */ +export function validateKey(key: string): boolean { + return VALID_KEY_REGEX.test(key); +} + +/** + * Value is opaque string up to 256 characters printable ASCII RFC0020 + * characters (i.e., the range 0x20 to 0x7E) except comma , and =. + */ +export function validateValue(value: string): boolean { + return ( + VALID_VALUE_BASE_REGEX.test(value) && + !INVALID_VALUE_COMMA_EQUAL_REGEX.test(value) + ); +} diff --git a/api/src/trace/internal/utils.ts b/api/src/trace/internal/utils.ts new file mode 100644 index 0000000000..080be77848 --- /dev/null +++ b/api/src/trace/internal/utils.ts @@ -0,0 +1,23 @@ +/* + * 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 { TraceState } from '../trace_state'; +import { TraceStateImpl } from './tracestate-impl'; + + +export function createTraceState(rawTraceState?: string): TraceState { + return new TraceStateImpl(rawTraceState); +} diff --git a/api/src/trace/invalid-span-constants.ts b/api/src/trace/invalid-span-constants.ts new file mode 100644 index 0000000000..882b4fe58b --- /dev/null +++ b/api/src/trace/invalid-span-constants.ts @@ -0,0 +1,26 @@ +/* + * 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 { SpanContext } from './span_context'; +import { TraceFlags } from './trace_flags'; + +export const INVALID_SPANID = '0000000000000000'; +export const INVALID_TRACEID = '00000000000000000000000000000000'; +export const INVALID_SPAN_CONTEXT: SpanContext = { + traceId: INVALID_TRACEID, + spanId: INVALID_SPANID, + traceFlags: TraceFlags.NONE, +}; diff --git a/api/src/trace/link.ts b/api/src/trace/link.ts new file mode 100644 index 0000000000..1d81d38d69 --- /dev/null +++ b/api/src/trace/link.ts @@ -0,0 +1,40 @@ +/* + * 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 { SpanAttributes } from './attributes'; +import { SpanContext } from './span_context'; + +/** + * A pointer from the current {@link Span} to another span in the same trace or + * in a different trace. + * Few examples of Link usage. + * 1. Batch Processing: A batch of elements may contain elements associated + * with one or more traces/spans. Since there can only be one parent + * SpanContext, Link is used to keep reference to SpanContext of all + * elements in the batch. + * 2. Public Endpoint: A SpanContext in incoming client request on a public + * endpoint is untrusted from service provider perspective. In such case it + * is advisable to start a new trace with appropriate sampling decision. + * However, it is desirable to associate incoming SpanContext to new trace + * initiated on service provider side so two traces (from Client and from + * Service Provider) can be correlated. + */ +export interface Link { + /** The {@link SpanContext} of a linked span. */ + context: SpanContext; + /** A set of {@link SpanAttributes} on the link. */ + attributes?: SpanAttributes; +} diff --git a/api/src/trace/span.ts b/api/src/trace/span.ts new file mode 100644 index 0000000000..d80b8c2626 --- /dev/null +++ b/api/src/trace/span.ts @@ -0,0 +1,129 @@ +/* + * 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 { Exception } from '../common/Exception'; +import { TimeInput } from '../common/Time'; +import { SpanAttributes, SpanAttributeValue } from './attributes'; +import { SpanContext } from './span_context'; +import { SpanStatus } from './status'; + +/** + * An interface that represents a span. A span represents a single operation + * within a trace. Examples of span might include remote procedure calls or a + * in-process function calls to sub-components. A Trace has a single, top-level + * "root" Span that in turn may have zero or more child Spans, which in turn + * may have children. + * + * Spans are created by the {@link Tracer.startSpan} method. + */ +export interface Span { + /** + * Returns the {@link SpanContext} object associated with this Span. + * + * Get an immutable, serializable identifier for this span that can be used + * to create new child spans. Returned SpanContext is usable even after the + * span ends. + * + * @returns the SpanContext object associated with this Span. + */ + spanContext(): SpanContext; + + /** + * Sets an attribute to the span. + * + * Sets a single Attribute with the key and value passed as arguments. + * + * @param key the key for this attribute. + * @param value the value for this attribute. Setting a value null or + * undefined is invalid and will result in undefined behavior. + */ + setAttribute(key: string, value: SpanAttributeValue): this; + + /** + * Sets attributes to the span. + * + * @param attributes the attributes that will be added. + * null or undefined attribute values + * are invalid and will result in undefined behavior. + */ + setAttributes(attributes: SpanAttributes): this; + + /** + * Adds an event to the Span. + * + * @param name the name of the event. + * @param [attributesOrStartTime] the attributes that will be added; these are + * associated with this event. Can be also a start time + * if type is {@type TimeInput} and 3rd param is undefined + * @param [startTime] start time of the event. + */ + addEvent( + name: string, + attributesOrStartTime?: SpanAttributes | TimeInput, + startTime?: TimeInput + ): this; + + /** + * Sets a status to the span. If used, this will override the default Span + * status. Default is {@link SpanStatusCode.UNSET}. SetStatus overrides the value + * of previous calls to SetStatus on the Span. + * + * @param status the SpanStatus to set. + */ + setStatus(status: SpanStatus): this; + + /** + * Updates the Span name. + * + * This will override the name provided via {@link Tracer.startSpan}. + * + * Upon this update, any sampling behavior based on Span name will depend on + * the implementation. + * + * @param name the Span name. + */ + updateName(name: string): this; + + /** + * Marks the end of Span execution. + * + * Call to End of a Span MUST not have any effects on child spans. Those may + * still be running and can be ended later. + * + * Do not return `this`. The Span generally should not be used after it + * is ended so chaining is not desired in this context. + * + * @param [endTime] the time to set as Span's end time. If not provided, + * use the current time as the span's end time. + */ + end(endTime?: TimeInput): void; + + /** + * Returns the flag whether this span will be recorded. + * + * @returns true if this Span is active and recording information like events + * with the `AddEvent` operation and attributes using `setAttributes`. + */ + isRecording(): boolean; + + /** + * Sets exception as a span event + * @param exception the exception the only accepted values are string or Error + * @param [time] the time to set as Span's event time. If not provided, + * use the current time. + */ + recordException(exception: Exception, time?: TimeInput): void; +} diff --git a/api/src/trace/span_context.ts b/api/src/trace/span_context.ts new file mode 100644 index 0000000000..613bdb8eb2 --- /dev/null +++ b/api/src/trace/span_context.ts @@ -0,0 +1,69 @@ +/* + * 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 { TraceState } from './trace_state'; + +/** + * A SpanContext represents the portion of a {@link Span} which must be + * serialized and propagated along side of a {@link Baggage}. + */ +export interface SpanContext { + /** + * The ID of the trace that this span belongs to. It is worldwide unique + * with practically sufficient probability by being made as 16 randomly + * generated bytes, encoded as a 32 lowercase hex characters corresponding to + * 128 bits. + */ + traceId: string; + /** + * The ID of the Span. It is globally unique with practically sufficient + * probability by being made as 8 randomly generated bytes, encoded as a 16 + * lowercase hex characters corresponding to 64 bits. + */ + spanId: string; + /** + * Only true if the SpanContext was propagated from a remote parent. + */ + isRemote?: boolean; + /** + * Trace flags to propagate. + * + * It is represented as 1 byte (bitmap). Bit to represent whether trace is + * sampled or not. When set, the least significant bit documents that the + * caller may have recorded trace data. A caller who does not record trace + * data out-of-band leaves this flag unset. + * + * see {@link TraceFlags} for valid flag values. + */ + traceFlags: number; + /** + * Tracing-system-specific info to propagate. + * + * The tracestate field value is a `list` as defined below. The `list` is a + * series of `list-members` separated by commas `,`, and a list-member is a + * key/value pair separated by an equals sign `=`. Spaces and horizontal tabs + * surrounding `list-members` are ignored. There can be a maximum of 32 + * `list-members` in a `list`. + * More Info: https://www.w3.org/TR/trace-context/#tracestate-field + * + * Examples: + * Single tracing system (generic format): + * tracestate: rojo=00f067aa0ba902b7 + * Multiple tracing systems (with different formatting): + * tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE + */ + traceState?: TraceState; +} diff --git a/api/src/trace/span_kind.ts b/api/src/trace/span_kind.ts new file mode 100644 index 0000000000..d0ed18123e --- /dev/null +++ b/api/src/trace/span_kind.ts @@ -0,0 +1,45 @@ +/* + * 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. + */ +export enum SpanKind { + /** Default value. Indicates that the span is used internally. */ + INTERNAL = 0, + + /** + * Indicates that the span covers server-side handling of an RPC or other + * remote request. + */ + SERVER = 1, + + /** + * Indicates that the span covers the client-side wrapper around an RPC or + * other remote request. + */ + CLIENT = 2, + + /** + * Indicates that the span describes producer sending a message to a + * broker. Unlike client and server, there is no direct critical path latency + * relationship between producer and consumer spans. + */ + PRODUCER = 3, + + /** + * Indicates that the span describes consumer receiving a message from a + * broker. Unlike client and server, there is no direct critical path latency + * relationship between producer and consumer spans. + */ + CONSUMER = 4, +} diff --git a/api/src/trace/spancontext-utils.ts b/api/src/trace/spancontext-utils.ts new file mode 100644 index 0000000000..6bd54903ae --- /dev/null +++ b/api/src/trace/spancontext-utils.ts @@ -0,0 +1,50 @@ +/* + * 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 { INVALID_SPANID, INVALID_TRACEID } from './invalid-span-constants'; +import { NonRecordingSpan } from './NonRecordingSpan'; +import { Span } from './span'; +import { SpanContext } from './span_context'; + +const VALID_TRACEID_REGEX = /^([0-9a-f]{32})$/i; +const VALID_SPANID_REGEX = /^[0-9a-f]{16}$/i; + +export function isValidTraceId(traceId: string): boolean { + return VALID_TRACEID_REGEX.test(traceId) && traceId !== INVALID_TRACEID; +} + +export function isValidSpanId(spanId: string): boolean { + return VALID_SPANID_REGEX.test(spanId) && spanId !== INVALID_SPANID; +} + +/** + * Returns true if this {@link SpanContext} is valid. + * @return true if this {@link SpanContext} is valid. + */ +export function isSpanContextValid(spanContext: SpanContext): boolean { + return ( + isValidTraceId(spanContext.traceId) && isValidSpanId(spanContext.spanId) + ); +} + +/** + * Wrap the given {@link SpanContext} in a new non-recording {@link Span} + * + * @param spanContext span context to be wrapped + * @returns a new non-recording {@link Span} with the provided context + */ +export function wrapSpanContext(spanContext: SpanContext): Span { + return new NonRecordingSpan(spanContext); +} diff --git a/api/src/trace/status.ts b/api/src/trace/status.ts new file mode 100644 index 0000000000..f5b7a9ba56 --- /dev/null +++ b/api/src/trace/status.ts @@ -0,0 +1,40 @@ +/* + * 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. + */ +export interface SpanStatus { + /** The status code of this message. */ + code: SpanStatusCode; + /** A developer-facing error message. */ + message?: string; +} + +/** + * An enumeration of status codes. + */ +export enum SpanStatusCode { + /** + * The default status. + */ + UNSET = 0, + /** + * The operation has been validated by an Application developer or + * Operator to have completed successfully. + */ + OK = 1, + /** + * The operation contains an error. + */ + ERROR = 2, +} diff --git a/api/src/trace/trace_flags.ts b/api/src/trace/trace_flags.ts new file mode 100644 index 0000000000..fd282010c7 --- /dev/null +++ b/api/src/trace/trace_flags.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ +export enum TraceFlags { + /** Represents no flag set. */ + NONE = 0x0, + /** Bit to represent whether trace is sampled in trace flags. */ + SAMPLED = 0x1 << 0, +} diff --git a/api/src/trace/trace_state.ts b/api/src/trace/trace_state.ts new file mode 100644 index 0000000000..640d1578a9 --- /dev/null +++ b/api/src/trace/trace_state.ts @@ -0,0 +1,59 @@ +/* + * 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. + */ + +export interface TraceState { + /** + * Create a new TraceState which inherits from this TraceState and has the + * given key set. + * The new entry will always be added in the front of the list of states. + * + * @param key key of the TraceState entry. + * @param value value of the TraceState entry. + */ + set(key: string, value: string): TraceState; + + /** + * Return a new TraceState which inherits from this TraceState but does not + * contain the given key. + * + * @param key the key for the TraceState entry to be removed. + */ + unset(key: string): TraceState; + + /** + * Returns the value to which the specified key is mapped, or `undefined` if + * this map contains no mapping for the key. + * + * @param key with which the specified value is to be associated. + * @returns the value to which the specified key is mapped, or `undefined` if + * this map contains no mapping for the key. + */ + get(key: string): string | undefined; + + // TODO: Consider to add support for merging an object as well by also + // accepting a single internalTraceState argument similar to the constructor. + + /** + * Serializes the TraceState to a `list` as defined below. The `list` is a + * series of `list-members` separated by commas `,`, and a list-member is a + * key/value pair separated by an equals sign `=`. Spaces and horizontal tabs + * surrounding `list-members` are ignored. There can be a maximum of 32 + * `list-members` in a `list`. + * + * @returns the serialized string. + */ + serialize(): string; +} diff --git a/api/src/trace/tracer.ts b/api/src/trace/tracer.ts new file mode 100644 index 0000000000..3c76927b25 --- /dev/null +++ b/api/src/trace/tracer.ts @@ -0,0 +1,100 @@ +/* + * 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 } from '../context/types'; +import { Span } from './span'; +import { SpanOptions } from './SpanOptions'; + +/** + * Tracer provides an interface for creating {@link Span}s. + */ +export interface Tracer { + /** + * Starts a new {@link Span}. Start the span without setting it on context. + * + * This method do NOT modify the current Context. + * + * @param name The name of the span + * @param [options] SpanOptions used for span creation + * @param [context] Context to use to extract parent + * @returns Span The newly created span + * @example + * const span = tracer.startSpan('op'); + * span.setAttribute('key', 'value'); + * span.end(); + */ + startSpan(name: string, options?: SpanOptions, context?: Context): Span; + + /** + * Starts a new {@link Span} and calls the given function passing it the + * created span as first argument. + * Additionally the new span gets set in context and this context is activated + * for the duration of the function call. + * + * @param name The name of the span + * @param [options] SpanOptions used for span creation + * @param [context] Context to use to extract parent + * @param fn function called in the context of the span and receives the newly created span as an argument + * @returns return value of fn + * @example + * const something = tracer.startActiveSpan('op', span => { + * try { + * do some work + * span.setStatus({code: SpanStatusCode.OK}); + * return something; + * } catch (err) { + * span.setStatus({ + * code: SpanStatusCode.ERROR, + * message: err.message, + * }); + * throw err; + * } finally { + * span.end(); + * } + * }); + * + * @example + * const span = tracer.startActiveSpan('op', span => { + * try { + * do some work + * return span; + * } catch (err) { + * span.setStatus({ + * code: SpanStatusCode.ERROR, + * message: err.message, + * }); + * throw err; + * } + * }); + * do some more work + * span.end(); + */ + startActiveSpan unknown>( + name: string, + fn: F + ): ReturnType; + startActiveSpan unknown>( + name: string, + options: SpanOptions, + fn: F + ): ReturnType; + startActiveSpan unknown>( + name: string, + options: SpanOptions, + context: Context, + fn: F + ): ReturnType; +} diff --git a/api/src/trace/tracer_options.ts b/api/src/trace/tracer_options.ts new file mode 100644 index 0000000000..44ef004ca7 --- /dev/null +++ b/api/src/trace/tracer_options.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/** + * An interface describes additional metadata of a tracer. + */ +export interface TracerOptions { + /** + * The schemaUrl of the tracer or instrumentation library + */ + schemaUrl?: string; +} diff --git a/api/src/trace/tracer_provider.ts b/api/src/trace/tracer_provider.ts new file mode 100644 index 0000000000..0cde8fb664 --- /dev/null +++ b/api/src/trace/tracer_provider.ts @@ -0,0 +1,37 @@ +/* + * 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 { Tracer } from './tracer'; +import { TracerOptions } from './tracer_options'; + +/** + * A registry for creating named {@link Tracer}s. + */ +export interface TracerProvider { + /** + * Returns a Tracer, creating one if one with the given name and version is + * not already created. + * + * This function may return different Tracer types (e.g. + * {@link NoopTracerProvider} vs. a functional tracer). + * + * @param name The name of the tracer or instrumentation library. + * @param version The version of the tracer or instrumentation library. + * @param options The options of the tracer or instrumentation library. + * @returns Tracer A Tracer with the given name and version + */ + getTracer(name: string, version?: string, options?: TracerOptions): Tracer; +} diff --git a/api/test/api/api.test.ts b/api/test/api/api.test.ts new file mode 100644 index 0000000000..4f51462a18 --- /dev/null +++ b/api/test/api/api.test.ts @@ -0,0 +1,253 @@ +/* + * 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 api, { + context, + Context, + defaultTextMapGetter, + defaultTextMapSetter, + diag, + propagation, + ROOT_CONTEXT, + Span, + SpanOptions, + TextMapGetter, + TextMapPropagator, + TextMapSetter, + trace, + TraceFlags, +} from '../../src'; +import { DiagAPI } from '../../src/api/diag'; +import { NonRecordingSpan } from '../../src/trace/NonRecordingSpan'; +import { NoopTracer } from '../../src/trace/NoopTracer'; +import { NoopTracerProvider } from '../../src/trace/NoopTracerProvider'; + +// DiagLogger implementation +const diagLoggerFunctions = [ + 'verbose', + 'debug', + 'info', + 'warn', + 'error', +] as const; + +describe('API', () => { + it('should expose a tracer provider via getTracerProvider', () => { + const tracer = api.trace.getTracerProvider(); + assert.ok(tracer); + assert.strictEqual(typeof tracer, 'object'); + }); + + it('getActiveSpan should get the current span', () => { + const span = new NonRecordingSpan(); + const ctx = trace.setSpan(ROOT_CONTEXT, span); + context.setGlobalContextManager({ active: () => ctx, disable: () => {} } as any); + + const active = trace.getActiveSpan(); + assert.strictEqual(active, span); + + context.disable(); + }); + + describe('Context', () => { + it('with should forward this, arguments and return value', () => { + function fnWithThis(this: string, a: string, b: number): string { + assert.strictEqual(this, 'that'); + assert.strictEqual(arguments.length, 2); + assert.strictEqual(a, 'one'); + assert.strictEqual(b, 2); + return 'done'; + } + + const res = context.with(ROOT_CONTEXT, fnWithThis, 'that', 'one', 2); + assert.strictEqual(res, 'done'); + + assert.strictEqual( + context.with(ROOT_CONTEXT, () => 3.14), + 3.14 + ); + }); + }); + + describe('GlobalTracerProvider', () => { + const spanContext = { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.NONE, + }; + const dummySpan = new NonRecordingSpan(spanContext); + + beforeEach(() => { + context.disable(); + trace.disable(); + propagation.disable(); + }); + + it('should use the global tracer provider', () => { + api.trace.setGlobalTracerProvider(new TestTracerProvider()); + const tracer = api.trace.getTracerProvider().getTracer('name'); + const span = tracer.startSpan('test'); + assert.deepStrictEqual(span, dummySpan); + }); + + it('should set delegate only on success', () => { + assert.strictEqual( + api.trace.setGlobalTracerProvider(new TestTracerProvider()), + true + ); + assert.strictEqual( + api.trace.setGlobalTracerProvider(new NoopTracerProvider()), + false + ); + assert.ok(api.trace.getTracer('name') instanceof TestTracer); + }); + + class TestTracer extends NoopTracer { + override startSpan(name: string, options?: SpanOptions): Span { + return dummySpan; + } + } + + class TestTracerProvider extends NoopTracerProvider { + override getTracer(_name: string, version?: string) { + return new TestTracer(); + } + } + + describe('should use the global propagation', () => { + const testKey = Symbol('kTestKey'); + + interface Carrier { + context?: Context; + setter?: TextMapSetter; + } + + class TestTextMapPropagation implements TextMapPropagator { + inject( + context: Context, + carrier: Carrier, + setter: TextMapSetter + ): void { + carrier.context = context; + carrier.setter = setter; + } + + extract( + context: Context, + carrier: Carrier, + getter: TextMapGetter + ): Context { + return context.setValue(testKey, { + context, + carrier, + getter, + }); + } + + fields(): string[] { + return ['TestField']; + } + } + + it('inject', () => { + api.propagation.setGlobalPropagator(new TestTextMapPropagation()); + + const context = ROOT_CONTEXT.setValue(testKey, 15); + const carrier: Carrier = {}; + api.propagation.inject(context, carrier); + assert.strictEqual(carrier.context, context); + assert.strictEqual(carrier.setter, defaultTextMapSetter); + + const setter: TextMapSetter = { + set: () => {}, + }; + api.propagation.inject(context, carrier, setter); + assert.strictEqual(carrier.context, context); + assert.strictEqual(carrier.setter, setter); + }); + + it('extract', () => { + api.propagation.setGlobalPropagator(new TestTextMapPropagation()); + + const carrier: Carrier = {}; + let context = api.propagation.extract(ROOT_CONTEXT, carrier); + let data: any = context.getValue(testKey); + assert.ok(data != null); + assert.strictEqual(data.context, ROOT_CONTEXT); + assert.strictEqual(data.carrier, carrier); + assert.strictEqual(data.getter, defaultTextMapGetter); + + const getter: TextMapGetter = { + keys: () => [], + get: () => undefined, + }; + context = api.propagation.extract(ROOT_CONTEXT, carrier, getter); + data = context.getValue(testKey); + assert.ok(data != null); + assert.strictEqual(data.context, ROOT_CONTEXT); + assert.strictEqual(data.carrier, carrier); + assert.strictEqual(data.getter, getter); + }); + + it('fields', () => { + api.propagation.setGlobalPropagator(new TestTextMapPropagation()); + + const fields = api.propagation.fields(); + assert.deepStrictEqual(fields, ['TestField']); + }); + }); + }); + + describe('Global diag', () => { + it('initialization', () => { + const inst = DiagAPI.instance(); + + assert.deepStrictEqual(diag, inst); + }); + + diagLoggerFunctions.forEach(fName => { + it(`no argument logger ${fName} message doesn't throw`, () => { + //@ts-expect-error an undefined logger is not allowed + diag.setLogger(); + assert.doesNotThrow(() => { + diag[fName](`${fName} message`); + }); + }); + + it(`null logger ${fName} message doesn't throw`, () => { + diag.setLogger(null as any); + assert.doesNotThrow(() => { + diag[fName](`${fName} message`); + }); + }); + + it(`undefined logger ${fName} message doesn't throw`, () => { + diag.setLogger(undefined as any); + assert.doesNotThrow(() => { + diag[fName](`${fName} message`); + }); + }); + + it(`empty logger ${fName} message doesn't throw`, () => { + diag.setLogger({} as any); + assert.doesNotThrow(() => { + diag[fName](`${fName} message`); + }); + }); + }); + }); +}); diff --git a/api/test/baggage/Baggage.test.ts b/api/test/baggage/Baggage.test.ts new file mode 100644 index 0000000000..080b6a4193 --- /dev/null +++ b/api/test/baggage/Baggage.test.ts @@ -0,0 +1,161 @@ +/* + * 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 { + ROOT_CONTEXT, + propagation, + baggageEntryMetadataFromString, +} from '../../src'; + +describe('Baggage', () => { + describe('create', () => { + it('should create an empty bag', () => { + const bag = propagation.createBaggage(); + + assert.deepStrictEqual(bag.getAllEntries(), []); + }); + + it('should create a bag with entries', () => { + const meta = baggageEntryMetadataFromString('opaque string'); + const bag = propagation.createBaggage({ + key1: { value: 'value1' }, + key2: { value: 'value2', metadata: meta }, + }); + + assert.deepStrictEqual(bag.getAllEntries(), [ + ['key1', { value: 'value1' }], + ['key2', { value: 'value2', metadata: meta }], + ]); + }); + }); + + describe('get', () => { + it('should not allow modification of returned entries', () => { + const bag = propagation + .createBaggage() + .setEntry('key', { value: 'value' }); + + const entry = bag.getEntry('key'); + assert.ok(entry); + entry.value = 'mutated'; + + assert.strictEqual(bag.getEntry('key')?.value, 'value'); + }); + }); + + describe('set', () => { + it('should create a new bag when an entry is added', () => { + const bag = propagation.createBaggage(); + + const bag2 = bag.setEntry('key', { value: 'value' }); + + assert.notStrictEqual(bag, bag2); + assert.deepStrictEqual(bag.getAllEntries(), []); + assert.deepStrictEqual(bag2.getAllEntries(), [ + ['key', { value: 'value' }], + ]); + }); + }); + + describe('remove', () => { + it('should create a new bag when an entry is removed', () => { + const bag = propagation.createBaggage({ + key: { value: 'value' }, + }); + + const bag2 = bag.removeEntry('key'); + + assert.deepStrictEqual(bag.getAllEntries(), [ + ['key', { value: 'value' }], + ]); + + assert.deepStrictEqual(bag2.getAllEntries(), []); + }); + + it('should create an empty bag multiple keys are removed', () => { + const bag = propagation.createBaggage({ + key: { value: 'value' }, + key1: { value: 'value1' }, + key2: { value: 'value2' }, + }); + + const bag2 = bag.removeEntries('key', 'key1'); + + assert.deepStrictEqual(bag.getAllEntries(), [ + ['key', { value: 'value' }], + ['key1', { value: 'value1' }], + ['key2', { value: 'value2' }], + ]); + + assert.deepStrictEqual(bag2.getAllEntries(), [ + ['key2', { value: 'value2' }], + ]); + }); + + it('should create an empty bag when it cleared', () => { + const bag = propagation.createBaggage({ + key: { value: 'value' }, + key1: { value: 'value1' }, + }); + + const bag2 = bag.clear(); + + assert.deepStrictEqual(bag.getAllEntries(), [ + ['key', { value: 'value' }], + ['key1', { value: 'value1' }], + ]); + + assert.deepStrictEqual(bag2.getAllEntries(), []); + }); + }); + + describe('context', () => { + it('should set and get a baggage from a context', () => { + const bag = propagation.createBaggage(); + + const ctx = propagation.setBaggage(ROOT_CONTEXT, bag); + + assert.strictEqual(bag, propagation.getBaggage(ctx)); + }); + }); + + describe('metadata', () => { + it('should create an opaque object which returns the string unchanged', () => { + const meta = baggageEntryMetadataFromString('this is a string'); + + assert.strictEqual(meta.toString(), 'this is a string'); + }); + + it('should return an empty string if input is invalid', () => { + //@ts-expect-error only accepts string values + const meta = baggageEntryMetadataFromString(1); + + assert.strictEqual(meta.toString(), ''); + }); + + it('should retain metadata', () => { + const bag = propagation.createBaggage({ + key: { + value: 'value', + metadata: baggageEntryMetadataFromString('meta'), + }, + }); + + assert.deepStrictEqual(bag.getEntry('key')?.metadata?.toString(), 'meta'); + }); + }); +}); diff --git a/api/test/context/NoopContextManager.test.ts b/api/test/context/NoopContextManager.test.ts new file mode 100644 index 0000000000..8a8a732bf7 --- /dev/null +++ b/api/test/context/NoopContextManager.test.ts @@ -0,0 +1,138 @@ +/* + * 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 { createContextKey, ROOT_CONTEXT } from '../../src/context/context'; +import { NoopContextManager } from '../../src/context/NoopContextManager'; + +describe('NoopContextManager', () => { + let contextManager: NoopContextManager; + + describe('.enable()', () => { + it('should work', () => { + assert.doesNotThrow(() => { + contextManager = new NoopContextManager(); + assert( + contextManager.enable() === contextManager, + 'should return this' + ); + }); + }); + }); + + describe('.disable()', () => { + it('should work', () => { + assert.doesNotThrow(() => { + assert( + contextManager.disable() === contextManager, + 'should return this' + ); + }); + contextManager.enable(); + }); + }); + + describe('.with()', () => { + it('should run the callback (ROOT_CONTEXT as target)', done => { + contextManager.with(ROOT_CONTEXT, done); + }); + + it('should run the callback (object as target)', done => { + const key = createContextKey('test key 1'); + const test = ROOT_CONTEXT.setValue(key, 1); + contextManager.with(test, () => { + assert.strictEqual( + contextManager.active(), + ROOT_CONTEXT, + 'should not have context' + ); + return done(); + }); + }); + + it('should run the callback (when disabled)', done => { + contextManager.disable(); + contextManager.with(ROOT_CONTEXT, () => { + contextManager.enable(); + return done(); + }); + }); + + it('should forward this, arguments and return value', () => { + function fnWithThis(this: string, a: string, b: number): string { + assert.strictEqual(this, 'that'); + assert.strictEqual(arguments.length, 2); + assert.strictEqual(a, 'one'); + assert.strictEqual(b, 2); + return 'done'; + } + + const res = contextManager.with( + ROOT_CONTEXT, + fnWithThis, + 'that', + 'one', + 2 + ); + assert.strictEqual(res, 'done'); + + assert.strictEqual( + contextManager.with(ROOT_CONTEXT, () => 3.14), + 3.14 + ); + }); + }); + + describe('.active()', () => { + it('should always return ROOT_CONTEXT (when enabled)', () => { + assert.strictEqual( + contextManager.active(), + ROOT_CONTEXT, + 'should not have context' + ); + }); + + it('should always return ROOT_CONTEXT (when disabled)', () => { + contextManager.disable(); + assert.strictEqual( + contextManager.active(), + ROOT_CONTEXT, + 'should not have context' + ); + contextManager.enable(); + }); + }); + + describe('.bind()', () => { + it('should return the same target (when enabled)', () => { + const test = { a: 1 }; + assert.deepStrictEqual( + contextManager.bind(contextManager.active(), test), + test + ); + }); + + it('should return the same target (when disabled)', () => { + contextManager.disable(); + const test = { a: 1 }; + assert.deepStrictEqual( + contextManager.bind(contextManager.active(), test), + test + ); + contextManager.enable(); + }); + }); +}); diff --git a/api/test/diag/ComponentLogger.test.ts b/api/test/diag/ComponentLogger.test.ts new file mode 100644 index 0000000000..b9648c218a --- /dev/null +++ b/api/test/diag/ComponentLogger.test.ts @@ -0,0 +1,61 @@ +/* + * 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 * as sinon from 'sinon'; +import { diag, DiagLogger, DiagLogLevel } from '../../src'; + +class SpyLogger implements DiagLogger { + debug() {} + error() {} + info() {} + warn() {} + verbose() {} +} + +const loggerFunctions = ['verbose', 'debug', 'info', 'warn', 'error']; + +describe('ComponentLogger', () => { + let logger: DiagLogger; + + const sandbox = sinon.createSandbox(); + + beforeEach(() => { + logger = new SpyLogger(); + sandbox.spy(logger); + diag.setLogger(logger, DiagLogLevel.ALL); + // clean any messages up that might be there from the registration + sandbox.reset(); + }); + + afterEach(() => { + sandbox.restore(); + }); + + loggerFunctions.forEach(name => { + const fName = name as keyof SpyLogger; + it(`should call global logger function "${name}" with namespace as first param`, () => { + const componentLogger = diag.createComponentLogger({ namespace: 'foo' }); + componentLogger[fName]('test'); + + assert.strictEqual((logger[fName] as sinon.SinonSpy).callCount, 1); + assert.deepStrictEqual((logger[fName] as sinon.SinonSpy).args[0], [ + 'foo', + 'test', + ]); + }); + }); +}); diff --git a/api/test/diag/consoleLogger.test.ts b/api/test/diag/consoleLogger.test.ts new file mode 100644 index 0000000000..2210a7c68b --- /dev/null +++ b/api/test/diag/consoleLogger.test.ts @@ -0,0 +1,218 @@ +/* + * 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. + */ + +/* eslint-disable no-console */ + +import * as assert from 'assert'; +import { DiagConsoleLogger } from '../../src/diag/consoleLogger'; + +export const diagLoggerFunctions = [ + 'verbose', + 'debug', + 'info', + 'warn', + 'error', +] as const; + +const consoleFuncs: Array = [ + 'debug', + 'info', + 'warn', + 'error', + 'log', + 'trace', +]; + +const expectedConsoleMap: { [n: string]: keyof Console } = { + error: 'error', + warn: 'warn', + info: 'info', + debug: 'debug', + verbose: 'trace', +}; + +describe('DiagConsoleLogger', () => { + const origConsole = console; + const orig: any = {}; + const calledArgs: any = {}; + + // Save original functions + consoleFuncs.forEach(fName => { + orig[fName] = console[fName]; + calledArgs[fName] = null; + }); + + let canMockConsole = true; + + try { + // eslint-disable-next-line no-global-assign + console = origConsole; + } catch (ex) { + // Not supported on CI pipeline (works locally) + canMockConsole = false; + } + + beforeEach(() => { + // mock Console + consoleFuncs.forEach(fName => { + console[fName] = (...args: unknown[]) => { + calledArgs[fName] = args; + }; + }); + }); + + afterEach(() => { + // restore + if (canMockConsole) { + try { + // eslint-disable-next-line no-global-assign + console = origConsole; + } catch (ex) { + // Not supported on CI pipeline + canMockConsole = false; + } + } + + consoleFuncs.forEach(fName => { + calledArgs[fName] = null; + console[fName] = orig[fName]; + }); + }); + + describe('constructor', () => { + diagLoggerFunctions.forEach(fName => { + it(`console logger should provide ${fName} function`, () => { + const consoleLogger: any = new DiagConsoleLogger(); + consoleLogger[fName](`${fName} called %s`, 'param1'); + assert.ok( + typeof consoleLogger[fName] === 'function', + `Must have a ${fName} function` + ); + }); + + it(`should log ${expectedConsoleMap[fName]} message with ${fName} call only`, () => { + const consoleLogger: any = new DiagConsoleLogger(); + consoleLogger[fName](`${fName} called %s`, 'param1'); + + // Make sure only gets logged once + let matches = 0; + consoleFuncs.forEach(cName => { + if (cName !== expectedConsoleMap[fName]) { + assert.deepStrictEqual(calledArgs[cName], null); + } else { + assert.deepStrictEqual(calledArgs[expectedConsoleMap[fName]], [ + `${fName} called %s`, + 'param1', + ]); + matches++; + } + }); + + assert.deepStrictEqual(calledArgs.log, null); + assert.strictEqual(matches, 1, 'should log at least once'); + }); + + consoleFuncs.forEach(cName => { + it(`should log ${fName} message even when console doesn't support ${cName} call before construction`, () => { + console[cName] = undefined; + const consoleLogger: any = new DiagConsoleLogger(); + consoleLogger[fName](`${fName} called %s`, 'param1'); + if (cName !== expectedConsoleMap[fName]) { + assert.deepStrictEqual(calledArgs[cName], null); + } else { + assert.deepStrictEqual(calledArgs.log, [ + `${fName} called %s`, + 'param1', + ]); + } + }); + + it(`should log ${fName} message even when console doesn't support ${cName} call after construction`, () => { + const consoleLogger: any = new DiagConsoleLogger(); + console[cName] = undefined; + consoleLogger[fName](`${fName} called %s`, 'param1'); + if (cName !== expectedConsoleMap[fName]) { + assert.deepStrictEqual(calledArgs[cName], null); + } else { + assert.deepStrictEqual(calledArgs.log, [ + `${fName} called %s`, + 'param1', + ]); + } + }); + }); + }); + + if (canMockConsole) { + diagLoggerFunctions.forEach(fName => { + const cName = expectedConsoleMap[fName]; + it(`should not throw even when console is not supported for ${fName} call`, () => { + // eslint-disable-next-line no-global-assign + (console as any) = undefined; + const consoleLogger: any = new DiagConsoleLogger(); + consoleLogger[fName](`${fName} called %s`, 'param1'); + assert.deepStrictEqual(calledArgs[cName], null); + assert.deepStrictEqual(calledArgs.log, null); + }); + + it(`should not throw even when console is disabled after construction for ${fName} call`, () => { + const consoleLogger: any = new DiagConsoleLogger(); + // eslint-disable-next-line no-global-assign + (console as any) = undefined; + consoleLogger[fName](`${fName} called %s`, 'param1'); + assert.deepStrictEqual(calledArgs[expectedConsoleMap[fName]], null); + assert.deepStrictEqual(calledArgs.log, null); + }); + + it(`should not throw even when console is invalid after construction for ${fName} call`, () => { + const invalidConsole = { + debug: 1, + warn: 2, + error: 3, + trace: 4, + info: 5, + log: 6, + }; + + const consoleLogger = new DiagConsoleLogger(); + // eslint-disable-next-line no-global-assign + (console as any) = invalidConsole; + consoleLogger[fName](`${fName} called %s`, 'param1'); + assert.deepStrictEqual(calledArgs[expectedConsoleMap[fName]], null); + assert.deepStrictEqual(calledArgs.log, null); + }); + + it(`should not throw even when console is invalid before construction for ${fName} call`, () => { + const invalidConsole = { + debug: 1, + warn: 2, + error: 3, + trace: 4, + info: 5, + log: 6, + }; + + // eslint-disable-next-line no-global-assign + (console as any) = invalidConsole; + const consoleLogger = new DiagConsoleLogger(); + consoleLogger[fName](`${fName} called %s`, 'param1'); + assert.deepStrictEqual(calledArgs[expectedConsoleMap[fName]], null); + assert.deepStrictEqual(calledArgs.log, null); + }); + }); + } + }); +}); diff --git a/api/test/diag/logLevel.test.ts b/api/test/diag/logLevel.test.ts new file mode 100644 index 0000000000..1825db31a9 --- /dev/null +++ b/api/test/diag/logLevel.test.ts @@ -0,0 +1,236 @@ +/* + * 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 { diag } from '../../src'; +import { createLogLevelDiagLogger } from '../../src/diag/internal/logLevelLogger'; +import { createNoopDiagLogger } from '../../src/diag/internal/noopLogger'; +import { DiagLogger, DiagLogLevel } from '../../src/diag/types'; + +// Matches the previous Logger definition +const incompleteLoggerFuncs = ['debug', 'info', 'warn', 'error'] as const; + +export const diagLoggerFunctions = [ + 'verbose', + 'debug', + 'info', + 'warn', + 'error', +] as const; + +describe('LogLevelFilter DiagLogger', () => { + const calledArgs: any = { + error: null, + warn: null, + info: null, + debug: null, + verbose: null, + }; + + let dummyLogger: DiagLogger; + + /** Simulated Legacy logger */ + let incompleteLogger: DiagLogger; + + const restoreCallHistory = () => { + diagLoggerFunctions.forEach(fName => { + calledArgs[fName] = null; + }); + }; + + beforeEach(() => { + // Set no logger so that sinon doesn't complain about TypeError: Attempted to wrap xxxx which is already wrapped + diag.disable(); + + // mock + dummyLogger = {} as DiagLogger; + diagLoggerFunctions.forEach(fName => { + dummyLogger[fName] = (...args: unknown[]) => { + calledArgs[fName] = args; + }; + }); + + incompleteLogger = {} as DiagLogger; + incompleteLoggerFuncs.forEach(fName => { + incompleteLogger[fName] = (...args: unknown[]) => { + calledArgs[fName] = args; + }; + }); + }); + + afterEach(() => { + restoreCallHistory(); + }); + + const levelMap: Array<{ + message: string; + level: DiagLogLevel; + ignoreFuncs: Array; + }> = [ + { message: 'ALL', level: DiagLogLevel.ALL, ignoreFuncs: [] }, + { message: 'greater than ALL', level: 32768, ignoreFuncs: [] }, + { message: 'VERBOSE', level: DiagLogLevel.VERBOSE, ignoreFuncs: [] }, + { message: 'DEBUG', level: DiagLogLevel.DEBUG, ignoreFuncs: ['verbose'] }, + { + message: 'INFO', + level: DiagLogLevel.INFO, + ignoreFuncs: ['verbose', 'debug'], + }, + { + message: 'WARN', + level: DiagLogLevel.WARN, + ignoreFuncs: ['verbose', 'debug', 'info'], + }, + { + message: 'ERROR', + level: DiagLogLevel.ERROR, + ignoreFuncs: ['verbose', 'debug', 'info', 'warn'], + }, + { + message: 'between ERROR and NONE', + level: 1, + ignoreFuncs: ['verbose', 'debug', 'info', 'warn', 'error'], + }, + { + message: 'NONE', + level: DiagLogLevel.NONE, + ignoreFuncs: ['verbose', 'debug', 'info', 'warn', 'error'], + }, + { + message: 'less than NONE', + level: -1000, + ignoreFuncs: ['verbose', 'debug', 'info', 'warn', 'error'], + }, + ]; + + levelMap.forEach(map => { + describe(`with ${map.message} log level`, () => { + diagLoggerFunctions.forEach(fName => { + describe(`calling ${fName} message`, () => { + it('should log', () => { + const testLogger = createLogLevelDiagLogger(map.level, dummyLogger); + testLogger[fName](`${fName} called %s`, 'param1'); + diagLoggerFunctions.forEach(lName => { + if (fName === lName && map.ignoreFuncs.indexOf(lName) === -1) { + assert.deepStrictEqual(calledArgs[lName], [ + `${fName} called %s`, + 'param1', + ]); + } else { + assert.strictEqual(calledArgs[lName], null); + } + }); + }); + + it('should be noop for null with explicit noop Logger log', () => { + const testLogger = createLogLevelDiagLogger( + map.level, + createNoopDiagLogger() + ); + testLogger[fName](`${fName} called %s`, 'param1'); + diagLoggerFunctions.forEach(lName => { + assert.strictEqual(calledArgs[lName], null); + }); + }); + + it('should be noop and not throw for null and no default Logger log', () => { + // @ts-expect-error null logger is not allowed + const testLogger = createLogLevelDiagLogger(map.level, null); + testLogger[fName](`${fName} called %s`, 'param1'); + diagLoggerFunctions.forEach(lName => { + assert.strictEqual(calledArgs[lName], null); + }); + }); + + it('should be noop and not throw for undefined and no default Logger log', () => { + // @ts-expect-error undefined logger is not allowed + const testLogger = createLogLevelDiagLogger(map.level, undefined); + testLogger[fName](`${fName} called %s`, 'param1'); + diagLoggerFunctions.forEach(lName => { + assert.strictEqual(calledArgs[lName], null); + }); + }); + + levelMap.forEach(masterLevelMap => { + describe(`when diag logger is set to ${masterLevelMap.message}`, () => { + it('diag.setLogger level is ignored when using a specific logger', () => { + diag.setLogger(dummyLogger, masterLevelMap.level); + + const testLogger = createLogLevelDiagLogger( + map.level, + dummyLogger + ); + restoreCallHistory(); + testLogger[fName](`${fName} called %s`, 'param1'); + diagLoggerFunctions.forEach(lName => { + if ( + fName === lName && + map.ignoreFuncs.indexOf(lName) === -1 + ) { + assert.deepStrictEqual(calledArgs[lName], [ + `${fName} called %s`, + 'param1', + ]); + } else { + assert.strictEqual(calledArgs[lName], null); + } + }); + }); + }); + }); + + it('diag.setLogger level and logger should log', () => { + diag.setLogger(dummyLogger, map.level); + restoreCallHistory(); + diag[fName](`${fName} called %s`, 'param1'); + diagLoggerFunctions.forEach(lName => { + if (fName === lName && map.ignoreFuncs.indexOf(lName) === -1) { + assert.deepStrictEqual(calledArgs[lName], [ + `${fName} called %s`, + 'param1', + ]); + } else { + assert.strictEqual(calledArgs[lName], null); + } + }); + }); + + it('should not throw with an invalid DiagLogger', () => { + const invalidLogger = { + debug: 1, + warn: 2, + error: 3, + trace: 4, + info: 5, + log: 6, + }; + + const testLogger = createLogLevelDiagLogger( + map.level, + invalidLogger as any + ); + restoreCallHistory(); + + testLogger[fName](`${fName} called %s`, 'param1'); + diagLoggerFunctions.forEach(lName => { + assert.strictEqual(calledArgs[lName], null); + }); + }); + }); + }); + }); + }); +}); diff --git a/api/test/diag/logger.test.ts b/api/test/diag/logger.test.ts new file mode 100644 index 0000000000..c0efdcb6f2 --- /dev/null +++ b/api/test/diag/logger.test.ts @@ -0,0 +1,126 @@ +/* + * 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 sinon = require('sinon'); +import { diag, DiagLogLevel } from '../../src'; +import { createNoopDiagLogger } from '../../src/diag/internal/noopLogger'; +import { DiagLogger } from '../../src/diag/types'; + +export const diagLoggerFunctions = [ + 'verbose', + 'debug', + 'info', + 'warn', + 'error', +] as const; +describe('DiagLogger functions', () => { + const calledArgs: any = { + error: null, + warn: null, + info: null, + debug: null, + verbose: null, + }; + + let dummyLogger: DiagLogger; + + const restoreCallHistory = () => { + diagLoggerFunctions.forEach(fName => { + calledArgs[fName] = null; + }); + }; + + beforeEach(() => { + // mock + dummyLogger = {} as DiagLogger; + diagLoggerFunctions.forEach(fName => { + dummyLogger[fName] = (...args: unknown[]) => { + calledArgs[fName] = args; + }; + }); + }); + + afterEach(() => { + restoreCallHistory(); + diag.disable(); + }); + + describe('constructor', () => { + diagLoggerFunctions.forEach(fName => { + it(`should log with ${fName} message`, () => { + const testLogger = dummyLogger; + testLogger[fName](`${fName} called %s`, 'param1'); + diagLoggerFunctions.forEach(lName => { + if (fName === lName) { + assert.deepStrictEqual(calledArgs[fName], [ + `${fName} called %s`, + 'param1', + ]); + } else { + assert.strictEqual(calledArgs[lName], null); + } + }); + }); + + it(`diag should log with ${fName} message`, () => { + diag.setLogger(dummyLogger, DiagLogLevel.ALL); + restoreCallHistory(); + diag[fName](`${fName} called %s`, 'param1'); + diagLoggerFunctions.forEach(lName => { + if (fName === lName) { + assert.deepStrictEqual(calledArgs[fName], [ + `${fName} called %s`, + 'param1', + ]); + } else { + assert.strictEqual(calledArgs[lName], null); + } + }); + }); + + it(`NoopLogger should implement all functions and not throw when ${fName} called`, () => { + const testLogger = createNoopDiagLogger(); + + assert.ok(typeof testLogger[fName], 'function'); + testLogger[fName](`${fName} called %s`, 'param1'); + }); + }); + }); + + describe('diag is used as the diag logger in setLogger', () => { + it('should not throw', () => { + diag.setLogger(diag); + }); + + it('should use the previously registered logger to log the error', () => { + const error = sinon.stub(); + diag.setLogger({ + verbose: () => {}, + debug: () => {}, + info: () => {}, + warn: () => {}, + error, + }); + + sinon.assert.notCalled(error); + + diag.setLogger(diag); + + sinon.assert.calledOnce(error); + }); + }); +}); diff --git a/api/test/index-webpack.ts b/api/test/index-webpack.ts new file mode 100644 index 0000000000..061a48ccfa --- /dev/null +++ b/api/test/index-webpack.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ +const testsContext = require.context('.', true, /test$/); +testsContext.keys().forEach(testsContext); + +const srcContext = require.context('.', true, /src$/); +srcContext.keys().forEach(srcContext); diff --git a/api/test/internal/global.test.ts b/api/test/internal/global.test.ts new file mode 100644 index 0000000000..ba6218c7ed --- /dev/null +++ b/api/test/internal/global.test.ts @@ -0,0 +1,155 @@ +/* + * 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 { getGlobal } from '../../src/internal/global-utils'; +import { _globalThis } from '../../src/platform'; +import { NoopContextManager } from '../../src/context/NoopContextManager'; +import { DiagLogLevel } from '../../src/diag/types'; +import sinon = require('sinon'); + +const api1 = require('../../src') as typeof import('../../src'); + +// clear cache and load a second instance of the api +for (const key of Object.keys(require.cache)) { + delete require.cache[key]; +} +const api2 = require('../../src') as typeof import('../../src'); + +// This will need to be changed manually on major version changes. +// It is intentionally not autogenerated to ensure the author of the change is aware of what they are doing. +const GLOBAL_API_SYMBOL_KEY = 'opentelemetry.js.api.1'; + +const getMockLogger = () => ({ + verbose: sinon.spy(), + debug: sinon.spy(), + info: sinon.spy(), + warn: sinon.spy(), + error: sinon.spy(), +}); + +describe('Global Utils', () => { + // prove they are separate instances + assert.notEqual(api1, api2); + // that return separate noop instances to start + assert.notStrictEqual( + api1.context['_getContextManager'](), + api2.context['_getContextManager']() + ); + + beforeEach(() => { + api1.context.disable(); + api1.propagation.disable(); + api1.trace.disable(); + api1.diag.disable(); + // @ts-expect-error we are modifying internals for testing purposes here + delete _globalThis[Symbol.for(GLOBAL_API_SYMBOL_KEY)]; + }); + + it('should change the global context manager', () => { + const original = api1.context['_getContextManager'](); + const newContextManager = new NoopContextManager(); + api1.context.setGlobalContextManager(newContextManager); + assert.notStrictEqual(api1.context['_getContextManager'](), original); + assert.strictEqual(api1.context['_getContextManager'](), newContextManager); + }); + + it('should load an instance from one which was set in the other', () => { + api1.context.setGlobalContextManager(new NoopContextManager()); + assert.strictEqual( + api1.context['_getContextManager'](), + api2.context['_getContextManager']() + ); + }); + + it('should disable both if one is disabled', () => { + const manager = new NoopContextManager(); + api1.context.setGlobalContextManager(manager); + + assert.strictEqual(manager, api1.context['_getContextManager']()); + api2.context.disable(); + assert.notStrictEqual(manager, api1.context['_getContextManager']()); + }); + + it('should return the module NoOp implementation if the version is a mismatch', () => { + const newContextManager = new NoopContextManager(); + api1.context.setGlobalContextManager(newContextManager); + + // ensure new context manager is returned + assert.strictEqual(api1.context['_getContextManager'](), newContextManager); + + const globalInstance = getGlobal('context'); + assert.ok(globalInstance); + // @ts-expect-error we are modifying internals for testing purposes here + _globalThis[Symbol.for(GLOBAL_API_SYMBOL_KEY)].version = '0.0.1'; + + // ensure new context manager is not returned because version above is incompatible + assert.notStrictEqual( + api1.context['_getContextManager'](), + newContextManager + ); + }); + + it('should debug log registrations', () => { + const logger = getMockLogger(); + api1.diag.setLogger(logger, DiagLogLevel.DEBUG); + + const newContextManager = new NoopContextManager(); + api1.context.setGlobalContextManager(newContextManager); + + sinon.assert.calledWith(logger.debug, sinon.match(/global for context/)); + sinon.assert.calledWith(logger.debug, sinon.match(/global for diag/)); + sinon.assert.calledTwice(logger.debug); + }); + + it('should log an error if there is a duplicate registration', () => { + const logger = getMockLogger(); + api1.diag.setLogger(logger); + + api1.context.setGlobalContextManager(new NoopContextManager()); + api1.context.setGlobalContextManager(new NoopContextManager()); + + sinon.assert.calledOnce(logger.error); + assert.strictEqual(logger.error.firstCall.args.length, 1); + assert.ok( + logger.error.firstCall.args[0].startsWith( + 'Error: @opentelemetry/api: Attempted duplicate registration of API: context' + ) + ); + }); + + it('should allow duplicate registration of the diag logger', () => { + const logger1 = getMockLogger(); + const logger2 = getMockLogger(); + + api1.diag.setLogger(logger1); + api1.diag.setLogger(logger2); + + const MSG = '__log message__'; + api1.diag.info(MSG); + + sinon.assert.notCalled(logger1.error); + sinon.assert.notCalled(logger1.info); + sinon.assert.calledOnce(logger1.warn); + sinon.assert.calledWith(logger1.warn, sinon.match(/will be overwritten/i)); + + sinon.assert.notCalled(logger2.error); + sinon.assert.calledOnce(logger2.warn); + sinon.assert.calledWith(logger2.warn, sinon.match(/will overwrite/i)); + sinon.assert.calledOnce(logger2.info); + sinon.assert.calledWith(logger2.info, MSG); + }); +}); diff --git a/api/test/internal/semver.test.ts b/api/test/internal/semver.test.ts new file mode 100644 index 0000000000..e9ac3ec727 --- /dev/null +++ b/api/test/internal/semver.test.ts @@ -0,0 +1,148 @@ +/* + * 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 { + isCompatible, + _makeCompatibilityCheck, +} from '../../src/internal/semver'; +import { VERSION } from '../../src/version'; + +describe('semver', () => { + it('should be compatible if versions are equal', () => { + assert.ok(isCompatible(VERSION)); + }); + + it('returns false if own version cannot be parsed', () => { + const check = _makeCompatibilityCheck('this is not semver'); + assert.ok(!check('1.0.0')); + }); + + it('incompatible if other version cannot be parsed', () => { + const check = _makeCompatibilityCheck('0.1.2'); + assert.ok(!check('this is not semver')); + }); + + describe('>= 1.0.0', () => { + const globalVersion = '5.5.5'; + const vers: [string, boolean][] = [ + // same major/minor run should be compatible + ['5.5.5', true], + ['5.5.6', true], + ['5.5.4', true], + + // prerelease version should not be compatible + ['5.5.5-rc.0', false], + + // if our version has a minor version increase, we may try to call methods which don't exist on the global + ['5.6.5', false], + ['5.6.6', false], + ['5.6.4', false], + + // if the global version is ahead of us by a minor revision, it has at least the methods we know about + ['5.4.5', true], + ['5.4.6', true], + ['5.4.4', true], + + // major version mismatch is always incompatible + ['6.5.5', false], + ['6.5.6', false], + ['6.5.4', false], + ['6.6.5', false], + ['6.6.6', false], + ['6.6.4', false], + ['6.4.5', false], + ['6.4.6', false], + ['6.4.4', false], + ['4.5.5', false], + ['4.5.6', false], + ['4.5.4', false], + ['4.6.5', false], + ['4.6.6', false], + ['4.6.4', false], + ['4.4.5', false], + ['4.4.6', false], + ['4.4.4', false], + ]; + + test(globalVersion, vers); + }); + + describe('< 1.0.0', () => { + const globalVersion = '0.5.5'; + const vers: [string, boolean][] = [ + // same minor/patch should be compatible + ['0.5.5', true], + + // prerelease version should not be compatible + ['0.5.5-rc.0', false], + + // if our version has a patch version increase, we may try to call methods which don't exist on the global + ['0.5.6', false], + + // if the global version is ahead of us by a patch revision, it has at least the methods we know about + ['0.5.4', true], + + // minor version mismatch is always incompatible + ['0.6.5', false], + ['0.6.6', false], + ['0.6.4', false], + ['0.4.5', false], + ['0.4.6', false], + ['0.4.4', false], + + // major version mismatch is always incompatible + ['1.5.5', false], + ['1.5.6', false], + ['1.5.4', false], + ['1.6.5', false], + ['1.6.6', false], + ['1.6.4', false], + ['1.4.5', false], + ['1.4.6', false], + ['1.4.4', false], + ]; + + test(globalVersion, vers); + }); + + describe('global version is prerelease', () => { + const globalVersion = '1.0.0-rc.3'; + const vers: [string, boolean][] = [ + // must match exactly + ['1.0.0', false], + ['1.0.0-rc.2', false], + ['1.0.0-rc.4', false], + + ['1.0.0-rc.3', true], + ]; + + test(globalVersion, vers); + }); +}); + +function test(globalVersion: string, vers: [string, boolean][]) { + describe(`global version is ${globalVersion}`, () => { + for (const [version, compatible] of vers) { + it(`API version ${version} ${ + compatible ? 'should' : 'should not' + } be able to access global`, () => { + const check = _makeCompatibilityCheck(version); + assert.strictEqual(check(globalVersion), compatible); + }); + } + }); +} diff --git a/api/test/internal/version.test.ts b/api/test/internal/version.test.ts new file mode 100644 index 0000000000..4d0e5f2542 --- /dev/null +++ b/api/test/internal/version.test.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 * as assert from 'assert'; +import { VERSION } from '../../src/version'; + +describe('version', () => { + it('should have generated VERSION.ts', () => { + const pjson = require('../../package.json'); + assert.strictEqual(pjson.version, VERSION); + }); + + it('prerelease tag versions are banned', () => { + // see https://github.com/open-telemetry/opentelemetry-js-api/issues/74 + assert.ok(VERSION.match(/^\d+\.\d+\.\d+$/)); + }); +}); diff --git a/api/test/noop-implementations/noop-span.test.ts b/api/test/noop-implementations/noop-span.test.ts new file mode 100644 index 0000000000..de0007aeeb --- /dev/null +++ b/api/test/noop-implementations/noop-span.test.ts @@ -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 { + SpanStatusCode, + INVALID_SPANID, + INVALID_TRACEID, + TraceFlags, +} from '../../src'; +import { NonRecordingSpan } from '../../src/trace/NonRecordingSpan'; + +describe('NonRecordingSpan', () => { + it('do not crash', () => { + const span = new NonRecordingSpan(); + span.setAttribute('my_string_attribute', 'foo'); + span.setAttribute('my_number_attribute', 123); + span.setAttribute('my_boolean_attribute', false); + span.setAttribute('my_obj_attribute', { a: true }); + span.setAttribute('my_sym_attribute', Symbol('a')); + span.setAttributes({ + my_string_attribute: 'foo', + my_number_attribute: 123, + }); + + span.addEvent('sent'); + span.addEvent('sent', { id: '42', key: 'value' }); + + span.setStatus({ code: SpanStatusCode.ERROR }); + + span.updateName('my-span'); + + assert.ok(!span.isRecording()); + assert.deepStrictEqual(span.spanContext(), { + traceId: INVALID_TRACEID, + spanId: INVALID_SPANID, + traceFlags: TraceFlags.NONE, + }); + span.end(); + }); +}); diff --git a/api/test/noop-implementations/noop-tracer-provider.test.ts b/api/test/noop-implementations/noop-tracer-provider.test.ts new file mode 100644 index 0000000000..5b7e5ff7b1 --- /dev/null +++ b/api/test/noop-implementations/noop-tracer-provider.test.ts @@ -0,0 +1,31 @@ +/* + * 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 { NoopTracer } from '../../src/trace/NoopTracer'; +import { NoopTracerProvider } from '../../src/trace/NoopTracerProvider'; + +describe('NoopTracerProvider', () => { + it('should not crash', () => { + const tracerProvider = new NoopTracerProvider(); + + assert.ok(tracerProvider.getTracer('tracer-name') instanceof NoopTracer); + assert.ok(tracerProvider.getTracer('tracer-name', 'v1') instanceof NoopTracer); + assert.ok(tracerProvider.getTracer('tracer-name', 'v1', { + schemaUrl: 'https://opentelemetry.io/schemas/1.7.0' + }) instanceof NoopTracer); + }); +}); diff --git a/api/test/noop-implementations/noop-tracer.test.ts b/api/test/noop-implementations/noop-tracer.test.ts new file mode 100644 index 0000000000..037017208e --- /dev/null +++ b/api/test/noop-implementations/noop-tracer.test.ts @@ -0,0 +1,84 @@ +/* + * 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 { + context, + Span, + SpanContext, + SpanKind, + trace, + TraceFlags, +} from '../../src'; +import { NonRecordingSpan } from '../../src/trace/NonRecordingSpan'; +import { NoopTracer } from '../../src/trace/NoopTracer'; + +describe('NoopTracer', () => { + it('should not crash', () => { + const tracer = new NoopTracer(); + + assert.ok(tracer.startSpan('span-name') instanceof NonRecordingSpan); + assert.ok( + tracer.startSpan('span-name1', { kind: SpanKind.CLIENT }) instanceof + NonRecordingSpan + ); + assert.ok( + tracer.startSpan('span-name2', { kind: SpanKind.CLIENT }) instanceof + NonRecordingSpan + ); + }); + + it('should propagate valid spanContext on the span (from context)', () => { + const tracer = new NoopTracer(); + const parent: SpanContext = { + traceId: 'd4cda95b652f4a1592b449dd92ffda3b', + spanId: '6e0c63ffe4e34c42', + traceFlags: TraceFlags.NONE, + }; + const span = tracer.startSpan( + 'test-1', + {}, + trace.setSpanContext(context.active(), parent) + ); + assert(span.spanContext().traceId === parent.traceId); + assert(span.spanContext().spanId === parent.spanId); + assert(span.spanContext().traceFlags === parent.traceFlags); + }); + + it('should accept 2 to 4 args and start an active span', () => { + const tracer = new NoopTracer(); + const name = 'span-name'; + const fn = (span: Span) => { + try { + return 1; + } finally { + span.end(); + } + }; + const opts = { attributes: { foo: 'bar' } }; + + assert.strictEqual((tracer as any).startActiveSpan(name), undefined); + + assert.strictEqual(tracer.startActiveSpan(name, fn), 1); + + assert.strictEqual(tracer.startActiveSpan(name, opts, fn), 1); + + assert.strictEqual( + tracer.startActiveSpan(name, opts, context.active(), fn), + 1 + ); + }); +}); diff --git a/api/test/proxy-implementations/proxy-tracer.test.ts b/api/test/proxy-implementations/proxy-tracer.test.ts new file mode 100644 index 0000000000..bb9c55bfe1 --- /dev/null +++ b/api/test/proxy-implementations/proxy-tracer.test.ts @@ -0,0 +1,189 @@ +/* + * 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 * as sinon from 'sinon'; +import { + context, + ProxyTracer, + ProxyTracerProvider, + ROOT_CONTEXT, + Span, + SpanKind, + SpanOptions, + Tracer, + TracerProvider, +} from '../../src'; +import { NonRecordingSpan } from '../../src/trace/NonRecordingSpan'; +import { NoopTracer } from '../../src/trace/NoopTracer'; + +describe('ProxyTracer', () => { + let provider: ProxyTracerProvider; + const sandbox = sinon.createSandbox(); + + beforeEach(() => { + provider = new ProxyTracerProvider(); + }); + + afterEach(() => { + sandbox.restore(); + }); + + describe('when no delegate is set', () => { + it('should return proxy tracers', () => { + const tracer = provider.getTracer('test'); + + assert.ok(tracer instanceof ProxyTracer); + }); + + it('startSpan should return Noop Spans', () => { + const tracer = provider.getTracer('test'); + + assert.ok(tracer.startSpan('span-name') instanceof NonRecordingSpan); + assert.ok( + tracer.startSpan('span-name1', { kind: SpanKind.CLIENT }) instanceof + NonRecordingSpan + ); + assert.ok( + tracer.startSpan('span-name2', { kind: SpanKind.CLIENT }) instanceof + NonRecordingSpan + ); + }); + }); + + describe('when delegate is set before getTracer', () => { + let delegate: TracerProvider; + let getTracerStub: sinon.SinonStub; + + beforeEach(() => { + getTracerStub = sandbox.stub().returns(new NoopTracer()); + delegate = { + getTracer: getTracerStub, + }; + provider.setDelegate(delegate); + }); + + it('should return tracers directly from the delegate', () => { + const tracer = provider.getTracer('test', 'v0'); + + sandbox.assert.calledOnce(getTracerStub); + assert.strictEqual(getTracerStub.firstCall.returnValue, tracer); + assert.deepStrictEqual(getTracerStub.firstCall.args, [ + 'test', + 'v0', + undefined, + ]); + }); + + it('should return tracers directly from the delegate with schema url', () => { + const tracer = provider.getTracer('test', 'v0', { + schemaUrl: 'https://opentelemetry.io/schemas/1.7.0', + }); + + sandbox.assert.calledOnce(getTracerStub); + assert.strictEqual(getTracerStub.firstCall.returnValue, tracer); + assert.deepStrictEqual(getTracerStub.firstCall.args, [ + 'test', + 'v0', + { schemaUrl: 'https://opentelemetry.io/schemas/1.7.0' }, + ]); + }); + }); + + describe('when delegate is set after getTracer', () => { + let tracer: Tracer; + let delegate: TracerProvider; + let delegateSpan: Span; + let delegateTracer: Tracer; + + beforeEach(() => { + delegateSpan = new NonRecordingSpan(); + delegateTracer = { + startSpan() { + return delegateSpan; + }, + + startActiveSpan() { + // stubbed + }, + }; + + tracer = provider.getTracer('test'); + + delegate = { + getTracer() { + return delegateTracer; + }, + }; + provider.setDelegate(delegate); + }); + + it('should create spans using the delegate tracer', () => { + const span = tracer.startSpan('test'); + + assert.strictEqual(span, delegateSpan); + }); + + it('should create active spans using the delegate tracer', () => { + // sinon types are broken with overloads, hence the any + // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/36436 + const startActiveSpanStub = sinon.stub( + delegateTracer, + 'startActiveSpan' + ); + + const name = 'span-name'; + const fn = (span: Span) => { + try { + return 1; + } finally { + span.end(); + } + }; + const opts = { attributes: { foo: 'bar' } }; + const ctx = context.active(); + + startActiveSpanStub.withArgs(name, fn).returns(1); + startActiveSpanStub.withArgs(name, opts, fn).returns(2); + startActiveSpanStub.withArgs(name, opts, ctx, fn).returns(3); + + assert.strictEqual(tracer.startActiveSpan(name, fn), 1); + assert.strictEqual(tracer.startActiveSpan(name, opts, fn), 2); + assert.strictEqual(tracer.startActiveSpan(name, opts, ctx, fn), 3); + }); + + it('should pass original arguments to DelegateTracer#startSpan', () => { + const startSpanStub = sandbox.stub(delegateTracer, 'startSpan'); + + const name = 'name1'; + const options: SpanOptions = {}; + const ctx = ROOT_CONTEXT.setValue(Symbol('test'), 1); + tracer.startSpan(name, options, ctx); + + // Assert the proxy tracer has the full API of the NoopTracer + assert.strictEqual( + NoopTracer.prototype.startSpan.length, + ProxyTracer.prototype.startSpan.length + ); + assert.deepStrictEqual(Object.getOwnPropertyNames(NoopTracer.prototype), [ + 'constructor', + 'startSpan', + 'startActiveSpan', + ]); + sandbox.assert.calledOnceWithExactly(startSpanStub, name, options, ctx); + }); + }); +}); diff --git a/api/test/trace/spancontext-utils.test.ts b/api/test/trace/spancontext-utils.test.ts new file mode 100644 index 0000000000..09f5712b27 --- /dev/null +++ b/api/test/trace/spancontext-utils.test.ts @@ -0,0 +1,70 @@ +/* + * 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 * as context from '../../src/trace/spancontext-utils'; +import { INVALID_SPANID, INVALID_TRACEID, TraceFlags } from '../../src'; + +describe('spancontext-utils', () => { + it('should return true for valid spancontext', () => { + const spanContext = { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.NONE, + }; + assert.ok(context.isSpanContextValid(spanContext)); + }); + + it('should return false when traceId is invalid', () => { + const spanContext = { + traceId: INVALID_TRACEID, + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.NONE, + }; + assert.ok(!context.isSpanContextValid(spanContext)); + }); + + it('should return false when spanId is invalid', () => { + const spanContext = { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: INVALID_SPANID, + traceFlags: TraceFlags.NONE, + }; + assert.ok(!context.isSpanContextValid(spanContext)); + }); + + it('should return false when traceId & spanId is invalid', () => { + const spanContext = { + traceId: INVALID_TRACEID, + spanId: INVALID_SPANID, + traceFlags: TraceFlags.NONE, + }; + assert.ok(!context.isSpanContextValid(spanContext)); + }); + + it('should wrap a SpanContext in a non-recording span', () => { + const spanContext = { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.NONE, + }; + + const span = context.wrapSpanContext(spanContext); + + assert.deepStrictEqual(span.spanContext(), spanContext); + assert.strictEqual(span.isRecording(), false); + }); +}); diff --git a/api/test/trace/tracestate-validators.test.ts b/api/test/trace/tracestate-validators.test.ts new file mode 100644 index 0000000000..0f355f1c12 --- /dev/null +++ b/api/test/trace/tracestate-validators.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 * as assert from 'assert'; +import { validateKey, validateValue } from '../../src/trace/internal/tracestate-validators'; + +describe('validators', () => { + describe('validateKey', () => { + const validKeysTestCases = [ + 'abcdefghijklmnopqrstuvwxyz0123456789-_*/', + 'baz-', + 'baz_', + 'baz*', + 'baz*bar', + 'baz/', + 'tracestate', + 'fw529a3039@dt', + '6cab5bb-29a@dt', + ]; + validKeysTestCases.forEach(testCase => + it(`returns true when key contains valid chars ${testCase}`, () => { + assert.ok(validateKey(testCase), `${testCase} should be valid`); + }) + ); + + const invalidKeysTestCases = [ + '1_key', + 'kEy_1', + 'k'.repeat(257), + 'key,', + 'TrAcEsTaTE', + 'TRACESTATE', + '', + '6num', + ]; + invalidKeysTestCases.forEach(testCase => + it(`returns true when key contains invalid chars ${testCase}`, () => { + assert.ok(!validateKey(testCase), `${testCase} should be invalid`); + }) + ); + }); + + describe('validateValue', () => { + const validValuesTestCases = [ + 'first second', + 'baz*', + 'baz$', + 'baz@', + 'first-second', + 'baz~bar', + 'test-v1:120', + '-second', + 'first.second', + 'TrAcEsTaTE', + 'TRACESTATE', + ]; + validValuesTestCases.forEach(testCase => + it(`returns true when value contains valid chars ${testCase}`, () => { + assert.ok(validateValue(testCase)); + }) + ); + + const invalidValuesTestCases = [ + 'my_value=5', + 'first,second', + 'first ', + 'k'.repeat(257), + ',baz', + 'baz,', + 'baz=', + '', + ]; + invalidValuesTestCases.forEach(testCase => + it(`returns true when value contains invalid chars ${testCase}`, () => { + assert.ok(!validateValue(testCase)); + }) + ); + }); +}); diff --git a/api/test/trace/tracestate.test.ts b/api/test/trace/tracestate.test.ts new file mode 100644 index 0000000000..699c6cd9cb --- /dev/null +++ b/api/test/trace/tracestate.test.ts @@ -0,0 +1,139 @@ +/* + * 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 { createTraceState } from '../../src/trace/internal/utils'; +import { TraceStateImpl } from '../../src/trace/internal/tracestate-impl'; + +describe('TraceState', () => { + describe('.serialize()', () => { + it('returns serialize string', () => { + const state = createTraceState('a=1,b=2'); + assert.deepStrictEqual(state.serialize(), 'a=1,b=2'); + }); + + it('must create a createTraceState and move updated keys to the front', () => { + const orgState = createTraceState('a=1,b=2'); + const state = orgState.set('b', '3'); + assert.deepStrictEqual(orgState.serialize(), 'a=1,b=2'); + assert.deepStrictEqual(state.serialize(), 'b=3,a=1'); + }); + + it('must create a createTraceState and add new keys to the front', () => { + let state = createTraceState().set('vendorname1', 'opaqueValue1'); + assert.deepStrictEqual(state.serialize(), 'vendorname1=opaqueValue1'); + + state = state.set('vendorname2', 'opaqueValue2'); + assert.deepStrictEqual( + state.serialize(), + 'vendorname2=opaqueValue2,vendorname1=opaqueValue1' + ); + }); + + it('must create a createTraceState and unset the entries', () => { + const orgState = createTraceState('c=4,b=3,a=1'); + let state = orgState.unset('b'); + assert.deepStrictEqual(state.serialize(), 'c=4,a=1'); + state = state.unset('c').unset('A'); + assert.deepStrictEqual(state.serialize(), 'a=1'); + assert.strictEqual(orgState.serialize(), 'c=4,b=3,a=1'); + }); + }); + + describe('.parse()', () => { + it('must successfully parse valid state value', () => { + const state = createTraceState( + 'vendorname2=opaqueValue2,vendorname1=opaqueValue1' + ); + assert.deepStrictEqual(state.get('vendorname1'), 'opaqueValue1'); + assert.deepStrictEqual(state.get('vendorname2'), 'opaqueValue2'); + assert.deepStrictEqual( + state.serialize(), + 'vendorname2=opaqueValue2,vendorname1=opaqueValue1' + ); + }); + + it('must drop states when the items are too long', () => { + const state = createTraceState('a=' + 'b'.repeat(512)); + assert.deepStrictEqual(state.get('a'), undefined); + assert.deepStrictEqual(state.serialize(), ''); + }); + + it('must drop states which cannot be parsed', () => { + const state = createTraceState('a=1,b,c=3'); + assert.deepStrictEqual(state.get('a'), '1'); + assert.deepStrictEqual(state.get('b'), undefined); + assert.deepStrictEqual(state.get('c'), '3'); + assert.deepStrictEqual(state.serialize(), 'a=1,c=3'); + }); + + it('must skip states that only have a single value with an equal sign', () => { + const state = createTraceState('a=1='); + assert.deepStrictEqual(state.get('a'), undefined); + }); + + it('must successfully parse valid state keys', () => { + const state = createTraceState('a-b=1,c/d=2,p*q=3,x_y=4'); + assert.deepStrictEqual(state.get('a-b'), '1'); + assert.deepStrictEqual(state.get('c/d'), '2'); + assert.deepStrictEqual(state.get('p*q'), '3'); + assert.deepStrictEqual(state.get('x_y'), '4'); + }); + + it('must successfully parse valid state value with spaces in between', () => { + const state = createTraceState('a=1,foo=bar baz'); + assert.deepStrictEqual(state.get('foo'), 'bar baz'); + assert.deepStrictEqual(state.serialize(), 'a=1,foo=bar baz'); + }); + + it('must truncate states with too many items', () => { + const state = createTraceState( + new Array(33) + .fill(0) + .map((_: null, num: number) => `a${num}=${num}`) + .join(',') + ) as TraceStateImpl; + assert.deepStrictEqual(state['_keys']().length, 32); + assert.deepStrictEqual(state.get('a0'), '0'); + assert.deepStrictEqual(state.get('a31'), '31'); + assert.deepStrictEqual( + state.get('a32'), + undefined, + 'should truncate from the tail' + ); + }); + + it('should not count invalid items towards max limit', () => { + const tracestate = new Array(32) + .fill(0) + .map((_: null, num: number) => `a${num}=${num}`) + .concat('invalid.suffix.key=1'); // add invalid key to beginning + tracestate.unshift('invalid.prefix.key=1'); + tracestate.splice(15, 0, 'invalid.middle.key.a=1'); + tracestate.splice(15, 0, 'invalid.middle.key.b=2'); + tracestate.splice(15, 0, 'invalid.middle.key.c=3'); + + const state = createTraceState(tracestate.join(',')) as TraceStateImpl; + + assert.deepStrictEqual(state['_keys']().length, 32); + assert.deepStrictEqual(state.get('a0'), '0'); + assert.deepStrictEqual(state.get('a31'), '31'); + assert.deepStrictEqual(state.get('invalid.middle.key.a'), undefined); + assert.deepStrictEqual(state.get('invalid.middle.key.b'), undefined); + assert.deepStrictEqual(state.get('invalid.middle.key.c'), undefined); + }); + }); +}); diff --git a/api/tsconfig.esm.json b/api/tsconfig.esm.json new file mode 100644 index 0000000000..fd8eb6b378 --- /dev/null +++ b/api/tsconfig.esm.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "ES6", + "moduleResolution": "node", + "outDir": "build/esm", + "rootDir": "src", + "tsBuildInfoFile": "build/esm/tsconfig.esm.tsbuildinfo" + }, + "include": [ + "src/**/*.ts" + ], +} diff --git a/api/tsconfig.json b/api/tsconfig.json new file mode 100644 index 0000000000..f73b707389 --- /dev/null +++ b/api/tsconfig.json @@ -0,0 +1,39 @@ +{ + "compilerOptions": { + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "declaration": true, + "declarationMap": true, + "forceConsistentCasingInFileNames": true, + "module": "commonjs", + "noEmitOnError": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "noImplicitOverride": true, + "outDir": "build", + "pretty": true, + "rootDir": ".", + "sourceMap": true, + "strict": true, + "strictNullChecks": true, + "target": "es5", + "incremental": true, + "newLine": "LF", + "inlineSources": true + }, + "include": [ + "src/**/*.ts", + "test/**/*.ts" + ], + "exclude": [ + "node_modules" + ], + "typedocOptions": { + "name": "OpenTelemetry API for JavaScript", + "out": "docs/out", + "entryPoints": ["./src/index.ts"], + "excludePrivate": true, + "hideGenerator": true + } +} diff --git a/api/webpack.node-polyfills.js b/api/webpack.node-polyfills.js new file mode 100644 index 0000000000..8d50ebd242 --- /dev/null +++ b/api/webpack.node-polyfills.js @@ -0,0 +1,52 @@ +module.exports = { + // Enable the assert library polyfill because that is used in tests + assert: true, + // The assert polyfill from github.com/browserify/commonjs-assert + // also requires the `global` polyfill. + global: true, + + // Turn off all other Node.js API polyfills for the browser tests to + // make sure that we are not attempting to use Node-specific APIs in + // the browser code. Instead, we will write browser specific + // implementations of platform functionality we need under the + // `./src/platform/browser` folder. This allows for writing browser + // optimized implementations of the specific needed functionality + // rather than bringing in (sometimes large) polyfills for the + // corresponding Node APIs. + Buffer: false, + __dirname: false, + __filename: false, + buffer: false, + child_process: false, + cluster: false, + console: false, + constants: false, + crypto: false, + dgram: false, + dns: false, + domain: false, + events: false, + fs: false, + http: false, + https: false, + module: false, + net: false, + os: false, + path: false, + process: false, + punycode: false, + querystring: false, + readline: false, + repl: false, + setImmediate: false, + stream: false, + string_decoder: false, + sys: false, + timers: false, + tls: false, + tty: false, + url: false, + util: false, + vm: false, + zlib: false +}; From 032f68f27dbe3319b07aabb21a71f800ba6a33d4 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 13 Sep 2022 11:02:32 +0200 Subject: [PATCH 19/77] chore(deps): update node.js to v18 (#3204) --- .github/workflows/peer-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/peer-api.yml b/.github/workflows/peer-api.yml index 47daa6f20f..d3239068d5 100644 --- a/.github/workflows/peer-api.yml +++ b/.github/workflows/peer-api.yml @@ -10,7 +10,7 @@ jobs: peer-api-check: runs-on: ubuntu-latest container: - image: node:14 + image: node:18 steps: - name: Checkout uses: actions/checkout@v3 From bd0a77f8babaed2b6980f1355401d8e2914de84e Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Tue, 13 Sep 2022 13:31:21 +0200 Subject: [PATCH 20/77] docs(sdk-metrics): fix typos and add missing parameter docs (#3244) Co-authored-by: Daniel Dyla --- experimental/CHANGELOG.md | 2 ++ .../opentelemetry-sdk-metrics/src/aggregator/types.ts | 1 + .../opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts | 2 +- .../opentelemetry-sdk-metrics/src/export/MetricExporter.ts | 1 + .../opentelemetry-sdk-metrics/src/state/MeterSharedState.ts | 1 + .../src/state/TemporalMetricProcessor.ts | 4 +--- .../packages/opentelemetry-sdk-metrics/src/view/Predicate.ts | 4 ++-- 7 files changed, 9 insertions(+), 6 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 413ffbfe6b..f3d709a045 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -50,6 +50,8 @@ All notable changes to experimental packages in this project will be documented ### :books: (Refine Doc) +* docs(sdk-metrics): fix typos and add missing parameter docs. [#3244](https://github.com/open-telemetry/opentelemetry-js/pull/3244) @pichlermarc + ### :house: (Internal) ## 0.32.0 diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts b/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts index 8f4f2e1acc..20c8f7ec4d 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts @@ -111,6 +111,7 @@ export interface Aggregator { * Returns the {@link MetricData} that this {@link Aggregator} will produce. * * @param descriptor the metric instrument descriptor. + * @param aggregationTemporality the temporality of the resulting {@link MetricData} * @param accumulationByAttributes the array of attributes and accumulation pairs. * @param endTime the end time of the metric data. * @return the {@link MetricData} that this {@link Aggregator} will produce. diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts index 956025f253..ae005b4988 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts @@ -29,7 +29,7 @@ export interface ExemplarFilter { * @param value The value of the measurement * @param timestamp A timestamp that best represents when the measurement was taken * @param attributes The complete set of MetricAttributes of the measurement - * @param context The Context of the measurement + * @param ctx The Context of the measurement */ shouldSample( value: number, diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts index 8e4eb7bd54..1421ddb71f 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts @@ -32,6 +32,7 @@ export interface PushMetricExporter { /** * Called to export sampled {@link ResourceMetrics}. * @param metrics the metric data to be exported. + * @param resultCallback callback for when the export has completed */ export(metrics: ResourceMetrics, resultCallback: (result: ExportResult) => void): void; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts index 4ddc0b8932..65ea6edde7 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts @@ -62,6 +62,7 @@ export class MeterSharedState { /** * @param collector opaque handle of {@link MetricCollector} which initiated the collection. * @param collectionTime the HrTime at which the collection was initiated. + * @param options options for collection. * @returns the list of metric data collected. */ async collect(collector: MetricCollectorHandle, collectionTime: HrTime, options?: MetricCollectOptions): Promise { diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/TemporalMetricProcessor.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/TemporalMetricProcessor.ts index 6c648ac117..7e0000d775 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/TemporalMetricProcessor.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/TemporalMetricProcessor.ts @@ -44,7 +44,7 @@ interface LastReportedHistory> { /** * Internal interface. * - * Provides unique reporting for each collectors. Allows synchronous collection + * Provides unique reporting for each collector. Allows synchronous collection * of metrics and reports given temporality values. */ export class TemporalMetricProcessor> { @@ -57,8 +57,6 @@ export class TemporalMetricProcessor> { * Builds the {@link MetricData} streams to report against a specific MetricCollector. * @param collector The information of the MetricCollector. * @param collectors The registered collectors. - * @param resource The resource to attach these metrics against. - * @param instrumentationScope The instrumentation scope that generated these metrics. * @param instrumentDescriptor The instrumentation descriptor that these metrics generated with. * @param currentAccumulations The current accumulation of metric data from instruments. * @param collectionTime The current collection timestamp. diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/Predicate.ts b/experimental/packages/opentelemetry-sdk-metrics/src/view/Predicate.ts index 605737b379..c12c32bbb2 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/view/Predicate.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/view/Predicate.ts @@ -16,7 +16,7 @@ // https://tc39.es/proposal-regex-escaping // escape ^ $ \ . + ? ( ) [ ] { } | -// do not need to escape * as we are interpret it as wildcard +// do not need to escape * as we interpret it as wildcard const ESCAPE = /[\^$\\.+?()[\]{}|]/g; export interface Predicate { @@ -24,7 +24,7 @@ export interface Predicate { } /** - * Wildcard pattern predicate, support patterns like `*`, `foo*`, `*bar`. + * Wildcard pattern predicate, supports patterns like `*`, `foo*`, `*bar`. */ export class PatternPredicate implements Predicate { private _matchAll: boolean; From fade3c989bd698948deefd0f67707f6d91aa7260 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Tue, 13 Sep 2022 18:25:51 +0200 Subject: [PATCH 21/77] ci(instrumentation-http): improve metrics test stability (#3242) * fix(instrumentation-http): improve metrics test stability * fix(changelog): add changelog entry. * fix(instrumentation-http): clean up test reader. * fix(changlog): move entry to internal * fix(instrumentation-http): fix TestMetricReader --- experimental/CHANGELOG.md | 2 + .../test/functionals/http-metrics.test.ts | 7 +-- .../test/utils/TestMetricReader.ts | 49 +++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 experimental/packages/opentelemetry-instrumentation-http/test/utils/TestMetricReader.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index f3d709a045..0c77075056 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -54,6 +54,8 @@ All notable changes to experimental packages in this project will be documented ### :house: (Internal) +* ci(instrumentation-http): improve metrics test stability [#3242](https://github.com/open-telemetry/opentelemetry-js/pull/3242) @pichlermarc + ## 0.32.0 ### :boom: Breaking Change diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts index 5ab046b45f..3d80bb950d 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts @@ -18,13 +18,13 @@ import { DataPointType, InMemoryMetricExporter, MeterProvider, - PeriodicExportingMetricReader, } from '@opentelemetry/sdk-metrics'; import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; import * as assert from 'assert'; import { HttpInstrumentation } from '../../src/http'; import { httpRequest } from '../utils/httpRequest'; +import { TestMetricReader } from '../utils/TestMetricReader'; const instrumentation = new HttpInstrumentation(); instrumentation.enable(); @@ -40,7 +40,8 @@ const pathname = '/test'; const tracerProvider = new NodeTracerProvider(); const meterProvider = new MeterProvider(); const metricsMemoryExporter = new InMemoryMetricExporter(AggregationTemporality.DELTA); -const metricReader = new PeriodicExportingMetricReader({ exporter: metricsMemoryExporter, exportIntervalMillis: 100 }); +const metricReader = new TestMetricReader(metricsMemoryExporter); + meterProvider.addMetricReader(metricReader); instrumentation.setTracerProvider(tracerProvider); instrumentation.setMeterProvider(meterProvider); @@ -69,7 +70,7 @@ describe('metrics', () => { for (let i = 0; i < requestCount; i++) { await httpRequest.get(`${protocol}://${hostname}:${serverPort}${pathname}`); } - await new Promise(resolve => setTimeout(resolve, 300)); + await metricReader.collectAndExport(); const resourceMetrics = metricsMemoryExporter.getMetrics(); const scopeMetrics = resourceMetrics[0].scopeMetrics; assert.strictEqual(scopeMetrics.length, 1, 'scopeMetrics count'); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/utils/TestMetricReader.ts b/experimental/packages/opentelemetry-instrumentation-http/test/utils/TestMetricReader.ts new file mode 100644 index 0000000000..53ea687d64 --- /dev/null +++ b/experimental/packages/opentelemetry-instrumentation-http/test/utils/TestMetricReader.ts @@ -0,0 +1,49 @@ +/* + * 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 { + MetricReader, + PushMetricExporter +} from '@opentelemetry/sdk-metrics'; + +export class TestMetricReader extends MetricReader { + constructor(private _exporter: PushMetricExporter) { + super({ + aggregationTemporalitySelector: _exporter.selectAggregationTemporality?.bind(_exporter), + }); + } + + protected onForceFlush(): Promise { + return Promise.resolve(undefined); + } + + protected onShutdown(): Promise { + return Promise.resolve(undefined); + } + + public async collectAndExport(): Promise { + const result = await this.collect(); + await new Promise((resolve, reject) => { + this._exporter.export(result.resourceMetrics, result => { + if (result.error != null) { + reject(result.error); + } else { + resolve(); + } + }); + }); + } +} From 9c102b765d8690bd799f00453ad674743fe49a85 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Wed, 14 Sep 2022 14:16:13 +0200 Subject: [PATCH 22/77] deps: update markdownlint-cli to 0.32.2 (#3253) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7633d06998..c5672be715 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ All notable changes to this project will be documented in this file. ### :house: (Internal) +* deps: update markdownlint-cli to 0.32.2 [#3253](https://github.com/open-telemetry/opentelemetry-js/pull/3253) @pichlermarc + ## 1.6.0 ### :rocket: (Enhancement) diff --git a/package.json b/package.json index 3488c1e1e8..a83a8c46a5 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "lerna": "5.4.3", "lerna-changelog": "2.2.0", "linkinator": "4.0.3", - "markdownlint-cli": "0.29.0", + "markdownlint-cli": "0.32.2", "semver": "7.3.5", "typedoc": "0.22.10", "typescript": "4.4.4", From ec56837f22523caac4a69f79011c09a6de088cb6 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Wed, 14 Sep 2022 17:21:38 +0200 Subject: [PATCH 23/77] chore: fix markdownlint issues (#3252) Co-authored-by: Daniel Dyla --- README.md | 3 +-- doc/web-api.md | 2 +- examples/basic-tracer-node/README.md | 2 -- experimental/packages/api-logs/README.md | 5 +---- experimental/packages/otlp-exporter-base/README.md | 3 --- experimental/packages/otlp-grpc-exporter-base/README.md | 2 -- experimental/packages/otlp-proto-exporter-base/README.md | 2 -- packages/opentelemetry-context-async-hooks/README.md | 2 +- 8 files changed, 4 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f52b0a4ad2..f3efd881f3 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ If you are a library author looking to build OpenTelemetry into your library, pl ### Node Support Only Node.js Active or Maintenance LTS versions are supported. -Previous versions of node _may_ work, but they are not tested by OpenTelemetry and they are not guaranteed to work. +Previous versions of node *may* work, but they are not tested by OpenTelemetry and they are not guaranteed to work. Please note that versions of Node.JS v8 prior to `v8.12.0` will NOT work, because OpenTelemetry Node depends on the `perf_hooks` module introduced in `v8.5.0` and `performance.timeOrigin` that is set correctly starting in `v8.12.0`. ### Browser Support @@ -556,6 +556,5 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [otel-api]: https://github.com/open-telemetry/opentelemetry-js-api [otel-core]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-core [otel-propagator-b3]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-b3 -[generate-api-documentation]: https://github.com/open-telemetry/opentelemetry-js/blob/main/CONTRIBUTING.md#generating-api-documentation [spec-versioning]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md diff --git a/doc/web-api.md b/doc/web-api.md index 8d916e5847..2c3df6d65d 100644 --- a/doc/web-api.md +++ b/doc/web-api.md @@ -18,4 +18,4 @@ browsing context only. [`window`]: https://developer.mozilla.org/en-US/docs/Web/API/window [`document`]: https://developer.mozilla.org/en-US/docs/Web/API/Document -[`navigator]: https://developer.mozilla.org/en-US/docs/Web/API/Navigator +[`navigator`]: https://developer.mozilla.org/en-US/docs/Web/API/Navigator diff --git a/examples/basic-tracer-node/README.md b/examples/basic-tracer-node/README.md index 6db3fc7834..d7da08813f 100644 --- a/examples/basic-tracer-node/README.md +++ b/examples/basic-tracer-node/README.md @@ -40,5 +40,3 @@ Click on the trace to view its details. ## LICENSE Apache License 2.0 - -[opentelemetry-collector-url]: https://github.com/open-telemetry/opentelemetry-exporter-otlp-http diff --git a/experimental/packages/api-logs/README.md b/experimental/packages/api-logs/README.md index d940cfc0cc..b0704800de 100644 --- a/experimental/packages/api-logs/README.md +++ b/experimental/packages/api-logs/README.md @@ -60,7 +60,4 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat [npm-url]: https://www.npmjs.com/package/@opentelemetry/api-metrics [npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi-metrics.svg - -[metrics-api-docs]: https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api_metrics.html - -[other-tracing-backends]: https://github.com/open-telemetry/opentelemetry-js#trace-exporters +[logs-api-docs]: https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api_logs.html diff --git a/experimental/packages/otlp-exporter-base/README.md b/experimental/packages/otlp-exporter-base/README.md index f44387c402..85f96aecd8 100644 --- a/experimental/packages/otlp-exporter-base/README.md +++ b/experimental/packages/otlp-exporter-base/README.md @@ -39,6 +39,3 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [npm-url-proto]: https://www.npmjs.com/package/@opentelemetry/otlp-proto-exporter-base [npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fotlp-exporter-base.svg [opentelemetry-collector-url]: https://github.com/open-telemetry/opentelemetry-collector -[opentelemetry-spec-protocol-exporter]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options -[semconv-resource-service-name]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md#service -[metrics-exporter-url]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-http diff --git a/experimental/packages/otlp-grpc-exporter-base/README.md b/experimental/packages/otlp-grpc-exporter-base/README.md index ec6f495b9a..d49ece2a36 100644 --- a/experimental/packages/otlp-grpc-exporter-base/README.md +++ b/experimental/packages/otlp-grpc-exporter-base/README.md @@ -29,5 +29,3 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [npm-url]: https://www.npmjs.com/package/@opentelemetry/otlp-grpc-exporter-base [npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fotlp-grpc-exporter-base.svg [opentelemetry-collector-url]: https://github.com/open-telemetry/opentelemetry-collector -[semconv-resource-service-name]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md#service -[metrics-exporter-url]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc diff --git a/experimental/packages/otlp-proto-exporter-base/README.md b/experimental/packages/otlp-proto-exporter-base/README.md index ed9f0d679b..84cd880dcd 100644 --- a/experimental/packages/otlp-proto-exporter-base/README.md +++ b/experimental/packages/otlp-proto-exporter-base/README.md @@ -29,5 +29,3 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [npm-url]: https://www.npmjs.com/package/@opentelemetry/otlp-proto-exporter-base [npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fotlp-proto-exporter-base.svg [opentelemetry-collector-url]: https://github.com/open-telemetry/opentelemetry-collector -[semconv-resource-service-name]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md#service -[metrics-exporter-url]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-proto diff --git a/packages/opentelemetry-context-async-hooks/README.md b/packages/opentelemetry-context-async-hooks/README.md index 553156d7c7..3c2e674ad1 100644 --- a/packages/opentelemetry-context-async-hooks/README.md +++ b/packages/opentelemetry-context-async-hooks/README.md @@ -5,7 +5,7 @@ This package provides two [`ContextManager`](https://open-telemetry.github.io/opentelemetry-js-api/interfaces/contextmanager.html) implementations built on APIs from Node.js's [`async_hooks`][async-hooks-doc] module. If you're looking for a `ContextManager` to use in browser environments, consider [opentelemetry-context-zone](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-context-zone) or [opentelemetry-context-zone-peer-dep](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-context-zone-peer-dep). -The definition of the `ContextManager` interface and the problem it solves can be found [here](def-context-manager). +The definition of the `ContextManager` interface and the problem it solves can be found [here][def-context-manager]. ## API From 4422d8ce210c684ff341ec574259e50e10ec2bbc Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Thu, 15 Sep 2022 05:32:03 +0200 Subject: [PATCH 24/77] deps: remove unused protobufjs and update used ones to 7.1.1 (#3251) * deps: remove unused protobufjs and update used ones to 7.1.1 * fix(changelog): add chanelog entry. Co-authored-by: Daniel Dyla --- experimental/CHANGELOG.md | 1 + experimental/packages/exporter-trace-otlp-proto/package.json | 3 +-- .../opentelemetry-exporter-metrics-otlp-proto/package.json | 3 +-- experimental/packages/otlp-proto-exporter-base/package.json | 5 +++-- experimental/packages/otlp-transformer/package.json | 1 - 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 0c77075056..171f3812f6 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -55,6 +55,7 @@ All notable changes to experimental packages in this project will be documented ### :house: (Internal) * ci(instrumentation-http): improve metrics test stability [#3242](https://github.com/open-telemetry/opentelemetry-js/pull/3242) @pichlermarc +* deps: remove unused protobufjs and update used ones to 7.1.1 #3251 [#3251](https://github.com/open-telemetry/opentelemetry-js/pull/3251) @pichlermarc ## 0.32.0 diff --git a/experimental/packages/exporter-trace-otlp-proto/package.json b/experimental/packages/exporter-trace-otlp-proto/package.json index 41aff440c7..4a1d2974dd 100644 --- a/experimental/packages/exporter-trace-otlp-proto/package.json +++ b/experimental/packages/exporter-trace-otlp-proto/package.json @@ -72,8 +72,7 @@ "@opentelemetry/otlp-proto-exporter-base": "0.32.0", "@opentelemetry/otlp-transformer": "0.32.0", "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "protobufjs": "^6.9.0" + "@opentelemetry/sdk-trace-base": "1.6.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-proto" } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json index 9723a58a55..d9e62b66e5 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json @@ -74,8 +74,7 @@ "@opentelemetry/otlp-proto-exporter-base": "0.32.0", "@opentelemetry/otlp-transformer": "0.32.0", "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-metrics": "0.32.0", - "protobufjs": "^6.9.0" + "@opentelemetry/sdk-metrics": "0.32.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-proto" } diff --git a/experimental/packages/otlp-proto-exporter-base/package.json b/experimental/packages/otlp-proto-exporter-base/package.json index a9ae89dcec..4c0ff243c6 100644 --- a/experimental/packages/otlp-proto-exporter-base/package.json +++ b/experimental/packages/otlp-proto-exporter-base/package.json @@ -52,7 +52,7 @@ "codecov": "3.8.3", "mocha": "10.0.0", "nyc": "15.1.0", - "protobufjs": "6.11.3", + "protobufjs-cli": "^1.0.2", "rimraf": "3.0.2", "sinon": "14.0.0", "ts-loader": "8.4.0", @@ -65,7 +65,8 @@ "dependencies": { "@grpc/proto-loader": "^0.6.9", "@opentelemetry/core": "1.6.0", - "@opentelemetry/otlp-exporter-base": "0.32.0" + "@opentelemetry/otlp-exporter-base": "0.32.0", + "protobufjs": "7.1.1" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-proto-exporter-base" } diff --git a/experimental/packages/otlp-transformer/package.json b/experimental/packages/otlp-transformer/package.json index b15be78d13..8bcd3949d5 100644 --- a/experimental/packages/otlp-transformer/package.json +++ b/experimental/packages/otlp-transformer/package.json @@ -69,7 +69,6 @@ "mkdirp": "1.0.4", "mocha": "10.0.0", "nyc": "15.1.0", - "protobufjs": "6.11.3", "rimraf": "3.0.2", "ts-loader": "8.4.0", "ts-mocha": "10.0.0", From ad88c3d9aa0100fe259b93f4b660e84417b757ac Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 16 Sep 2022 07:55:46 -0400 Subject: [PATCH 25/77] chore: proposal 1.7.0/0.33.0 (#3259) --- CHANGELOG.md | 10 +++++-- README.md | 1 + examples/https/package.json | 18 +++++------ examples/opentelemetry-web/package.json | 30 +++++++++---------- examples/otlp-exporter-node/package.json | 26 ++++++++-------- experimental/CHANGELOG.md | 14 +++++++-- .../node14/package.json | 6 ++-- .../node16/package.json | 6 ++-- experimental/packages/api-logs/package.json | 2 +- .../exporter-trace-otlp-grpc/package.json | 14 ++++----- .../exporter-trace-otlp-http/package.json | 12 ++++---- .../exporter-trace-otlp-proto/package.json | 14 ++++----- .../opentelemetry-api-metrics/package.json | 2 +- .../package.json | 16 +++++----- .../package.json | 14 ++++----- .../package.json | 18 +++++------ .../package.json | 8 ++--- .../package.json | 16 +++++----- .../package.json | 16 +++++----- .../package.json | 18 +++++------ .../package.json | 16 +++++----- .../package.json | 4 +-- .../opentelemetry-sdk-metrics/package.json | 8 ++--- .../opentelemetry-sdk-node/package.json | 20 ++++++------- .../packages/otlp-exporter-base/package.json | 4 +-- .../otlp-grpc-exporter-base/package.json | 12 ++++---- .../otlp-proto-exporter-base/package.json | 6 ++-- .../packages/otlp-transformer/package.json | 12 ++++---- .../package.json | 8 ++--- .../package.json | 2 +- .../package.json | 2 +- .../opentelemetry-context-zone/package.json | 4 +-- packages/opentelemetry-core/package.json | 4 +-- .../package.json | 10 +++---- .../package.json | 10 +++---- .../opentelemetry-propagator-b3/package.json | 4 +-- .../package.json | 4 +-- packages/opentelemetry-resources/package.json | 6 ++-- .../opentelemetry-sdk-trace-base/package.json | 8 ++--- .../opentelemetry-sdk-trace-node/package.json | 16 +++++----- .../opentelemetry-sdk-trace-web/package.json | 14 ++++----- .../package.json | 2 +- .../package.json | 12 ++++---- packages/template/package.json | 2 +- selenium-tests/package.json | 22 +++++++------- 45 files changed, 245 insertions(+), 228 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5672be715..7f7b5db2f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,14 @@ All notable changes to this project will be documented in this file. ### :bug: (Bug Fix) +### :books: (Refine Doc) + +### :house: (Internal) + +## 1.7.0 + +### :bug: (Bug Fix) + * fix(sdk-trace-base): make span start times resistant to hrtime clock drift [#3129](https://github.com/open-telemetry/opentelemetry-js/issues/3129) @@ -40,8 +48,6 @@ All notable changes to this project will be documented in this file. * chore: update trace-web example and rename it to opentelemetry-web [#3145](https://github.com/open-telemetry/opentelemetry-js/pull/3145) @pichlermarc * chore: update https example [#3152](https://github.com/open-telemetry/opentelemetry-js/pull/3152) @pichlermarc -### :house: (Internal) - ## 1.5.0 ### :rocket: (Enhancement) diff --git a/README.md b/README.md index f3efd881f3..d0d7dd65eb 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ This is the JavaScript version of [OpenTelemetry](https://opentelemetry.io/), a | API Version | Core version | Experimental Packages | | ----------- | ------------ | --------------------- | +| 1.2.x | 1.7.x | 0.33.x | | 1.2.x | 1.6.x | 0.32.x | | 1.1.x | 1.5.x | 0.31.x | | 1.1.x | 1.4.x | 0.30.x | diff --git a/examples/https/package.json b/examples/https/package.json index c6eee81462..e9dcc45177 100644 --- a/examples/https/package.json +++ b/examples/https/package.json @@ -1,7 +1,7 @@ { "name": "https-example", "private": true, - "version": "0.32.0", + "version": "0.33.0", "description": "Example of HTTPs integration with OpenTelemetry", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -33,14 +33,14 @@ }, "dependencies": { "@opentelemetry/api": "^1.0.0", - "@opentelemetry/exporter-jaeger": "1.6.0", - "@opentelemetry/exporter-zipkin": "1.6.0", - "@opentelemetry/instrumentation": "0.32.0", - "@opentelemetry/instrumentation-http": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/sdk-trace-node": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/exporter-jaeger": "1.7.0", + "@opentelemetry/exporter-zipkin": "1.7.0", + "@opentelemetry/instrumentation": "0.33.0", + "@opentelemetry/instrumentation-http": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/sdk-trace-node": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/https", "devDependencies": { diff --git a/examples/opentelemetry-web/package.json b/examples/opentelemetry-web/package.json index f1159103b5..f99b49e3f7 100644 --- a/examples/opentelemetry-web/package.json +++ b/examples/opentelemetry-web/package.json @@ -1,7 +1,7 @@ { "name": "web-opentelemetry-example", "private": true, - "version": "0.32.0", + "version": "0.33.0", "description": "Example of using @opentelemetry/sdk-trace-web and @opentelemetry/sdk-metrics in browser", "main": "index.js", "scripts": { @@ -43,20 +43,20 @@ }, "dependencies": { "@opentelemetry/api": "^1.0.2", - "@opentelemetry/api-metrics": "0.32.0", - "@opentelemetry/context-zone": "1.6.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/exporter-metrics-otlp-http": "0.32.0", - "@opentelemetry/exporter-trace-otlp-http": "0.32.0", - "@opentelemetry/exporter-zipkin": "1.6.0", - "@opentelemetry/instrumentation": "0.32.0", - "@opentelemetry/instrumentation-fetch": "0.32.0", - "@opentelemetry/instrumentation-xml-http-request": "0.32.0", - "@opentelemetry/propagator-b3": "1.6.0", - "@opentelemetry/sdk-metrics": "0.32.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/sdk-trace-web": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/context-zone": "1.7.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", + "@opentelemetry/exporter-trace-otlp-http": "0.33.0", + "@opentelemetry/exporter-zipkin": "1.7.0", + "@opentelemetry/instrumentation": "0.33.0", + "@opentelemetry/instrumentation-fetch": "0.33.0", + "@opentelemetry/instrumentation-xml-http-request": "0.33.0", + "@opentelemetry/propagator-b3": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/sdk-trace-web": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/tracer-web" } diff --git a/examples/otlp-exporter-node/package.json b/examples/otlp-exporter-node/package.json index 21b27440d4..085d15917d 100644 --- a/examples/otlp-exporter-node/package.json +++ b/examples/otlp-exporter-node/package.json @@ -1,7 +1,7 @@ { "name": "example-otlp-exporter-node", "private": true, - "version": "0.32.0", + "version": "0.33.0", "description": "Example of using @opentelemetry/collector-exporter in Node.js", "main": "index.js", "scripts": { @@ -29,18 +29,18 @@ }, "dependencies": { "@opentelemetry/api": "^1.1.0", - "@opentelemetry/api-metrics": "0.32.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/exporter-metrics-otlp-grpc": "0.32.0", - "@opentelemetry/exporter-metrics-otlp-http": "0.32.0", - "@opentelemetry/exporter-metrics-otlp-proto": "0.32.0", - "@opentelemetry/exporter-trace-otlp-grpc": "0.32.0", - "@opentelemetry/exporter-trace-otlp-http": "0.32.0", - "@opentelemetry/exporter-trace-otlp-proto": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-metrics": "0.32.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.33.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.33.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/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/otlp-exporter-node" } diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 171f3812f6..d62009288d 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -6,6 +6,18 @@ All notable changes to experimental packages in this project will be documented ### :boom: Breaking Change +### :rocket: (Enhancement) + +### :bug: (Bug Fix) + +### :books: (Refine Doc) + +### :house: (Internal) + +## 0.33.0 + +### :boom: Breaking Change + * Add `resourceDetectors` option to `NodeSDK` [#3210](https://github.com/open-telemetry/opentelemetry-js/issues/3210) * `NodeSDK.detectResources()` function is no longer able to receive config as a parameter. Instead, the detectors are passed to the constructor. @@ -46,8 +58,6 @@ All notable changes to experimental packages in this project will be documented * Add `resourceDetectors` option to `NodeSDK` [#3210](https://github.com/open-telemetry/opentelemetry-js/issues/3210) * feat: add Logs API @mkuba [#3117](https://github.com/open-telemetry/opentelemetry-js/pull/3117) -### :bug: (Bug Fix) - ### :books: (Refine Doc) * docs(sdk-metrics): fix typos and add missing parameter docs. [#3244](https://github.com/open-telemetry/opentelemetry-js/pull/3244) @pichlermarc diff --git a/experimental/backwards-compatability/node14/package.json b/experimental/backwards-compatability/node14/package.json index a9db91d167..30cc1e1f5d 100644 --- a/experimental/backwards-compatability/node14/package.json +++ b/experimental/backwards-compatability/node14/package.json @@ -1,6 +1,6 @@ { "name": "backcompat-node14", - "version": "0.32.0", + "version": "0.33.0", "private": true, "description": "Backwards compatability app for node 14 types and the OpenTelemetry Node.js SDK", "main": "index.js", @@ -9,8 +9,8 @@ "peer-api-check": "node ../../../scripts/peer-api-check.js" }, "dependencies": { - "@opentelemetry/sdk-node": "0.32.0", - "@opentelemetry/sdk-trace-base": "1.6.0" + "@opentelemetry/sdk-node": "0.33.0", + "@opentelemetry/sdk-trace-base": "1.7.0" }, "devDependencies": { "@types/node": "14.18.25", diff --git a/experimental/backwards-compatability/node16/package.json b/experimental/backwards-compatability/node16/package.json index f1ea4b4f77..f130915560 100644 --- a/experimental/backwards-compatability/node16/package.json +++ b/experimental/backwards-compatability/node16/package.json @@ -1,6 +1,6 @@ { "name": "backcompat-node16", - "version": "0.32.0", + "version": "0.33.0", "private": true, "description": "Backwards compatability app for node 16 types and the OpenTelemetry Node.js SDK", "main": "index.js", @@ -9,8 +9,8 @@ "peer-api-check": "node ../../../scripts/peer-api-check.js" }, "dependencies": { - "@opentelemetry/sdk-node": "0.32.0", - "@opentelemetry/sdk-trace-base": "1.6.0" + "@opentelemetry/sdk-node": "0.33.0", + "@opentelemetry/sdk-trace-base": "1.7.0" }, "devDependencies": { "@types/node": "16.11.52", diff --git a/experimental/packages/api-logs/package.json b/experimental/packages/api-logs/package.json index 91a2ac61f0..25dc650922 100644 --- a/experimental/packages/api-logs/package.json +++ b/experimental/packages/api-logs/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/api-logs", - "version": "0.32.0", + "version": "0.33.0", "description": "Public logs API for OpenTelemetry", "main": "build/src/index.js", "module": "build/esm/index.js", diff --git a/experimental/packages/exporter-trace-otlp-grpc/package.json b/experimental/packages/exporter-trace-otlp-grpc/package.json index 7402f23557..a4b177ebb0 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/package.json +++ b/experimental/packages/exporter-trace-otlp-grpc/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-trace-otlp-grpc", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry Collector Exporter allows user to send collected traces to the OpenTelemetry Collector", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -49,7 +49,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/otlp-exporter-base": "0.32.0", + "@opentelemetry/otlp-exporter-base": "0.33.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -69,11 +69,11 @@ "dependencies": { "@grpc/grpc-js": "^1.5.9", "@grpc/proto-loader": "^0.6.9", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/otlp-grpc-exporter-base": "0.32.0", - "@opentelemetry/otlp-transformer": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-grpc" } diff --git a/experimental/packages/exporter-trace-otlp-http/package.json b/experimental/packages/exporter-trace-otlp-http/package.json index 990f56cd42..4abc90ed7a 100644 --- a/experimental/packages/exporter-trace-otlp-http/package.json +++ b/experimental/packages/exporter-trace-otlp-http/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-trace-otlp-http", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry Collector Trace Exporter allows user to send collected traces to the OpenTelemetry Collector", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -94,11 +94,11 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0", - "@opentelemetry/otlp-exporter-base": "0.32.0", - "@opentelemetry/otlp-transformer": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/otlp-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-http" } diff --git a/experimental/packages/exporter-trace-otlp-proto/package.json b/experimental/packages/exporter-trace-otlp-proto/package.json index 4a1d2974dd..271246ad00 100644 --- a/experimental/packages/exporter-trace-otlp-proto/package.json +++ b/experimental/packages/exporter-trace-otlp-proto/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-trace-otlp-proto", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry Collector Exporter allows user to send collected traces to the OpenTelemetry Collector using protobuf over HTTP", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -67,12 +67,12 @@ }, "dependencies": { "@grpc/proto-loader": "^0.6.9", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/otlp-exporter-base": "0.32.0", - "@opentelemetry/otlp-proto-exporter-base": "0.32.0", - "@opentelemetry/otlp-transformer": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/otlp-exporter-base": "0.33.0", + "@opentelemetry/otlp-proto-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-proto" } diff --git a/experimental/packages/opentelemetry-api-metrics/package.json b/experimental/packages/opentelemetry-api-metrics/package.json index a901850ee7..3118cdb019 100644 --- a/experimental/packages/opentelemetry-api-metrics/package.json +++ b/experimental/packages/opentelemetry-api-metrics/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/api-metrics", - "version": "0.32.0", + "version": "0.33.0", "description": "Public metrics API for OpenTelemetry", "main": "build/src/index.js", "module": "build/esm/index.js", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json index 362fdae821..40d8fb7a35 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-metrics-otlp-grpc", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry Collector Metrics Exporter allows user to send collected metrics to the OpenTelemetry Collector", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -49,7 +49,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/api-metrics": "0.32.0", + "@opentelemetry/api-metrics": "0.33.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -69,12 +69,12 @@ "dependencies": { "@grpc/grpc-js": "^1.5.9", "@grpc/proto-loader": "^0.6.9", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/exporter-metrics-otlp-http": "0.32.0", - "@opentelemetry/otlp-grpc-exporter-base": "0.32.0", - "@opentelemetry/otlp-transformer": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-metrics": "0.32.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc" } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json index 91a50f0125..245bc38e36 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-metrics-otlp-http", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry Collector Metrics Exporter allows user to send collected metrics to the OpenTelemetry Collector", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -94,12 +94,12 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.32.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/otlp-exporter-base": "0.32.0", - "@opentelemetry/otlp-transformer": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-metrics": "0.32.0" + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/otlp-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-http" } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json index d9e62b66e5..60f678472d 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-metrics-otlp-proto", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry Collector Metrics Exporter allows user to send collected metrics to the OpenTelemetry Collector using protobuf over HTTP", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -49,7 +49,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/api-metrics": "0.32.0", + "@opentelemetry/api-metrics": "0.33.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -68,13 +68,13 @@ }, "dependencies": { "@grpc/proto-loader": "0.6.9", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/exporter-metrics-otlp-http": "0.32.0", - "@opentelemetry/otlp-exporter-base": "0.32.0", - "@opentelemetry/otlp-proto-exporter-base": "0.32.0", - "@opentelemetry/otlp-transformer": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-metrics": "0.32.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", + "@opentelemetry/otlp-exporter-base": "0.33.0", + "@opentelemetry/otlp-proto-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-proto" } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/package.json b/experimental/packages/opentelemetry-exporter-prometheus/package.json index 69e9dc9694..0067320ed4 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/package.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-prometheus", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry Exporter Prometheus provides a metrics endpoint for Prometheus", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -59,9 +59,9 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.32.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/sdk-metrics": "0.32.0" + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-prometheus" } diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/package.json b/experimental/packages/opentelemetry-instrumentation-fetch/package.json index d7e22f7f07..d9448b1e6e 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/package.json +++ b/experimental/packages/opentelemetry-instrumentation-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-fetch", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry fetch automatic instrumentation package.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -56,9 +56,9 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/context-zone": "1.6.0", - "@opentelemetry/propagator-b3": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", + "@opentelemetry/context-zone": "1.7.0", + "@opentelemetry/propagator-b3": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -87,10 +87,10 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0", - "@opentelemetry/instrumentation": "0.32.0", - "@opentelemetry/sdk-trace-web": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/instrumentation": "0.33.0", + "@opentelemetry/sdk-trace-web": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-fetch" } diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/package.json b/experimental/packages/opentelemetry-instrumentation-grpc/package.json index 31675724b9..e2bcb44f1f 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/package.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-grpc", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry grpc automatic instrumentation package.", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -48,10 +48,10 @@ "@grpc/grpc-js": "1.5.9", "@grpc/proto-loader": "0.6.9", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/context-async-hooks": "1.6.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/sdk-trace-node": "1.6.0", + "@opentelemetry/context-async-hooks": "1.7.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/sdk-trace-node": "1.7.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/semver": "7.3.9", @@ -71,9 +71,9 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.32.0", - "@opentelemetry/instrumentation": "0.32.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/instrumentation": "0.33.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-grpc" } diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index 754414cf9f..f5aed8faea 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-http", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry http/https automatic instrumentation package.", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -46,9 +46,9 @@ }, "devDependencies": { "@opentelemetry/api": "^1.0.0", - "@opentelemetry/context-async-hooks": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/sdk-trace-node": "1.6.0", + "@opentelemetry/context-async-hooks": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/sdk-trace-node": "1.7.0", "@types/got": "9.6.12", "@types/mocha": "9.1.1", "@types/node": "18.6.5", @@ -74,11 +74,11 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.32.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/instrumentation": "0.32.0", - "@opentelemetry/sdk-metrics": "0.32.0", - "@opentelemetry/semantic-conventions": "1.6.0", + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/instrumentation": "0.33.0", + "@opentelemetry/sdk-metrics": "0.33.0", + "@opentelemetry/semantic-conventions": "1.7.0", "semver": "^7.3.5" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http" diff --git a/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json b/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json index 78b43fda9e..fa029f09f2 100644 --- a/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json +++ b/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-xml-http-request", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry XMLHttpRequest automatic instrumentation package.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -56,9 +56,9 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/context-zone": "1.6.0", - "@opentelemetry/propagator-b3": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", + "@opentelemetry/context-zone": "1.7.0", + "@opentelemetry/propagator-b3": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -87,10 +87,10 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0", - "@opentelemetry/instrumentation": "0.32.0", - "@opentelemetry/sdk-trace-web": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/instrumentation": "0.33.0", + "@opentelemetry/sdk-trace-web": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-xml-http-request" } diff --git a/experimental/packages/opentelemetry-instrumentation/package.json b/experimental/packages/opentelemetry-instrumentation/package.json index 6fc1409a1f..e3ead29861 100644 --- a/experimental/packages/opentelemetry-instrumentation/package.json +++ b/experimental/packages/opentelemetry-instrumentation/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation", - "version": "0.32.0", + "version": "0.33.0", "description": "Base class for node which OpenTelemetry instrumentation modules extend", "author": "OpenTelemetry Authors", "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation", @@ -68,7 +68,7 @@ "url": "https://github.com/open-telemetry/opentelemetry-js/issues" }, "dependencies": { - "@opentelemetry/api-metrics": "0.32.0", + "@opentelemetry/api-metrics": "0.33.0", "require-in-the-middle": "^5.0.3", "semver": "^7.3.2", "shimmer": "^1.2.1" diff --git a/experimental/packages/opentelemetry-sdk-metrics/package.json b/experimental/packages/opentelemetry-sdk-metrics/package.json index 3d8cbb9a23..6931480a4f 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/package.json +++ b/experimental/packages/opentelemetry-sdk-metrics/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-metrics", - "version": "0.32.0", + "version": "0.33.0", "description": "Work in progress OpenTelemetry metrics SDK", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -77,9 +77,9 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.32.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/resources": "1.6.0", + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/resources": "1.7.0", "lodash.merge": "4.6.2" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-metrics" diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index 584183a5dd..8bc140b685 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-node", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry SDK for Node.js", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -44,21 +44,21 @@ "access": "public" }, "dependencies": { - "@opentelemetry/api-metrics": "0.32.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/instrumentation": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-metrics": "0.32.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/sdk-trace-node": "1.6.0" + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/instrumentation": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/sdk-trace-node": "1.7.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0" }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@opentelemetry/context-async-hooks": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0", + "@opentelemetry/context-async-hooks": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/semver": "7.3.9", diff --git a/experimental/packages/otlp-exporter-base/package.json b/experimental/packages/otlp-exporter-base/package.json index 3cc6e7e75e..63c86f9d33 100644 --- a/experimental/packages/otlp-exporter-base/package.json +++ b/experimental/packages/otlp-exporter-base/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/otlp-exporter-base", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry OTLP Exporter base (for internal use only)", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -61,7 +61,7 @@ "access": "public" }, "dependencies": { - "@opentelemetry/core": "1.6.0" + "@opentelemetry/core": "1.7.0" }, "devDependencies": { "@opentelemetry/api": "^1.0.0", diff --git a/experimental/packages/otlp-grpc-exporter-base/package.json b/experimental/packages/otlp-grpc-exporter-base/package.json index 12ede6c932..3f73103f33 100644 --- a/experimental/packages/otlp-grpc-exporter-base/package.json +++ b/experimental/packages/otlp-grpc-exporter-base/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/otlp-grpc-exporter-base", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry OTLP-gRPC Exporter base (for internal use only)", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -51,9 +51,9 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/otlp-transformer": "0.32.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -73,8 +73,8 @@ "dependencies": { "@grpc/grpc-js": "^1.5.9", "@grpc/proto-loader": "^0.6.9", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/otlp-exporter-base": "0.32.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/otlp-exporter-base": "0.33.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-grpc-exporter-base" } diff --git a/experimental/packages/otlp-proto-exporter-base/package.json b/experimental/packages/otlp-proto-exporter-base/package.json index 4c0ff243c6..4ea4a0085c 100644 --- a/experimental/packages/otlp-proto-exporter-base/package.json +++ b/experimental/packages/otlp-proto-exporter-base/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/otlp-proto-exporter-base", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry OTLP-HTTP-protobuf Exporter base (for internal use only)", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -64,8 +64,8 @@ }, "dependencies": { "@grpc/proto-loader": "^0.6.9", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/otlp-exporter-base": "0.32.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/otlp-exporter-base": "0.33.0", "protobufjs": "7.1.1" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-proto-exporter-base" diff --git a/experimental/packages/otlp-transformer/package.json b/experimental/packages/otlp-transformer/package.json index 8bcd3949d5..f91adbb1c2 100644 --- a/experimental/packages/otlp-transformer/package.json +++ b/experimental/packages/otlp-transformer/package.json @@ -4,7 +4,7 @@ "publishConfig": { "access": "public" }, - "version": "0.32.0", + "version": "0.33.0", "description": "Transform OpenTelemetry SDK data into OTLP", "module": "build/esm/index.js", "esnext": "build/esnext/index.js", @@ -76,11 +76,11 @@ "webpack": "4.46.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.32.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-metrics": "0.32.0", - "@opentelemetry/sdk-trace-base": "1.6.0" + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0", + "@opentelemetry/sdk-trace-base": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-transformer" } diff --git a/integration-tests/propagation-validation-server/package.json b/integration-tests/propagation-validation-server/package.json index d937b351af..ef4919d2d4 100644 --- a/integration-tests/propagation-validation-server/package.json +++ b/integration-tests/propagation-validation-server/package.json @@ -1,6 +1,6 @@ { "name": "propagation-validation-server", - "version": "1.6.0", + "version": "1.7.0", "description": "server for w3c tests", "main": "validation_server.js", "private": true, @@ -12,9 +12,9 @@ }, "dependencies": { "@opentelemetry/api": "^1.0.0", - "@opentelemetry/context-async-hooks": "1.6.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", + "@opentelemetry/context-async-hooks": "1.7.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", "axios": "0.24.0", "body-parser": "1.19.0", "express": "4.17.1" diff --git a/packages/opentelemetry-context-async-hooks/package.json b/packages/opentelemetry-context-async-hooks/package.json index cc06b47ca7..7ab2edb96b 100644 --- a/packages/opentelemetry-context-async-hooks/package.json +++ b/packages/opentelemetry-context-async-hooks/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/context-async-hooks", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry AsyncHooks-based Context Manager", "main": "build/src/index.js", "types": "build/src/index.d.ts", diff --git a/packages/opentelemetry-context-zone-peer-dep/package.json b/packages/opentelemetry-context-zone-peer-dep/package.json index e2fd07fe4b..c69038e0de 100644 --- a/packages/opentelemetry-context-zone-peer-dep/package.json +++ b/packages/opentelemetry-context-zone-peer-dep/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/context-zone-peer-dep", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry Context Zone with peer dependency for zone.js", "main": "build/src/index.js", "module": "build/esm/index.js", diff --git a/packages/opentelemetry-context-zone/package.json b/packages/opentelemetry-context-zone/package.json index d9d38cd4e5..d8eec0d82b 100644 --- a/packages/opentelemetry-context-zone/package.json +++ b/packages/opentelemetry-context-zone/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/context-zone", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry Context Zone", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -74,7 +74,7 @@ "webpack-merge": "5.8.0" }, "dependencies": { - "@opentelemetry/context-zone-peer-dep": "1.6.0", + "@opentelemetry/context-zone-peer-dep": "1.7.0", "zone.js": "^0.11.0" }, "sideEffects": true, diff --git a/packages/opentelemetry-core/package.json b/packages/opentelemetry-core/package.json index a5fab5ea21..0232d62469 100644 --- a/packages/opentelemetry-core/package.json +++ b/packages/opentelemetry-core/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/core", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry Core provides constants and utilities shared by all OpenTelemetry SDK packages.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -91,7 +91,7 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0" }, "dependencies": { - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-core" } diff --git a/packages/opentelemetry-exporter-jaeger/package.json b/packages/opentelemetry-exporter-jaeger/package.json index 15064eba8f..d16251d86c 100644 --- a/packages/opentelemetry-exporter-jaeger/package.json +++ b/packages/opentelemetry-exporter-jaeger/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-jaeger", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry Exporter Jaeger allows user to send collected traces to Jaeger", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -45,7 +45,7 @@ }, "devDependencies": { "@opentelemetry/api": "^1.0.0", - "@opentelemetry/resources": "1.6.0", + "@opentelemetry/resources": "1.7.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -62,9 +62,9 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0", "jaeger-client": "^3.15.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-exporter-jaeger" diff --git a/packages/opentelemetry-exporter-zipkin/package.json b/packages/opentelemetry-exporter-zipkin/package.json index ed04d165b1..8cdc04dc7d 100644 --- a/packages/opentelemetry-exporter-zipkin/package.json +++ b/packages/opentelemetry-exporter-zipkin/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-zipkin", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry Zipkin Exporter allows the user to send collected traces to Zipkin.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -91,10 +91,10 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-exporter-zipkin" } diff --git a/packages/opentelemetry-propagator-b3/package.json b/packages/opentelemetry-propagator-b3/package.json index 6b78e271fe..60d74a7aef 100644 --- a/packages/opentelemetry-propagator-b3/package.json +++ b/packages/opentelemetry-propagator-b3/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/propagator-b3", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry B3 propagator provides context propagation for systems that are using the B3 header format", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -51,7 +51,7 @@ "access": "public" }, "dependencies": { - "@opentelemetry/core": "1.6.0" + "@opentelemetry/core": "1.7.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0" diff --git a/packages/opentelemetry-propagator-jaeger/package.json b/packages/opentelemetry-propagator-jaeger/package.json index 54b24fcf69..fded131245 100644 --- a/packages/opentelemetry-propagator-jaeger/package.json +++ b/packages/opentelemetry-propagator-jaeger/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/propagator-jaeger", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry Jaeger propagator provides HTTP header propagation for systems that are using Jaeger HTTP header format.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -80,7 +80,7 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0" + "@opentelemetry/core": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-jaeger" } diff --git a/packages/opentelemetry-resources/package.json b/packages/opentelemetry-resources/package.json index 0e4d276c30..ed7964a019 100644 --- a/packages/opentelemetry-resources/package.json +++ b/packages/opentelemetry-resources/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/resources", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry SDK resources", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -89,8 +89,8 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-resources" } diff --git a/packages/opentelemetry-sdk-trace-base/package.json b/packages/opentelemetry-sdk-trace-base/package.json index 088904cc49..970c8b5c83 100644 --- a/packages/opentelemetry-sdk-trace-base/package.json +++ b/packages/opentelemetry-sdk-trace-base/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-trace-base", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry Tracing", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -91,9 +91,9 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-base" } diff --git a/packages/opentelemetry-sdk-trace-node/package.json b/packages/opentelemetry-sdk-trace-node/package.json index 051fad0f9d..91c1dc5035 100644 --- a/packages/opentelemetry-sdk-trace-node/package.json +++ b/packages/opentelemetry-sdk-trace-node/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-trace-node", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry Node SDK provides automatic telemetry (tracing, metrics, etc) for Node.js applications", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -46,8 +46,8 @@ }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@opentelemetry/resources": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/semver": "7.3.9", @@ -64,11 +64,11 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0" }, "dependencies": { - "@opentelemetry/context-async-hooks": "1.6.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/propagator-b3": "1.6.0", - "@opentelemetry/propagator-jaeger": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", + "@opentelemetry/context-async-hooks": "1.7.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/propagator-b3": "1.7.0", + "@opentelemetry/propagator-jaeger": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", "semver": "^7.3.5" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node" diff --git a/packages/opentelemetry-sdk-trace-web/package.json b/packages/opentelemetry-sdk-trace-web/package.json index ade633dcf7..ace6d3108b 100644 --- a/packages/opentelemetry-sdk-trace-web/package.json +++ b/packages/opentelemetry-sdk-trace-web/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-trace-web", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry Web Tracer", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -57,9 +57,9 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@opentelemetry/context-zone": "1.6.0", - "@opentelemetry/propagator-b3": "1.6.0", - "@opentelemetry/resources": "1.6.0", + "@opentelemetry/context-zone": "1.7.0", + "@opentelemetry/propagator-b3": "1.7.0", + "@opentelemetry/resources": "1.7.0", "@types/jquery": "3.5.8", "@types/mocha": "9.1.1", "@types/node": "18.6.5", @@ -91,9 +91,9 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0" + "@opentelemetry/core": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web" } diff --git a/packages/opentelemetry-semantic-conventions/package.json b/packages/opentelemetry-semantic-conventions/package.json index 8d4953452a..6d0cb6227a 100644 --- a/packages/opentelemetry-semantic-conventions/package.json +++ b/packages/opentelemetry-semantic-conventions/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/semantic-conventions", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTelemetry semantic conventions", "main": "build/src/index.js", "module": "build/esm/index.js", diff --git a/packages/opentelemetry-shim-opentracing/package.json b/packages/opentelemetry-shim-opentracing/package.json index 81ac9c3a66..795b7a9bec 100644 --- a/packages/opentelemetry-shim-opentracing/package.json +++ b/packages/opentelemetry-shim-opentracing/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/shim-opentracing", - "version": "1.6.0", + "version": "1.7.0", "description": "OpenTracing to OpenTelemetry shim", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -43,9 +43,9 @@ }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@opentelemetry/propagator-b3": "1.6.0", - "@opentelemetry/propagator-jaeger": "1.6.0", - "@opentelemetry/sdk-trace-base": "1.6.0", + "@opentelemetry/propagator-b3": "1.7.0", + "@opentelemetry/propagator-jaeger": "1.7.0", + "@opentelemetry/sdk-trace-base": "1.7.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "codecov": "3.8.3", @@ -59,8 +59,8 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0" }, "dependencies": { - "@opentelemetry/core": "1.6.0", - "@opentelemetry/semantic-conventions": "1.6.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0", "opentracing": "^0.14.4" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-shim-opentracing" diff --git a/packages/template/package.json b/packages/template/package.json index e34c60e575..6b8cc9759e 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/template", - "version": "1.6.0", + "version": "1.7.0", "private": true, "publishConfig": { "access": "restricted" diff --git a/selenium-tests/package.json b/selenium-tests/package.json index a276f0e84c..4647c0f149 100644 --- a/selenium-tests/package.json +++ b/selenium-tests/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/selenium-tests", - "version": "1.6.0", + "version": "1.7.0", "private": true, "description": "OpenTelemetry Selenium Tests", "main": "index.js", @@ -56,16 +56,16 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/context-zone-peer-dep": "1.6.0", - "@opentelemetry/core": "1.6.0", - "@opentelemetry/exporter-trace-otlp-http": "0.32.0", - "@opentelemetry/exporter-zipkin": "1.6.0", - "@opentelemetry/instrumentation": "0.32.0", - "@opentelemetry/instrumentation-fetch": "0.32.0", - "@opentelemetry/instrumentation-xml-http-request": "0.32.0", - "@opentelemetry/sdk-metrics": "0.32.0", - "@opentelemetry/sdk-trace-base": "1.6.0", - "@opentelemetry/sdk-trace-web": "1.6.0", + "@opentelemetry/context-zone-peer-dep": "1.7.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/exporter-trace-otlp-http": "0.33.0", + "@opentelemetry/exporter-zipkin": "1.7.0", + "@opentelemetry/instrumentation": "0.33.0", + "@opentelemetry/instrumentation-fetch": "0.33.0", + "@opentelemetry/instrumentation-xml-http-request": "0.33.0", + "@opentelemetry/sdk-metrics": "0.33.0", + "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/sdk-trace-web": "1.7.0", "zone.js": "0.11.4" } } From 6fadc6e9a2d8f6b3eea3df92b89ef41093a2fbcb Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Fri, 16 Sep 2022 14:57:05 +0200 Subject: [PATCH 26/77] chore(deps): pin dependency protobufjs-cli to 1.0.2 (#3263) --- experimental/packages/otlp-proto-exporter-base/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/packages/otlp-proto-exporter-base/package.json b/experimental/packages/otlp-proto-exporter-base/package.json index 4ea4a0085c..bdb3660638 100644 --- a/experimental/packages/otlp-proto-exporter-base/package.json +++ b/experimental/packages/otlp-proto-exporter-base/package.json @@ -52,7 +52,7 @@ "codecov": "3.8.3", "mocha": "10.0.0", "nyc": "15.1.0", - "protobufjs-cli": "^1.0.2", + "protobufjs-cli": "1.0.2", "rimraf": "3.0.2", "sinon": "14.0.0", "ts-loader": "8.4.0", From 7870438d1f8c028f382dc22a36528dddbdf3ebca Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Fri, 16 Sep 2022 15:28:41 +0200 Subject: [PATCH 27/77] chore: ignore @opentelemetry/api in renovate config (#3265) Co-authored-by: Daniel Dyla --- renovate.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/renovate.json b/renovate.json index f284cae23d..0e91ce6425 100644 --- a/renovate.json +++ b/renovate.json @@ -6,17 +6,13 @@ "groupSlug": "all-minor-patch", "matchUpdateTypes": ["patch", "minor"] }, - { - "matchPackageNames": ["@opentelemetry/api"], - "rangeStrategy": "bump" - }, { "matchPaths": ["backwards-compatibility"], "matchPackageNames": ["@types/node"], "enabled": false } ], - "ignoreDeps": ["gcp-metadata", "got", "mocha", "husky", "karma-webpack"], + "ignoreDeps": ["gcp-metadata", "got", "mocha", "husky", "karma-webpack", "@opentelemetry/api"], "assignees": ["@blumamir", "@dyladan", "@legendecas", "@Rauno56", "@vmarchaud"], "schedule": ["before 3am on Friday"], "labels": ["dependencies"] From 0074ee2ccdc1c7eda1e5952049d84fe119f748e5 Mon Sep 17 00:00:00 2001 From: Sami Musallam Date: Sun, 18 Sep 2022 11:19:18 +0300 Subject: [PATCH 28/77] Validate maxExportBatchSize in BatchSpanProcessorBase (#3232) --- CHANGELOG.md | 3 +++ .../src/export/BatchSpanProcessorBase.ts | 9 +++++++-- .../export/BatchSpanProcessorBase.test.ts | 19 ++++++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f7b5db2f3..52fea3af5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ All notable changes to this project will be documented in this file. * fix(sdk-trace-base): make span start times resistant to hrtime clock drift [#3129](https://github.com/open-telemetry/opentelemetry-js/issues/3129) +* fix(sdk-trace-base): validate maxExportBatchSize in BatchSpanProcessorBase + [#3232](https://github.com/open-telemetry/opentelemetry-js/issues/3232) + ### :books: (Refine Doc) * docs(metrics): add missing metrics packages to SDK reference documentation [#3239](https://github.com/open-telemetry/opentelemetry-js/pull/3239) @dyladan diff --git a/packages/opentelemetry-sdk-trace-base/src/export/BatchSpanProcessorBase.ts b/packages/opentelemetry-sdk-trace-base/src/export/BatchSpanProcessorBase.ts index e6417d84af..8978fc7d79 100644 --- a/packages/opentelemetry-sdk-trace-base/src/export/BatchSpanProcessorBase.ts +++ b/packages/opentelemetry-sdk-trace-base/src/export/BatchSpanProcessorBase.ts @@ -14,14 +14,14 @@ * limitations under the License. */ -import { context, Context, TraceFlags } from '@opentelemetry/api'; +import {context, Context, diag, TraceFlags} from '@opentelemetry/api'; import { BindOnceFuture, ExportResultCode, getEnv, globalErrorHandler, suppressTracing, - unrefTimer, + unrefTimer } from '@opentelemetry/core'; import { Span } from '../Span'; import { SpanProcessor } from '../SpanProcessor'; @@ -63,6 +63,11 @@ export abstract class BatchSpanProcessorBase implements : env.OTEL_BSP_EXPORT_TIMEOUT; this._shutdownOnce = new BindOnceFuture(this._shutdown, this); + + if (this._maxExportBatchSize > this._maxQueueSize) { + diag.warn('BatchSpanProcessor: maxExportBatchSize must be smaller or equal to maxQueueSize, setting maxExportBatchSize to match maxQueueSize'); + this._maxExportBatchSize = this._maxQueueSize; + } } forceFlush(): Promise { diff --git a/packages/opentelemetry-sdk-trace-base/test/common/export/BatchSpanProcessorBase.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/export/BatchSpanProcessorBase.test.ts index 8d8de40d32..229e2bdb3c 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/export/BatchSpanProcessorBase.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/export/BatchSpanProcessorBase.test.ts @@ -18,7 +18,7 @@ import { diag, ROOT_CONTEXT } from '@opentelemetry/api'; import { ExportResultCode, loggingErrorHandler, - setGlobalErrorHandler, + setGlobalErrorHandler } from '@opentelemetry/core'; import * as assert from 'assert'; import * as sinon from 'sinon'; @@ -435,4 +435,21 @@ describe('BatchSpanProcessorBase', () => { }); }); }); + + describe('maxExportBatchSize', () => { + let processor: BatchSpanProcessor; + + describe('when "maxExportBatchSize" is greater than "maxQueueSize"', () => { + beforeEach(() => { + processor = new BatchSpanProcessor( + exporter,{ + maxExportBatchSize: 7, + maxQueueSize: 6, + }); + }); + it('should match maxQueueSize', () => { + assert.equal(processor['_maxExportBatchSize'], processor['_maxQueueSize']); + }); + }); + }); }); From d8dabf1be3825f5d33aebb636bf8340156250f81 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Sun, 18 Sep 2022 16:38:11 +0800 Subject: [PATCH 29/77] docs: update exporter guide (#3256) Co-authored-by: Valentin Marchaud --- doc/{ => contributing}/web-api.md | 0 doc/exporter-guide.md | 50 ++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 8 deletions(-) rename doc/{ => contributing}/web-api.md (100%) diff --git a/doc/web-api.md b/doc/contributing/web-api.md similarity index 100% rename from doc/web-api.md rename to doc/contributing/web-api.md diff --git a/doc/exporter-guide.md b/doc/exporter-guide.md index 46dfe0d221..adeb090b43 100644 --- a/doc/exporter-guide.md +++ b/doc/exporter-guide.md @@ -12,13 +12,15 @@ opentelemetry-exporter-myexporter │ └── index.ts │ └── transform.ts │ └── types.ts - │ └── myexporter.ts + │ └── my-trace-exporter.ts + │ └── my-metric-exporter.ts └── test └── transform.test.ts - └── myexporter.test.ts + └── my-trace-exporter.test.ts + └── my-metric-exporter.test.ts ``` -## Tracing +## Traces The `SpanExporter` interface defines which methods the protocol-specific trace/span exporters must implement so that they can be plugged into OpenTelemetry SDK. Span exporters must follow these rules: @@ -29,7 +31,7 @@ The `SpanExporter` interface defines which methods the protocol-specific trace/s 5. Do not modify received spans. 6. Do not implement queuing or batching logic because this is handled by Span Processors. -The current `SpanExporter` interface (`0.2.0`) contains 2 methods: +The current `SpanExporter` interface contains 2 methods: - `export`: Exports a batch of spans. In this method, you’ll process and translate `ReadableSpan` Data into the data that your trace backend accepts, and send them to your tracing backend. @@ -39,16 +41,48 @@ Please refer to the [Zipkin Exporter][zipkin-exporter] or [Jaeger Exporter][jaeg ## Metrics -The `MetricExporter` defines the interface that protocol-specific exporters must implement so that they can be plugged into OpenTelemetry SDK and support sending of metrics data. +Metrics can be exported with two distinct patterns: -The current `MetricExporter` interface (`0.2.0`) defines 2 methods: +- Push model exporting, like periodically push metrics to the backend. +- Pull model exporting, like Prometheus pulling metrics from the application. -- `export`: Exports a batch of telemetry data. In this method you’ll process and translate `MetricRecord` Data into the data that your metric backend accepts. +### Push model exporting -- `shutdown`: Shuts down the exporter. This is an opportunity for exporter to do any cleanup required. `Shutdown` should be called only once for each Exporter instance. After the call to `Shutdown` subsequent calls to Export are not allowed and should return `FailedNotRetryable` error. +The `PushMetricExporter` defines the interface that protocol-specific exporters must implement so that they can be plugged into OpenTelemetry SDK and support sending of metrics data with `PeriodicMetricReader`. + +The current `PushMetricExporter` interface defines 3 required methods: + +- `export`: Exports a batch of telemetry data. In this method you’ll process and translate `ResourceMetrics` into the data that your metric backend accepts. + +- `shutdown`: Shuts down the exporter. This is an opportunity for exporter to do any cleanup required. `Shutdown` should be called only once for each Exporter instance. + +- `forceFlush`: Ensure that the export of any metrics the exporter has received is completed before the returned promise is settled. + +The `PushMetricExporter` interface can also implement following methods to provide a preference on metric configuration: + +- `selectAggregationTemporality`: Select the preferred `AggregationTemporality` for the given `InstrumentType` for this exporter. + +- `selectAggregation`: Select the preferred `Aggregation` for the given `InstrumentType` for this exporter. + +Please refer to the [OTLP Exporter][otlp-exporter] for more comprehensive examples. + +### Pull model exporting + +The pulling model exporting requires the export pipeline proactively initiate metric collections. Such exporting pipeline must be modeled as a `MetricReader`. + +The abstract class `MetricReader` defines the interface that protocol-specific readers must implement so that they can be plugged into OpenTelemetry SDK and support pulling of metrics data. + +The current `MetricReader` interface defines 2 required methods: + +- `onShutdown`: Shuts down the reader. This is an opportunity for reader to do any cleanup required. `Shutdown` should be called only once for each reader instance. + +- `onForceFlush`: Ensure that the export of any metrics the reader has received is completed before the returned promise is settled. + +A `MetricReader` can initiate a metric collection request with `MetricReader.collect()` method. The `MetricReader.collect()` returns a promise that settles with a `CollectionResult`, containing the `ResourceMetrics` record and a series of reasons for possibly failed asynchronous metric instrument collection. The `ResourceMetrics` record can be processed and translated into the data that your metric backend accepts. Please refer to the [Prometheus Exporter][prometheus-exporter] for more comprehensive examples. [zipkin-exporter]: https://github.com/open-telemetry/opentelemetry-js/blob/main/packages/opentelemetry-exporter-zipkin [jaeger-exporter]: https://github.com/open-telemetry/opentelemetry-js/blob/main/packages/opentelemetry-exporter-jaeger +[otlp-exporter]: https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc [prometheus-exporter]: https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-exporter-prometheus From 6111ae0181474f89c9f9441a0f8a474ef3092175 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 19 Sep 2022 15:31:18 -0400 Subject: [PATCH 30/77] chore: remove repo specific files from api dir (#3260) --- api/.commitlintrc.yml | 29 -------- api/.editorconfig | 11 --- api/.eslintrc.js | 69 ------------------ api/.gitattributes | 39 ---------- api/.github/CODEOWNERS | 15 ---- api/.github/workflows/codeql-analysis.yml | 34 --------- api/.github/workflows/docs.yaml | 27 ------- api/.github/workflows/lint.yaml | 37 ---------- api/.github/workflows/release-please.yml | 33 --------- api/.github/workflows/test.yaml | 58 --------------- api/.gitignore | 88 ----------------------- api/.markdownlint.json | 7 -- api/.npmignore | 4 -- api/TODO.md | 11 +++ api/karma.base.js | 31 -------- api/karma.conf.js | 8 --- api/karma.webpack.js | 43 ----------- api/renovate.json | 25 ------- api/scripts/version-update.js | 48 ------------- api/tsconfig.esm.json | 13 ---- api/tsconfig.json | 39 ---------- api/webpack.node-polyfills.js | 52 -------------- 22 files changed, 11 insertions(+), 710 deletions(-) delete mode 100644 api/.commitlintrc.yml delete mode 100644 api/.editorconfig delete mode 100644 api/.eslintrc.js delete mode 100644 api/.gitattributes delete mode 100644 api/.github/CODEOWNERS delete mode 100644 api/.github/workflows/codeql-analysis.yml delete mode 100644 api/.github/workflows/docs.yaml delete mode 100644 api/.github/workflows/lint.yaml delete mode 100644 api/.github/workflows/release-please.yml delete mode 100644 api/.github/workflows/test.yaml delete mode 100644 api/.gitignore delete mode 100644 api/.markdownlint.json delete mode 100644 api/.npmignore create mode 100644 api/TODO.md delete mode 100644 api/karma.base.js delete mode 100644 api/karma.conf.js delete mode 100644 api/karma.webpack.js delete mode 100644 api/renovate.json delete mode 100644 api/scripts/version-update.js delete mode 100644 api/tsconfig.esm.json delete mode 100644 api/tsconfig.json delete mode 100644 api/webpack.node-polyfills.js diff --git a/api/.commitlintrc.yml b/api/.commitlintrc.yml deleted file mode 100644 index 1a5e5ac793..0000000000 --- a/api/.commitlintrc.yml +++ /dev/null @@ -1,29 +0,0 @@ -extends: - - '@commitlint/config-conventional' -rules: - header-max-length: [1, 'always', 72] - type-enum: - - 2 - - always - - - ci - - feat - - fix - - docs - - style - - refactor - - perf - - test - - revert - - chore -help: | - **Possible types**: - `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle CI, BrowserStack, SauceLabs) - `feat`: Adds a new feature. - `fix`: Solves a bug. - `docs`: Adds or alters documentation. (example scopes: readme, worker, code_of_conduct, contributors) - `style`: Improves formatting, white-space. - `refactor`: Rewrites code without feature, performance or bug changes. - `perf`: Improves performance. - `test`: Adds or modifies tests. (example scopes: functionals, unit-tests) - `revert`: Changes that reverting other changes - `chore`: No production code change. Updating grunt tasks etc; diff --git a/api/.editorconfig b/api/.editorconfig deleted file mode 100644 index f68e97b033..0000000000 --- a/api/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# http://editorconfig.org - -root = true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true diff --git a/api/.eslintrc.js b/api/.eslintrc.js deleted file mode 100644 index c78e7b660d..0000000000 --- a/api/.eslintrc.js +++ /dev/null @@ -1,69 +0,0 @@ -module.exports = { - plugins: [ - "@typescript-eslint", - "header", - "node" - ], - extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], - parser: "@typescript-eslint/parser", - parserOptions: { - "project": "./tsconfig.json" - }, - rules: { - "quotes": [2, "single", { "avoidEscape": true }], - "@typescript-eslint/no-floating-promises": 2, - "@typescript-eslint/no-this-alias": "off", - "brace-style": ["error", "1tbs"], - "eqeqeq": [ - "error", - "smart" - ], - "prefer-rest-params": "off", - "@typescript-eslint/naming-convention": [ - "error", - { - "selector": "memberLike", - "modifiers": ["private", "protected"], - "format": ["camelCase"], - "leadingUnderscore": "require" - } - ], - "no-console": "error", - "no-shadow": "off", - "@typescript-eslint/no-shadow": ["warn"], - "@typescript-eslint/no-unused-vars": ["error", {"argsIgnorePattern": "^_", "args": "after-used"}], - "@typescript-eslint/no-inferrable-types": ["error", { ignoreProperties: true }], - "@typescript-eslint/no-empty-function": ["off"], - "@typescript-eslint/ban-types": ["warn", { - "types": { - "Function": null, - } - }], - "@typescript-eslint/no-shadow": ["warn"], - "arrow-parens": ["error", "as-needed"], - "node/no-deprecated-api": ["warn"], - "header/header": [2, "block", [{ - pattern: / \* Copyright The OpenTelemetry Authors[\r\n]+ \*[\r\n]+ \* Licensed under the Apache License, Version 2\.0 \(the \"License\"\);[\r\n]+ \* you may not use this file except in compliance with the License\.[\r\n]+ \* You may obtain a copy of the License at[\r\n]+ \*[\r\n]+ \* https:\/\/www\.apache\.org\/licenses\/LICENSE-2\.0[\r\n]+ \*[\r\n]+ \* Unless required by applicable law or agreed to in writing, software[\r\n]+ \* distributed under the License is distributed on an \"AS IS\" BASIS,[\r\n]+ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.[\r\n]+ \* See the License for the specific language governing permissions and[\r\n]+ \* limitations under the License\./gm, - template: - `\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n ` - }]] - }, - overrides: [ - { - "files": ["test/**/*.ts"], - "rules": { - "no-empty": "off", - "@typescript-eslint/ban-ts-ignore": "off", - "@typescript-eslint/no-empty-function": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-floating-promises": 1, - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/no-var-requires": "off", - "@typescript-eslint/no-shadow": ["off"], - "@typescript-eslint/no-floating-promises": ["off"], - "@typescript-eslint/no-non-null-assertion": ["off"], - "@typescript-eslint/explicit-module-boundary-types": ["off"] - } - } - ] -}; diff --git a/api/.gitattributes b/api/.gitattributes deleted file mode 100644 index 0113e927b8..0000000000 --- a/api/.gitattributes +++ /dev/null @@ -1,39 +0,0 @@ -## This .gitattributes file automatically formats the EOL character in certain filetypes within the repository - -## Source code -# JavaScript, TypeScript, c, and h source files -*.js text eol=lf -*.ts text eol=lf -*.h text eol=lf diff=cpp -*.c text eol=lf diff=cpp - -# Shell scripts -*.sh text eol=lf -*.bash text eol=lf - -# Windows batch and PowerShell scripts -*.bat text eol=crlf -*.cmd text eol=crlf -*.ps1 text eol=crlf - -##### Other file types ##### - -## Text files and documentation -*.txt text -README* text -RELEASING* text -CHANGELOG* text -CONTRIBUTING* text -INSTALL* text -LICENSE* text - -## Non-text documentation -*.html text diff=html -*.pdf binary -*.json text eol=lf -*.rtf binary - -## Git Properties -.gitignore text -.gitmodules text -.gitattributes text diff --git a/api/.github/CODEOWNERS b/api/.github/CODEOWNERS deleted file mode 100644 index 744582a847..0000000000 --- a/api/.github/CODEOWNERS +++ /dev/null @@ -1,15 +0,0 @@ -##################################################### -# -# List of approvers for OpenTelemetry JS SDK -# -##################################################### -# -# Learn about membership in OpenTelemetry community: -# https://github.com/open-telemetry/community/blob/master/community-membership.md -# -# -# Learn about CODEOWNERS file format: -# https://help.github.com/en/articles/about-code-owners -# - -* @open-telemetry/javascript-approvers diff --git a/api/.github/workflows/codeql-analysis.yml b/api/.github/workflows/codeql-analysis.yml deleted file mode 100644 index c9efc6332b..0000000000 --- a/api/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: "CodeQL" - -on: - workflow_dispatch: - schedule: - # ┌───────────── minute (0 - 59) - # │ ┌───────────── hour (0 - 23) - # │ │ ┌───────────── day of the month (1 - 31) - # │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) - # │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) - # │ │ │ │ │ - # │ │ │ │ │ - # │ │ │ │ │ - # * * * * * - - cron: '30 1 * * *' - -jobs: - CodeQL-Build: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: javascript - - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 diff --git a/api/.github/workflows/docs.yaml b/api/.github/workflows/docs.yaml deleted file mode 100644 index 4dae75bbf6..0000000000 --- a/api/.github/workflows/docs.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Deploy API Documentation - -on: - release: - types: [published] - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout 🛎️ - uses: actions/checkout@v2 - - - name: Install root dependencies - run: npm install --ignore-scripts - - - name: Build 🔧 - run: | - npm run compile - npm run docs - - - name: Deploy 🚀 - uses: JamesIves/github-pages-deploy-action@releases/v3 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BRANCH: gh-pages # The branch the action should deploy to. - FOLDER: docs/out # The folder the action should deploy. diff --git a/api/.github/workflows/lint.yaml b/api/.github/workflows/lint.yaml deleted file mode 100644 index aba62bd293..0000000000 --- a/api/.github/workflows/lint.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Lint - -on: - push: - branches: - - main - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Lint markdown files - uses: docker://avtodev/markdown-lint:v1 - with: - args: "./**/*.md -i ./CHANGELOG.md" - - - name: Install dependencies - run: npm install - - - name: Build 🔧 - run: npm run compile - - - name: Lint - run: npm run lint - - - name: Check for Circular Dependencies - run: npm run cycle-check - - - name: Generate Documentation 📜 - run: npm run docs - - - name: Test Docs - run: npm run docs:test diff --git a/api/.github/workflows/release-please.yml b/api/.github/workflows/release-please.yml deleted file mode 100644 index f4f136910d..0000000000 --- a/api/.github/workflows/release-please.yml +++ /dev/null @@ -1,33 +0,0 @@ -on: - push: - branches: - - main -name: release-please -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: GoogleCloudPlatform/release-please-action@v2 - id: release - with: - token: ${{secrets.RELEASE_PR_TOKEN}} - release-type: node - package-name: "@opentelemetry/api" - # The logic below handles the npm publication: - - uses: actions/checkout@v2 - # these if statements ensure that a publication only occurs when - # a new release is created: - if: ${{ steps.release.outputs.release_created }} - - uses: actions/setup-node@v1 - with: - node-version: 14 - registry-url: 'https://registry.npmjs.org' - if: ${{ steps.release.outputs.release_created }} - - run: npm install - if: ${{ steps.release.outputs.release_created }} - - run: npm run compile - if: ${{ steps.release.outputs.release_created }} - - run: npm publish --tag next - env: - NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} - if: ${{ steps.release.outputs.release_created }} diff --git a/api/.github/workflows/test.yaml b/api/.github/workflows/test.yaml deleted file mode 100644 index 75f3998fc0..0000000000 --- a/api/.github/workflows/test.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: Unit Tests -on: - push: - branches: - - main - pull_request: - -jobs: - unit-test: - strategy: - fail-fast: false - matrix: - node: ["8", "10", "12", "14", "16"] - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup Node - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - - - name: Install Dependencies - run: npm install - - - name: Compile 🔧 - run: npm run compile - - - name: Unit tests - run: npm run test - - - name: Report Coverage - run: npm run codecov - if: ${{ matrix.node == '14' }} - - browser-tests: - runs-on: ubuntu-latest - container: - image: circleci/node:12-browsers - steps: - - name: Permission Setup - run: sudo chmod -R 777 /github /__w - - - name: Checkout - uses: actions/checkout@v2 - - - name: Install Dependencies - run: npm install - - - name: Compile 🔧 - run: npm run compile - - - name: Unit tests - run: npm run test:browser - - - name: Report Coverage - run: npm run codecov:browser diff --git a/api/.gitignore b/api/.gitignore deleted file mode 100644 index 10aac0eb73..0000000000 --- a/api/.gitignore +++ /dev/null @@ -1,88 +0,0 @@ -# version.ts file is autogenerated at compile time -src/version.ts - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ -build/ - -# TypeScript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env - -# next.js build output -.next - -# lock files -yarn.lock -package-lock.json - -# generated gh-pages files -docs/out - -.nyc_output - -#lerna -.changelog -package.json.lerna_backup - -# OS generated files -.DS_Store - -# VsCode configs -.vscode/ - -#Visual Studio -.vs/ - -#IDEA -.idea -*.iml diff --git a/api/.markdownlint.json b/api/.markdownlint.json deleted file mode 100644 index 6208ac19f1..0000000000 --- a/api/.markdownlint.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "MD013": false, - "MD024": false, - "MD033": false, - "MD041": false, - "MD026": false -} diff --git a/api/.npmignore b/api/.npmignore deleted file mode 100644 index 9505ba9450..0000000000 --- a/api/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -/bin -/coverage -/doc -/test diff --git a/api/TODO.md b/api/TODO.md new file mode 100644 index 0000000000..53f2b1c282 --- /dev/null +++ b/api/TODO.md @@ -0,0 +1,11 @@ +# TODO + +These tasks must be completed before the API package can be released from this repository. + +- [x] remove files specific to the API git repo +- [ ] add to lerna monorepo + - [ ] add tsconfig files + - [ ] add web testing + - [ ] build esm versions +- [ ] test node versions 8, 10, and 12 +- [ ] add to auto published docs diff --git a/api/karma.base.js b/api/karma.base.js deleted file mode 100644 index cbae813f7b..0000000000 --- a/api/karma.base.js +++ /dev/null @@ -1,31 +0,0 @@ -/*! - * 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 - * - * 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. - */ - -module.exports = { - listenAddress: 'localhost', - hostname: 'localhost', - browsers: ['ChromeHeadless'], - frameworks: ['mocha'], - coverageIstanbulReporter: { - reports: ['html', 'json'], - dir: '.nyc_output', - fixWebpackSourcePaths: true - }, - reporters: ['spec', 'coverage-istanbul'], - files: ['test/index-webpack.ts'], - preprocessors: { 'test/index-webpack.ts': ['webpack'] }, - webpackMiddleware: { noInfo: true } -}; diff --git a/api/karma.conf.js b/api/karma.conf.js deleted file mode 100644 index c6dacb9a68..0000000000 --- a/api/karma.conf.js +++ /dev/null @@ -1,8 +0,0 @@ -const karmaWebpackConfig = require('./karma.webpack'); -const karmaBaseConfig = require('./karma.base'); - -module.exports = (config) => { - config.set(Object.assign({}, karmaBaseConfig, { - webpack: karmaWebpackConfig - })) -}; \ No newline at end of file diff --git a/api/karma.webpack.js b/api/karma.webpack.js deleted file mode 100644 index bc8eb3a790..0000000000 --- a/api/karma.webpack.js +++ /dev/null @@ -1,43 +0,0 @@ -/*! - * 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 - * - * 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. - */ - -const webpackNodePolyfills = require('./webpack.node-polyfills.js'); - -// This is the webpack configuration for browser Karma tests with coverage. -module.exports = { - mode: 'development', - target: 'web', - output: { filename: 'bundle.js' }, - resolve: { extensions: ['.ts', '.js'] }, - devtool: 'inline-source-map', - module: { - rules: [ - { test: /\.ts$/, use: 'ts-loader' }, - { - enforce: 'post', - exclude: /(node_modules|\.test\.[tj]sx?$)/, - test: /\.ts$/, - use: { - loader: 'istanbul-instrumenter-loader', - options: { esModules: true } - } - }, - // This setting configures Node polyfills for the browser that will be - // added to the webpack bundle for Karma tests. - { parser: { node: webpackNodePolyfills } } - ] - } -}; diff --git a/api/renovate.json b/api/renovate.json deleted file mode 100644 index f78c11be4a..0000000000 --- a/api/renovate.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "extends": [ - "config:base" - ], - "packageRules": [ - { - "groupName": "all non-major dependencies", - "updateTypes": ["patch", "minor"], - "groupSlug": "all-minor-patch" - } - ], - "ignoreDeps": [ - "gcp-metadata", - "got", - "mocha" - ], - "assignees": [ - "@dyladan", - "@vmarchaud" - ], - "schedule": [ - "before 3am on Friday" - ], - "labels": ["dependencies"] -} diff --git a/api/scripts/version-update.js b/api/scripts/version-update.js deleted file mode 100644 index 4e22aa900b..0000000000 --- a/api/scripts/version-update.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ - -const fs = require('fs'); -const os = require('os'); -const path = require('path'); - -const appRoot = process.cwd(); - -const packageJsonUrl = path.resolve(`${appRoot}/package.json`); -const pjson = require(packageJsonUrl); - -const content = `/* - * 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. - */ - -// this is autogenerated file, see scripts/version-update.js -export const VERSION = '${pjson.version}'; -`; - -const fileUrl = path.join(appRoot, "src", "version.ts") - -fs.writeFileSync(fileUrl, content); \ No newline at end of file diff --git a/api/tsconfig.esm.json b/api/tsconfig.esm.json deleted file mode 100644 index fd8eb6b378..0000000000 --- a/api/tsconfig.esm.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "ES6", - "moduleResolution": "node", - "outDir": "build/esm", - "rootDir": "src", - "tsBuildInfoFile": "build/esm/tsconfig.esm.tsbuildinfo" - }, - "include": [ - "src/**/*.ts" - ], -} diff --git a/api/tsconfig.json b/api/tsconfig.json deleted file mode 100644 index f73b707389..0000000000 --- a/api/tsconfig.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "compilerOptions": { - "allowUnreachableCode": false, - "allowUnusedLabels": false, - "declaration": true, - "declarationMap": true, - "forceConsistentCasingInFileNames": true, - "module": "commonjs", - "noEmitOnError": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "noUnusedLocals": true, - "noImplicitOverride": true, - "outDir": "build", - "pretty": true, - "rootDir": ".", - "sourceMap": true, - "strict": true, - "strictNullChecks": true, - "target": "es5", - "incremental": true, - "newLine": "LF", - "inlineSources": true - }, - "include": [ - "src/**/*.ts", - "test/**/*.ts" - ], - "exclude": [ - "node_modules" - ], - "typedocOptions": { - "name": "OpenTelemetry API for JavaScript", - "out": "docs/out", - "entryPoints": ["./src/index.ts"], - "excludePrivate": true, - "hideGenerator": true - } -} diff --git a/api/webpack.node-polyfills.js b/api/webpack.node-polyfills.js deleted file mode 100644 index 8d50ebd242..0000000000 --- a/api/webpack.node-polyfills.js +++ /dev/null @@ -1,52 +0,0 @@ -module.exports = { - // Enable the assert library polyfill because that is used in tests - assert: true, - // The assert polyfill from github.com/browserify/commonjs-assert - // also requires the `global` polyfill. - global: true, - - // Turn off all other Node.js API polyfills for the browser tests to - // make sure that we are not attempting to use Node-specific APIs in - // the browser code. Instead, we will write browser specific - // implementations of platform functionality we need under the - // `./src/platform/browser` folder. This allows for writing browser - // optimized implementations of the specific needed functionality - // rather than bringing in (sometimes large) polyfills for the - // corresponding Node APIs. - Buffer: false, - __dirname: false, - __filename: false, - buffer: false, - child_process: false, - cluster: false, - console: false, - constants: false, - crypto: false, - dgram: false, - dns: false, - domain: false, - events: false, - fs: false, - http: false, - https: false, - module: false, - net: false, - os: false, - path: false, - process: false, - punycode: false, - querystring: false, - readline: false, - repl: false, - setImmediate: false, - stream: false, - string_decoder: false, - sys: false, - timers: false, - tls: false, - tty: false, - url: false, - util: false, - vm: false, - zlib: false -}; From c2688326890ee42151aca2e15801a8769f9b53c3 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 22 Sep 2022 05:29:00 -0400 Subject: [PATCH 31/77] chore: add api to monorepo (#3261) * Add API to lerna * Update todo * Expect instead of ignore error * Add webpack test context * Block scope test variables * Fix linting * Fix lining path * Fix lint * Fix lint * Update index-webpack.worker.ts Co-authored-by: Nev <54870357+MSNev@users.noreply.github.com> --- api/.eslintrc.js | 8 +++ api/TODO.md | 10 ++-- api/karma.conf.js | 24 ++++++++ api/karma.worker.js | 24 ++++++++ api/package.json | 58 +++++++++---------- api/src/platform/browser/globalThis.ts | 6 +- api/src/trace/NoopTracer.ts | 6 +- api/test/api/api.test.ts | 2 +- api/test/diag/consoleLogger.test.ts | 6 +- api/test/index-webpack.ts | 12 ++-- api/test/index-webpack.worker.ts | 19 ++++++ api/tsconfig.all.json | 9 +++ api/tsconfig.esm.json | 11 ++++ api/tsconfig.esnext.json | 11 ++++ api/tsconfig.json | 13 +++++ experimental/packages/api-logs/tsconfig.json | 5 ++ .../exporter-trace-otlp-grpc/tsconfig.json | 3 + .../exporter-trace-otlp-http/tsconfig.json | 3 + .../exporter-trace-otlp-proto/tsconfig.json | 3 + .../opentelemetry-api-metrics/tsconfig.json | 5 ++ .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../opentelemetry-sdk-metrics/tsconfig.json | 3 + .../opentelemetry-sdk-node/tsconfig.json | 3 + .../packages/otlp-exporter-base/tsconfig.json | 3 + .../otlp-grpc-exporter-base/tsconfig.json | 3 + .../otlp-proto-exporter-base/tsconfig.json | 3 + .../packages/otlp-transformer/tsconfig.json | 3 + .../tsconfig.json | 3 + lerna.json | 1 + .../tsconfig.json | 5 ++ .../tsconfig.json | 5 ++ packages/opentelemetry-core/tsconfig.json | 3 + .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../opentelemetry-propagator-b3/tsconfig.json | 3 + .../tsconfig.json | 3 + .../opentelemetry-resources/tsconfig.json | 3 + .../tsconfig.json | 3 + .../tsconfig.json | 3 + .../opentelemetry-sdk-trace-web/tsconfig.json | 3 + .../tsconfig.json | 3 + tsconfig.json | 4 ++ 50 files changed, 282 insertions(+), 49 deletions(-) create mode 100644 api/.eslintrc.js create mode 100644 api/karma.conf.js create mode 100644 api/karma.worker.js create mode 100644 api/test/index-webpack.worker.ts create mode 100644 api/tsconfig.all.json create mode 100644 api/tsconfig.esm.json create mode 100644 api/tsconfig.esnext.json create mode 100644 api/tsconfig.json diff --git a/api/.eslintrc.js b/api/.eslintrc.js new file mode 100644 index 0000000000..7d5c10c7f9 --- /dev/null +++ b/api/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + "env": { + "mocha": true, + "commonjs": true, + "shared-node-browser": true + }, + ...require('../eslint.config.js') +} diff --git a/api/TODO.md b/api/TODO.md index 53f2b1c282..30f67e54ec 100644 --- a/api/TODO.md +++ b/api/TODO.md @@ -3,9 +3,9 @@ These tasks must be completed before the API package can be released from this repository. - [x] remove files specific to the API git repo -- [ ] add to lerna monorepo - - [ ] add tsconfig files - - [ ] add web testing - - [ ] build esm versions +- [x] add to lerna monorepo + - [x] add tsconfig files + - [x] add web testing + - [x] build esm versions - [ ] test node versions 8, 10, and 12 -- [ ] add to auto published docs +- [x] add to auto published docs diff --git a/api/karma.conf.js b/api/karma.conf.js new file mode 100644 index 0000000000..5f7d9f888d --- /dev/null +++ b/api/karma.conf.js @@ -0,0 +1,24 @@ +/*! + * 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 + * + * 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. + */ + +const karmaWebpackConfig = require('../karma.webpack'); +const karmaBaseConfig = require('../karma.base'); + +module.exports = (config) => { + config.set(Object.assign({}, karmaBaseConfig, { + webpack: karmaWebpackConfig, + })) +}; diff --git a/api/karma.worker.js b/api/karma.worker.js new file mode 100644 index 0000000000..7917d5a000 --- /dev/null +++ b/api/karma.worker.js @@ -0,0 +1,24 @@ +/*! + * 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 + * + * 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. + */ + +const karmaWebpackConfig = require('../karma.webpack'); +const karmaBaseConfig = require('../karma.worker'); + +module.exports = (config) => { + config.set(Object.assign({}, karmaBaseConfig, { + webpack: karmaWebpackConfig, + })) +}; diff --git a/api/package.json b/api/package.json index c0a475d890..012fd629ef 100644 --- a/api/package.json +++ b/api/package.json @@ -12,22 +12,25 @@ }, "repository": "https://github.com/open-telemetry/opentelemetry-js-api.git", "scripts": { - "clean": "tsc --build --clean tsconfig.json tsconfig.esm.json", - "codecov:browser": "nyc report --reporter=json && codecov -f coverage/*.json -p .", - "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p .", - "precompile": "npm run version", + "clean": "tsc --build --clean", + "codecov:browser": "nyc report --reporter=json && codecov -f coverage/*.json -p ../", + "codecov:webworker": "nyc report --reporter=json && codecov -f coverage/*.json -p ../", + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../", + "precompile": "lerna run version --scope $(npm pkg get name) --include-dependencies", "compile": "tsc --build tsconfig.json tsconfig.esm.json", "docs": "typedoc", "docs:deploy": "gh-pages --dist docs/out", "docs:test": "linkinator docs/out --silent && linkinator docs/*.md *.md --markdown --silent", - "lint:fix": "eslint src test --ext .ts --fix", - "lint": "eslint src test --ext .ts", + "lint:fix": "eslint . --ext .ts --fix", + "lint": "eslint . --ext .ts", "test:browser": "nyc karma start --single-run", "test": "nyc ts-mocha -p tsconfig.json test/**/*.test.ts", + "test:webworker": "nyc karma start karma.worker.js --single-run", "cycle-check": "dpdm --exit-code circular:1 src/index.ts", - "version": "node scripts/version-update.js", - "prewatch": "npm run version", - "watch": "tsc --build --watch" + "version": "node ../scripts/version-update.js", + "prewatch": "npm run precompile", + "watch": "tsc --build --watch", + "peer-api-check": "node ../scripts/peer-api-check.js" }, "keywords": [ "opentelemetry", @@ -57,34 +60,27 @@ "access": "public" }, "devDependencies": { - "@types/mocha": "8.2.2", - "@types/node": "14.17.4", - "@types/sinon": "10.0.2", - "@types/webpack-env": "1.16.0", - "@typescript-eslint/eslint-plugin": "5.0.0", - "@typescript-eslint/parser": "5.0.0", - "codecov": "3.8.2", - "dpdm": "3.7.1", - "eslint": "7.32.0", - "eslint-plugin-header": "3.1.1", - "eslint-plugin-node": "11.1.0", - "gh-pages": "3.2.0", + "@types/mocha": "9.1.1", + "@types/node": "18.6.5", + "@types/sinon": "10.0.13", + "@types/webpack-env": "1.16.3", + "codecov": "3.8.3", + "dpdm": "3.10.0", "istanbul-instrumenter-loader": "3.0.1", - "karma": "5.2.3", + "karma": "6.3.16", "karma-chrome-launcher": "3.1.0", "karma-coverage-istanbul-reporter": "3.0.3", "karma-mocha": "2.0.1", + "karma-mocha-webworker": "1.3.0", "karma-spec-reporter": "0.0.32", "karma-webpack": "4.0.2", - "lerna-changelog": "1.0.1", - "linkinator": "2.13.6", - "mocha": "7.2.0", + "mocha": "10.0.0", "nyc": "15.1.0", - "sinon": "11.1.1", - "ts-loader": "8.2.0", - "ts-mocha": "8.0.0", - "typedoc": "0.21.2", - "typescript": "4.3.5", + "sinon": "14.0.0", + "ts-loader": "8.4.0", + "ts-mocha": "10.0.0", + "typescript": "4.4.4", "webpack": "4.46.0" - } + }, + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/api" } diff --git a/api/src/platform/browser/globalThis.ts b/api/src/platform/browser/globalThis.ts index ebea1f48c5..68ca8ac5ff 100644 --- a/api/src/platform/browser/globalThis.ts +++ b/api/src/platform/browser/globalThis.ts @@ -29,7 +29,7 @@ // eslint-disable-next-line node/no-unsupported-features/es-builtins, no-undef export const _globalThis: typeof globalThis = typeof globalThis === 'object' ? globalThis : - typeof self === 'object' ? self : - typeof window === 'object' ? window : - typeof global === 'object' ? global : + typeof self === 'object' ? self : + typeof window === 'object' ? window : + typeof global === 'object' ? global : {} as typeof globalThis; diff --git a/api/src/trace/NoopTracer.ts b/api/src/trace/NoopTracer.ts index d1db93e9cf..cf386c4f57 100644 --- a/api/src/trace/NoopTracer.ts +++ b/api/src/trace/NoopTracer.ts @@ -24,7 +24,7 @@ import { SpanOptions } from './SpanOptions'; import { SpanContext } from './span_context'; import { Tracer } from './tracer'; -const context = ContextAPI.getInstance(); +const contextApi = ContextAPI.getInstance(); /** * No-op implementations of {@link Tracer}. @@ -87,11 +87,11 @@ export class NoopTracer implements Tracer { fn = arg4 as F; } - const parentContext = ctx ?? context.active(); + const parentContext = ctx ?? contextApi.active(); const span = this.startSpan(name, opts, parentContext); const contextWithSpanSet = setSpan(parentContext, span); - return context.with(contextWithSpanSet, fn, undefined, span); + return contextApi.with(contextWithSpanSet, fn, undefined, span); } } diff --git a/api/test/api/api.test.ts b/api/test/api/api.test.ts index 4f51462a18..9b5570b763 100644 --- a/api/test/api/api.test.ts +++ b/api/test/api/api.test.ts @@ -56,7 +56,7 @@ describe('API', () => { const span = new NonRecordingSpan(); const ctx = trace.setSpan(ROOT_CONTEXT, span); context.setGlobalContextManager({ active: () => ctx, disable: () => {} } as any); - + const active = trace.getActiveSpan(); assert.strictEqual(active, span); diff --git a/api/test/diag/consoleLogger.test.ts b/api/test/diag/consoleLogger.test.ts index 2210a7c68b..fd57f11836 100644 --- a/api/test/diag/consoleLogger.test.ts +++ b/api/test/diag/consoleLogger.test.ts @@ -27,14 +27,14 @@ export const diagLoggerFunctions = [ 'error', ] as const; -const consoleFuncs: Array = [ +const consoleFuncs = [ 'debug', 'info', 'warn', 'error', 'log', 'trace', -]; +] as const; const expectedConsoleMap: { [n: string]: keyof Console } = { error: 'error', @@ -127,6 +127,7 @@ describe('DiagConsoleLogger', () => { consoleFuncs.forEach(cName => { it(`should log ${fName} message even when console doesn't support ${cName} call before construction`, () => { + // @ts-expect-error removing a console property is not allowed by types console[cName] = undefined; const consoleLogger: any = new DiagConsoleLogger(); consoleLogger[fName](`${fName} called %s`, 'param1'); @@ -142,6 +143,7 @@ describe('DiagConsoleLogger', () => { it(`should log ${fName} message even when console doesn't support ${cName} call after construction`, () => { const consoleLogger: any = new DiagConsoleLogger(); + // @ts-expect-error removing a console property is not allowed by types console[cName] = undefined; consoleLogger[fName](`${fName} called %s`, 'param1'); if (cName !== expectedConsoleMap[fName]) { diff --git a/api/test/index-webpack.ts b/api/test/index-webpack.ts index 061a48ccfa..856be100b2 100644 --- a/api/test/index-webpack.ts +++ b/api/test/index-webpack.ts @@ -13,8 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const testsContext = require.context('.', true, /test$/); -testsContext.keys().forEach(testsContext); +{ + const testsContext = require.context('.', true, /test$/); + testsContext.keys().forEach(testsContext); +} -const srcContext = require.context('.', true, /src$/); -srcContext.keys().forEach(srcContext); +{ + const srcContext = require.context('.', true, /src$/); + srcContext.keys().forEach(srcContext); +} diff --git a/api/test/index-webpack.worker.ts b/api/test/index-webpack.worker.ts new file mode 100644 index 0000000000..d568d570b1 --- /dev/null +++ b/api/test/index-webpack.worker.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ +{ + const testsContext = require.context('./', true, /test$/); + testsContext.keys().forEach(testsContext); +} diff --git a/api/tsconfig.all.json b/api/tsconfig.all.json new file mode 100644 index 0000000000..4aa747e89f --- /dev/null +++ b/api/tsconfig.all.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "references": [ + { "path": "./tsconfig.json" }, + { "path": "./tsconfig.esm.json" }, + { "path": "./tsconfig.esnext.json" } + ] +} diff --git a/api/tsconfig.esm.json b/api/tsconfig.esm.json new file mode 100644 index 0000000000..50611a86af --- /dev/null +++ b/api/tsconfig.esm.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.base.esm.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build/esm", + "tsBuildInfoFile": "build/esm/tsconfig.esm.tsbuildinfo" + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/api/tsconfig.esnext.json b/api/tsconfig.esnext.json new file mode 100644 index 0000000000..0e3427cbc1 --- /dev/null +++ b/api/tsconfig.esnext.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.base.esnext.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build/esnext", + "tsBuildInfoFile": "build/esnext/tsconfig.esnext.tsbuildinfo" + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/api/tsconfig.json b/api/tsconfig.json new file mode 100644 index 0000000000..088086278b --- /dev/null +++ b/api/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "build" + }, + "include": [ + "src/**/*.ts", + "test/**/*.ts" + ], + "references": [ + ] +} diff --git a/experimental/packages/api-logs/tsconfig.json b/experimental/packages/api-logs/tsconfig.json index ed9d0830bd..e22548584a 100644 --- a/experimental/packages/api-logs/tsconfig.json +++ b/experimental/packages/api-logs/tsconfig.json @@ -7,5 +7,10 @@ "include": [ "src/**/*.ts", "test/**/*.ts" + ], + "references": [ + { + "path": "../../../api" + } ] } diff --git a/experimental/packages/exporter-trace-otlp-grpc/tsconfig.json b/experimental/packages/exporter-trace-otlp-grpc/tsconfig.json index 94d47b6e19..abde2bfde9 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/tsconfig.json +++ b/experimental/packages/exporter-trace-otlp-grpc/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/exporter-trace-otlp-http/tsconfig.json b/experimental/packages/exporter-trace-otlp-http/tsconfig.json index 087c804079..bb73fd2a34 100644 --- a/experimental/packages/exporter-trace-otlp-http/tsconfig.json +++ b/experimental/packages/exporter-trace-otlp-http/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/exporter-trace-otlp-proto/tsconfig.json b/experimental/packages/exporter-trace-otlp-proto/tsconfig.json index 3324a8a529..9b6c50baef 100644 --- a/experimental/packages/exporter-trace-otlp-proto/tsconfig.json +++ b/experimental/packages/exporter-trace-otlp-proto/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-api-metrics/tsconfig.json b/experimental/packages/opentelemetry-api-metrics/tsconfig.json index ed9d0830bd..e22548584a 100644 --- a/experimental/packages/opentelemetry-api-metrics/tsconfig.json +++ b/experimental/packages/opentelemetry-api-metrics/tsconfig.json @@ -7,5 +7,10 @@ "include": [ "src/**/*.ts", "test/**/*.ts" + ], + "references": [ + { + "path": "../../../api" + } ] } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json index b6a4e45748..1be23dd8b2 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json index 132af2033a..1f981132ba 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json index be2921b2fd..63e825da3f 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json index b9a0327885..138ffc3aad 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-fetch/tsconfig.json index b228a2080a..9b921df4d9 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-fetch/tsconfig.json @@ -10,6 +10,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-context-zone" }, diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json index 8b4ba562f1..c21412396f 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-context-async-hooks" }, diff --git a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json index 034c613b3e..94828c26da 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-context-async-hooks" }, diff --git a/experimental/packages/opentelemetry-instrumentation-xml-http-request/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-xml-http-request/tsconfig.json index b228a2080a..9b921df4d9 100644 --- a/experimental/packages/opentelemetry-instrumentation-xml-http-request/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-xml-http-request/tsconfig.json @@ -10,6 +10,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-context-zone" }, diff --git a/experimental/packages/opentelemetry-instrumentation/tsconfig.json b/experimental/packages/opentelemetry-instrumentation/tsconfig.json index 948abef3ce..af53bd1755 100644 --- a/experimental/packages/opentelemetry-instrumentation/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../opentelemetry-api-metrics" } diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json index 53d44a09df..c56be210db 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json +++ b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-sdk-node/tsconfig.json b/experimental/packages/opentelemetry-sdk-node/tsconfig.json index 8249dd1ce6..3d1db30739 100644 --- a/experimental/packages/opentelemetry-sdk-node/tsconfig.json +++ b/experimental/packages/opentelemetry-sdk-node/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-context-async-hooks" }, diff --git a/experimental/packages/otlp-exporter-base/tsconfig.json b/experimental/packages/otlp-exporter-base/tsconfig.json index 3e284c16fc..fbb799ec14 100644 --- a/experimental/packages/otlp-exporter-base/tsconfig.json +++ b/experimental/packages/otlp-exporter-base/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" } diff --git a/experimental/packages/otlp-grpc-exporter-base/tsconfig.json b/experimental/packages/otlp-grpc-exporter-base/tsconfig.json index 087c804079..bb73fd2a34 100644 --- a/experimental/packages/otlp-grpc-exporter-base/tsconfig.json +++ b/experimental/packages/otlp-grpc-exporter-base/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/otlp-proto-exporter-base/tsconfig.json b/experimental/packages/otlp-proto-exporter-base/tsconfig.json index 3e05eef24c..b0fd3b0b55 100644 --- a/experimental/packages/otlp-proto-exporter-base/tsconfig.json +++ b/experimental/packages/otlp-proto-exporter-base/tsconfig.json @@ -11,6 +11,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/otlp-transformer/tsconfig.json b/experimental/packages/otlp-transformer/tsconfig.json index a396bcb48f..e06d7404a5 100644 --- a/experimental/packages/otlp-transformer/tsconfig.json +++ b/experimental/packages/otlp-transformer/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../../api" + }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/integration-tests/propagation-validation-server/tsconfig.json b/integration-tests/propagation-validation-server/tsconfig.json index eb74c6b4c6..7b374cea7b 100644 --- a/integration-tests/propagation-validation-server/tsconfig.json +++ b/integration-tests/propagation-validation-server/tsconfig.json @@ -6,6 +6,9 @@ }, "include": [], "references": [ + { + "path": "../../api" + }, { "path": "../../packages/opentelemetry-context-async-hooks" }, diff --git a/lerna.json b/lerna.json index 04c90d0ef0..5c0f76b9c2 100644 --- a/lerna.json +++ b/lerna.json @@ -2,6 +2,7 @@ "version": "independent", "npmClient": "npm", "packages": [ + "api", "packages/*", "experimental/packages/*", "experimental/backwards-compatability/*", diff --git a/packages/opentelemetry-context-async-hooks/tsconfig.json b/packages/opentelemetry-context-async-hooks/tsconfig.json index bdc94d2213..b1ea0838e6 100644 --- a/packages/opentelemetry-context-async-hooks/tsconfig.json +++ b/packages/opentelemetry-context-async-hooks/tsconfig.json @@ -7,5 +7,10 @@ "include": [ "src/**/*.ts", "test/**/*.ts" + ], + "references": [ + { + "path": "../../api" + } ] } diff --git a/packages/opentelemetry-context-zone-peer-dep/tsconfig.json b/packages/opentelemetry-context-zone-peer-dep/tsconfig.json index 479d4bc0d2..da6d2b6486 100644 --- a/packages/opentelemetry-context-zone-peer-dep/tsconfig.json +++ b/packages/opentelemetry-context-zone-peer-dep/tsconfig.json @@ -11,5 +11,10 @@ "include": [ "src/**/*.ts", "test/**/*.ts" + ], + "references": [ + { + "path": "../../api" + } ] } diff --git a/packages/opentelemetry-core/tsconfig.json b/packages/opentelemetry-core/tsconfig.json index 0717beecbf..101baf4195 100644 --- a/packages/opentelemetry-core/tsconfig.json +++ b/packages/opentelemetry-core/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-semantic-conventions" } diff --git a/packages/opentelemetry-exporter-jaeger/tsconfig.json b/packages/opentelemetry-exporter-jaeger/tsconfig.json index 8b45d214a9..ce2661c050 100644 --- a/packages/opentelemetry-exporter-jaeger/tsconfig.json +++ b/packages/opentelemetry-exporter-jaeger/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-core" }, diff --git a/packages/opentelemetry-exporter-zipkin/tsconfig.json b/packages/opentelemetry-exporter-zipkin/tsconfig.json index 8b45d214a9..ce2661c050 100644 --- a/packages/opentelemetry-exporter-zipkin/tsconfig.json +++ b/packages/opentelemetry-exporter-zipkin/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-core" }, diff --git a/packages/opentelemetry-propagator-b3/tsconfig.json b/packages/opentelemetry-propagator-b3/tsconfig.json index 789e61fc86..f60209f8c4 100644 --- a/packages/opentelemetry-propagator-b3/tsconfig.json +++ b/packages/opentelemetry-propagator-b3/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-core" } diff --git a/packages/opentelemetry-propagator-jaeger/tsconfig.json b/packages/opentelemetry-propagator-jaeger/tsconfig.json index a6c0bb2617..a942b2b6aa 100644 --- a/packages/opentelemetry-propagator-jaeger/tsconfig.json +++ b/packages/opentelemetry-propagator-jaeger/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-core" } diff --git a/packages/opentelemetry-resources/tsconfig.json b/packages/opentelemetry-resources/tsconfig.json index 51dcc3ed88..bbd7dbbe43 100644 --- a/packages/opentelemetry-resources/tsconfig.json +++ b/packages/opentelemetry-resources/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-core" }, diff --git a/packages/opentelemetry-sdk-trace-base/tsconfig.json b/packages/opentelemetry-sdk-trace-base/tsconfig.json index b16c7037b4..fa14714abd 100644 --- a/packages/opentelemetry-sdk-trace-base/tsconfig.json +++ b/packages/opentelemetry-sdk-trace-base/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-core" }, diff --git a/packages/opentelemetry-sdk-trace-node/tsconfig.json b/packages/opentelemetry-sdk-trace-node/tsconfig.json index 5894551b3d..837d89d421 100644 --- a/packages/opentelemetry-sdk-trace-node/tsconfig.json +++ b/packages/opentelemetry-sdk-trace-node/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-context-async-hooks" }, diff --git a/packages/opentelemetry-sdk-trace-web/tsconfig.json b/packages/opentelemetry-sdk-trace-web/tsconfig.json index f317cb38d1..09ac19a176 100644 --- a/packages/opentelemetry-sdk-trace-web/tsconfig.json +++ b/packages/opentelemetry-sdk-trace-web/tsconfig.json @@ -10,6 +10,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-context-zone" }, diff --git a/packages/opentelemetry-shim-opentracing/tsconfig.json b/packages/opentelemetry-shim-opentracing/tsconfig.json index a256765295..0e01f63184 100644 --- a/packages/opentelemetry-shim-opentracing/tsconfig.json +++ b/packages/opentelemetry-shim-opentracing/tsconfig.json @@ -9,6 +9,9 @@ "test/**/*.ts" ], "references": [ + { + "path": "../../api" + }, { "path": "../opentelemetry-core" }, diff --git a/tsconfig.json b/tsconfig.json index 9f3cd60df8..10419db907 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,7 @@ "typedocOptions": { "entryPointStrategy": "packages", "entryPoints": [ + "api", "experimental/packages/exporter-trace-otlp-grpc", "experimental/packages/exporter-trace-otlp-http", "experimental/packages/exporter-trace-otlp-proto", @@ -49,6 +50,9 @@ "excludePrivate": true }, "references": [ + { + "path": "api" + }, { "path": "packages/opentelemetry-context-async-hooks" }, From afe065772360d3acec8b8fc15e20536fd896c6c6 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Sat, 24 Sep 2022 09:25:20 +0200 Subject: [PATCH 32/77] docs(metrics-exporters): fix wrong exporter const name in example (#3271) --- experimental/CHANGELOG.md | 2 ++ .../packages/opentelemetry-exporter-metrics-otlp-grpc/README.md | 2 +- .../packages/opentelemetry-exporter-metrics-otlp-http/README.md | 2 +- .../opentelemetry-exporter-metrics-otlp-proto/README.md | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index d62009288d..1c77eafbad 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -12,6 +12,8 @@ All notable changes to experimental packages in this project will be documented ### :books: (Refine Doc) +* docs(metrics-exporters): fix wrong exporter const name in example [#3270](https://github.com/open-telemetry/opentelemetry-js/issues/3270) @pichlermarc + ### :house: (Internal) ## 0.33.0 diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md index 02f25fc855..e00bf05e41 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md @@ -32,7 +32,7 @@ const collectorOptions = { url: 'http://:', }; -const exporter = new OTLPMetricExporter(collectorOptions); +const metricExporter = new OTLPMetricExporter(collectorOptions); const meterProvider = new MeterProvider({}); meterProvider.addMetricReader(new PeriodicExportingMetricReader({ diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md index 28fa70613b..d495e53b38 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md @@ -32,7 +32,7 @@ const collectorOptions = { headers: {}, // an optional object containing custom headers to be sent with each request concurrencyLimit: 1, // an optional limit on pending requests }; -const exporter = new OTLPMetricExporter(collectorOptions); +const metricExporter = new OTLPMetricExporter(collectorOptions); const meterProvider = new MeterProvider({}); meterProvider.addMetricReader(new PeriodicExportingMetricReader({ diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md index 1c1c115d48..a5d812236d 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md @@ -28,7 +28,7 @@ const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-pr const collectorOptions = { url: '', // url is optional and can be omitted - default is http://localhost:4318/v1/metrics }; -const exporter = new OTLPMetricExporter(collectorOptions); +const metricExporter = new OTLPMetricExporter(collectorOptions); const meterProvider = new MeterProvider({}); meterProvider.addMetricReader(new PeriodicExportingMetricReader({ From 6b8bb15ab5d91094d328ab543595b8d7ea768e23 Mon Sep 17 00:00:00 2001 From: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> Date: Thu, 29 Sep 2022 01:48:11 -0500 Subject: [PATCH 33/77] feat(sdk-node): configure trace exporter with environment variables (#3143) * feat(sdk-node): wip add functionality to retrieve list of exporters Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): wip add functionality to configure otlp Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): wip add otlp protocol retrieval Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): wip configure span processor Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): wip create node tracer providers Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add otlp exporter tests Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): refactor otlp protocol logic Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): refactor configure exporter function Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add zipkin and jaeger exporters and tests Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add console exporter and tests Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add console exporter and tests Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): handle invalid exporters case Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix tests failing due to newly added feature Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add more unit tests Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add changelog Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add documentation to readme Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add comments to public methods Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add integration tests Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix lint Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix lint in readme Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix lint in readme Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): refactor to use class for tracer with env exporters Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix lint Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): refactor sdk class and tests Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix typo Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix typo Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix metric test Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix lint and refactor Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix lint Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * Rename tracerProviderWithEnvExporter.ts to TracerProviderWithEnvExporter.ts * feat(sdk-node): move adding span processors to different class Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add more tests and reconfigure some tests Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add missing env value deletion after test Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): fix lint Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): override register method and upate logic and tests Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): add override for addspanprocessor method Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * feat(sdk-node): undo accidental changelog removal Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> * Undo accidental empty change heading Signed-off-by: Svetlana Brennan <50715937+svetlanabrennan@users.noreply.github.com> Co-authored-by: Valentin Marchaud --- experimental/CHANGELOG.md | 2 + .../packages/opentelemetry-sdk-node/README.md | 26 +- .../opentelemetry-sdk-node/package.json | 5 + .../src/TracerProviderWithEnvExporter.ts | 124 ++++++++ .../opentelemetry-sdk-node/src/sdk.ts | 29 +- .../TracerProviderWithEnvExporter.test.ts | 283 ++++++++++++++++++ .../opentelemetry-sdk-node/test/sdk.test.ts | 195 +++++++++++- .../opentelemetry-sdk-node/tsconfig.json | 15 + .../src/utils/environment.ts | 12 +- 9 files changed, 672 insertions(+), 19 deletions(-) create mode 100644 experimental/packages/opentelemetry-sdk-node/src/TracerProviderWithEnvExporter.ts create mode 100644 experimental/packages/opentelemetry-sdk-node/test/TracerProviderWithEnvExporter.test.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 1c77eafbad..04482240f8 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -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) diff --git a/experimental/packages/opentelemetry-sdk-node/README.md b/experimental/packages/opentelemetry-sdk-node/README.md index 97027ff7fb..0d4f3c0f7a 100644 --- a/experimental/packages/opentelemetry-sdk-node/README.md +++ b/experimental/packages/opentelemetry-sdk-node/README.md @@ -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 @@ -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: diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index 8bc140b685..d4f0f48a38 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -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", diff --git a/experimental/packages/opentelemetry-sdk-node/src/TracerProviderWithEnvExporter.ts b/experimental/packages/opentelemetry-sdk-node/src/TracerProviderWithEnvExporter.ts new file mode 100644 index 0000000000..f4abb593ab --- /dev/null +++ b/experimental/packages/opentelemetry-sdk-node/src/TracerProviderWithEnvExporter.ts @@ -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 !== ''); + } +} diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts index a48028760b..bb20ed9440 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts @@ -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 */ @@ -64,7 +65,7 @@ export class NodeSDK { private _autoDetectResources: boolean; - private _tracerProvider?: NodeTracerProvider; + private _tracerProvider?: NodeTracerProvider | TracerProviderWithEnvExporters; private _meterProvider?: MeterProvider; private _serviceName?: string; @@ -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, diff --git a/experimental/packages/opentelemetry-sdk-node/test/TracerProviderWithEnvExporter.test.ts b/experimental/packages/opentelemetry-sdk-node/test/TracerProviderWithEnvExporter.test.ts new file mode 100644 index 0000000000..2ba4d0394a --- /dev/null +++ b/experimental/packages/opentelemetry-sdk-node/test/TracerProviderWithEnvExporter.test.ts @@ -0,0 +1,283 @@ +/* + * 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 { + ConsoleSpanExporter, + SimpleSpanProcessor, + BatchSpanProcessor, +} from '@opentelemetry/sdk-trace-base'; +import * as assert from 'assert'; +import * as Sinon from 'sinon'; +import { env } from 'process'; +import { OTLPTraceExporter as OTLPProtoTraceExporter, OTLPTraceExporter } 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'; +import { TracerProviderWithEnvExporters } from '../src/TracerProviderWithEnvExporter'; + +describe('set up trace exporter with env exporters', () => { + let spyGetOtlpProtocol: Sinon.SinonSpy; + let stubLoggerError: Sinon.SinonStub; + + beforeEach(() => { + spyGetOtlpProtocol = Sinon.spy(TracerProviderWithEnvExporters, 'getOtlpProtocol'); + stubLoggerError = Sinon.stub(diag, 'warn'); + }); + afterEach(() => { + spyGetOtlpProtocol.restore(); + stubLoggerError.restore(); + }); + describe('setup otlp exporter from env', () => { + it('set up default exporter when user does not define otel trace exporter', async () => { + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(spyGetOtlpProtocol.returned('http/protobuf')); + assert(listOfExporters.length === 1); + assert(listOfExporters[0] instanceof OTLPProtoTraceExporter); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + }); + it('use otlp exporter and grpc exporter protocol env value', async () => { + env.OTEL_TRACES_EXPORTER = 'otlp'; + env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'grpc'; + + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(spyGetOtlpProtocol.returned('grpc')); + assert(listOfExporters.length === 1); + assert(listOfExporters[0] instanceof OTLPGrpcTraceExporter); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + + delete env.OTEL_TRACES_EXPORTER; + delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + }); + it('sdk will ignore protocol defined with no-signal env and use signal specific protocol instead', async () => { + env.OTEL_TRACES_EXPORTER = 'otlp'; + env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'http/protobuf'; + env.OTEL_EXPORTER_OTLP_PROTOCOL = 'grpc'; + + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(spyGetOtlpProtocol.returned('http/protobuf')); + assert(listOfExporters.length === 1); + assert(listOfExporters[0] instanceof OTLPTraceExporter); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + + delete env.OTEL_TRACES_EXPORTER; + delete env.OTEL_EXPORTER_OTLP_PROTOCOL; + delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + }); + it('do not use any exporters when empty value is provided for exporter', async () => { + env.OTEL_TRACES_EXPORTER = ''; + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']; + const listOfExporters = sdk['_configuredExporters']; + + assert(spyGetOtlpProtocol.notCalled); + assert(listOfExporters.length === 0); + assert(listOfProcessors === undefined); + env.OTEL_TRACES_EXPORTER = ''; + }); + it('do not use any exporters when none value is only provided', async () => { + env.OTEL_TRACES_EXPORTER = 'none'; + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']; + const listOfExporters = sdk['_configuredExporters']; + + assert(spyGetOtlpProtocol.notCalled); + assert(listOfExporters.length === 0); + assert(listOfProcessors === undefined); + delete env.OTEL_TRACES_EXPORTER; + }); + it('log warning that sdk will not be initalized when exporter is set to none', async () => { + env.OTEL_TRACES_EXPORTER = 'none'; + new TracerProviderWithEnvExporters(); + + assert.strictEqual(stubLoggerError.args[0][0], 'OTEL_TRACES_EXPORTER contains "none" or is empty. SDK will not be initialized.'); + delete env.OTEL_TRACES_EXPORTER; + }); + it('use default exporter when none value is provided with other exports', async () => { + env.OTEL_TRACES_EXPORTER = 'otlp,zipkin,none'; + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(listOfExporters[0] instanceof OTLPProtoTraceExporter); + assert(listOfExporters.length === 1); + assert(listOfExporters[0] instanceof OTLPHttpTraceExporter === false); + assert(listOfExporters[0] instanceof ZipkinExporter === false); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + delete env.OTEL_TRACES_EXPORTER; + }); + it('log warning that default exporter will be used since exporter list contains none with other exports ', async () => { + env.OTEL_TRACES_EXPORTER = 'otlp,zipkin,none'; + new TracerProviderWithEnvExporters(); + + assert.strictEqual( + stubLoggerError.args[0][0], 'OTEL_TRACES_EXPORTER contains "none" along with other exporters. Using default otlp exporter.' + ); + delete env.OTEL_TRACES_EXPORTER; + }); + it('should warn that exporter is unrecognized and not able to be set up', async () => { + env.OTEL_TRACES_EXPORTER = 'invalid'; + new TracerProviderWithEnvExporters(); + + assert.strictEqual( + stubLoggerError.args[0][0], 'Unrecognized OTEL_TRACES_EXPORTER value: invalid.' + ); + + assert.strictEqual( + stubLoggerError.args[1][0], 'Unable to set up trace exporter(s) due to invalid exporter and/or protocol values.' + ); + + delete env.OTEL_TRACES_EXPORTER; + }); + it('should log warning when provided protocol name is not valid', async () => { + env.OTEL_EXPORTER_OTLP_PROTOCOL = 'invalid'; + new TracerProviderWithEnvExporters(); + + assert.strictEqual( + stubLoggerError.args[0][0], 'Unsupported OTLP traces protocol: invalid. Using http/protobuf.' + ); + delete env.OTEL_EXPORTER_OTLP_PROTOCOL; + }); + }); + describe('setup zipkin exporter from env', () => { + it('use the zipkin exporter', async () => { + env.OTEL_TRACES_EXPORTER = 'zipkin'; + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(listOfExporters.length === 1); + assert(listOfExporters[0] instanceof ZipkinExporter); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + delete env.OTEL_TRACES_EXPORTER; + }); + it('setup zipkin exporter and otlp exporter', async () => { + env.OTEL_TRACES_EXPORTER = 'zipkin, otlp'; + env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'grpc'; + + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(spyGetOtlpProtocol.returned('grpc')); + assert(listOfExporters.length === 2); + assert(listOfExporters[0] instanceof ZipkinExporter); + assert(listOfExporters[1] instanceof OTLPGrpcTraceExporter); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + assert(listOfProcessors[1] instanceof BatchSpanProcessor); + + delete env.OTEL_TRACES_EXPORTER; + delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + }); + }); + describe('setup jaeger exporter from env', () => { + it('use the jaeger exporter', async () => { + env.OTEL_TRACES_EXPORTER = 'jaeger'; + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(listOfExporters.length === 1); + assert(listOfExporters[0] instanceof JaegerExporter); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + delete env.OTEL_TRACES_EXPORTER; + }); + it('setup jaeger exporter and otlp exporter', async () => { + env.OTEL_TRACES_EXPORTER = 'jaeger, otlp'; + env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'http/json'; + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(spyGetOtlpProtocol.returned('http/json')); + assert(listOfExporters.length === 2); + assert(listOfExporters[0] instanceof JaegerExporter); + assert(listOfExporters[1] instanceof OTLPHttpTraceExporter); + assert(listOfProcessors.length === 2); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + assert(listOfProcessors[1] instanceof BatchSpanProcessor); + + delete env.OTEL_TRACES_EXPORTER; + delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + }); + }); + describe('setup console exporter from env', () => { + it('use the console exporter', async () => { + env.OTEL_TRACES_EXPORTER = 'console'; + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(listOfExporters.length === 1); + assert(listOfExporters[0] instanceof ConsoleSpanExporter); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof SimpleSpanProcessor); + delete env.OTEL_TRACES_EXPORTER; + }); + it('ignores the protocol', async () => { + env.OTEL_TRACES_EXPORTER = 'console'; + env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'grpc'; + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(spyGetOtlpProtocol.notCalled); + assert(listOfExporters.length === 1); + assert(listOfExporters[0] instanceof ConsoleSpanExporter); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof SimpleSpanProcessor); + + delete env.OTEL_TRACES_EXPORTER; + delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + }); + it('setup console exporter and otlp exporter', async () => { + env.OTEL_TRACES_EXPORTER = 'console, otlp'; + env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'grpc'; + const sdk = new TracerProviderWithEnvExporters(); + const listOfProcessors = sdk['_spanProcessors']!; + const listOfExporters = sdk['_configuredExporters']; + + assert(spyGetOtlpProtocol.returned('grpc')); + assert(listOfExporters.length === 2); + assert(listOfExporters[0] instanceof ConsoleSpanExporter); + assert(listOfExporters[1] instanceof OTLPGrpcTraceExporter); + assert(listOfProcessors.length === 2); + assert(listOfProcessors[0] instanceof SimpleSpanProcessor); + assert(listOfProcessors[1] instanceof BatchSpanProcessor); + + delete env.OTEL_TRACES_EXPORTER; + delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + }); + }); +}); diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index c1b0b90d56..12a3833744 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -44,17 +44,21 @@ import { import { ConsoleSpanExporter, SimpleSpanProcessor, + BatchSpanProcessor, + NoopSpanProcessor, } from '@opentelemetry/sdk-trace-base'; import * as assert from 'assert'; import * as semver from 'semver'; import * as Sinon from 'sinon'; import { NodeSDK } from '../src'; +import { env } from 'process'; +import { TracerProviderWithEnvExporters } from '../src/TracerProviderWithEnvExporter'; import { envDetector, processDetector, Resource } from '@opentelemetry/resources'; - +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; const DefaultContextManager = semver.gte(process.version, '14.8.0') ? AsyncLocalStorageContextManager @@ -78,6 +82,9 @@ describe('Node SDK', () => { describe('Basic Registration', () => { it('should not register any unconfigured SDK components', async () => { + // need to set OTEL_TRACES_EXPORTER to none since default value is otlp + // which sets up an exporter and affects the context manager + env.OTEL_TRACES_EXPORTER = 'none'; const sdk = new NodeSDK({ autoDetectResources: false, }); @@ -87,8 +94,8 @@ describe('Node SDK', () => { assert.strictEqual(context['_getContextManager'](), ctxManager, 'context manager should not change'); assert.strictEqual(propagation['_getGlobalPropagator'](), propagator, 'propagator should not change'); assert.strictEqual((trace.getTracerProvider() as ProxyTracerProvider).getDelegate(), delegate, 'tracer provider should not have changed'); - assert.ok(!(metrics.getMeterProvider() instanceof MeterProvider)); + delete env.OTEL_TRACES_EXPORTER; }); it('should register a tracer provider if an exporter is provided', async () => { @@ -135,6 +142,9 @@ describe('Node SDK', () => { }); it('should register a meter provider if a reader is provided', async () => { + // need to set OTEL_TRACES_EXPORTER to none since default value is otlp + // which sets up an exporter and affects the context manager + env.OTEL_TRACES_EXPORTER = 'none'; const exporter = new ConsoleMetricExporter(); const metricReader = new PeriodicExportingMetricReader({ exporter: exporter, @@ -156,6 +166,7 @@ describe('Node SDK', () => { assert.ok(metrics.getMeterProvider() instanceof MeterProvider); await sdk.shutdown(); + delete env.OTEL_TRACES_EXPORTER; }); }); @@ -173,6 +184,9 @@ describe('Node SDK', () => { } it('should register meter views when provided', async () => { + // need to set OTEL_TRACES_EXPORTER to none since default value is otlp + // which sets up an exporter and affects the context manager + env.OTEL_TRACES_EXPORTER = 'none'; const exporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE); const metricReader = new PeriodicExportingMetricReader({ exporter: exporter, @@ -219,6 +233,7 @@ describe('Node SDK', () => { assert.ok(firstMetricRecord.descriptor.name === 'test-view', 'should have renamed counter metric'); await sdk.shutdown(); + delete env.OTEL_TRACES_EXPORTER; }); it('should throw error when calling configureMeterProvider when views are already configured', () => { @@ -471,7 +486,6 @@ describe('Node SDK', () => { delete process.env.OTEL_SERVICE_NAME; }); - it('should configure service name via OTEL_RESOURCE_ATTRIBUTES env var', async () => { process.env.OTEL_RESOURCE_ATTRIBUTES = 'service.name=resource-env-set-name'; const sdk = new NodeSDK(); @@ -501,3 +515,178 @@ describe('Node SDK', () => { }); }); }); + +describe('setup exporter from env', () => { + let spyGetOtlpProtocol: Sinon.SinonSpy; + let stubLoggerError: Sinon.SinonStub; + + beforeEach(() => { + spyGetOtlpProtocol = Sinon.spy(TracerProviderWithEnvExporters, 'getOtlpProtocol'); + stubLoggerError = Sinon.stub(diag, 'warn'); + }); + afterEach(() => { + spyGetOtlpProtocol.restore(); + stubLoggerError.restore(); + }); + it('use default exporter TracerProviderWithEnvExporters when user does not provide span processor or trace exporter to sdk config', async () => { + const sdk = new NodeSDK(); + await sdk.start(); + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + + assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + }); + it('ignore env exporter when user provides exporter to sdk config', async () => { + const traceExporter = new ConsoleSpanExporter(); + const sdk = new NodeSDK({ + traceExporter + }); + await sdk.start(); + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + + assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters === false); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof SimpleSpanProcessor === false); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + }); + it('ignores default env exporter when user provides span processor to sdk config', async () => { + const traceExporter = new ConsoleSpanExporter(); + const spanProcessor = new SimpleSpanProcessor(traceExporter); + const sdk = new NodeSDK({ + spanProcessor + }); + await sdk.start(); + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + + assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters === false); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof SimpleSpanProcessor); + assert(listOfProcessors[0] instanceof BatchSpanProcessor === false); + }); + it('ignores env exporter when user provides tracer exporter to sdk config and sets exporter via env', async () => { + env.OTEL_TRACES_EXPORTER = 'console'; + const traceExporter = new OTLPTraceExporter(); + const sdk = new NodeSDK({ + traceExporter + }); + await sdk.start(); + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + + assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters === false); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof SimpleSpanProcessor === false); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + delete env.OTEL_TRACES_EXPORTER; + }); + it('use otlp exporter and defined exporter protocol env value', async () => { + env.OTEL_TRACES_EXPORTER = 'otlp'; + env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'grpc'; + const sdk = new NodeSDK(); + await sdk.start(); + + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + delete env.OTEL_TRACES_EXPORTER; + delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + }); + it('use noop span processor when user sets env exporter to none', async () => { + env.OTEL_TRACES_EXPORTER = 'none'; + const sdk = new NodeSDK(); + await sdk.start(); + + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + const activeProcessor = sdk['_tracerProvider']?.getActiveSpanProcessor(); + + assert(listOfProcessors.length === 0); + assert(activeProcessor instanceof NoopSpanProcessor); + delete env.OTEL_TRACES_EXPORTER; + }); + it('log warning that sdk will not be initalized when exporter is set to none', async () => { + env.OTEL_TRACES_EXPORTER = 'none'; + const sdk = new NodeSDK(); + await sdk.start(); + + assert.strictEqual(stubLoggerError.args[0][0], 'OTEL_TRACES_EXPORTER contains "none" or is empty. SDK will not be initialized.'); + delete env.OTEL_TRACES_EXPORTER; + }); + it('do not use any exporters when empty value is provided for exporter', async () => { + env.OTEL_TRACES_EXPORTER = ''; + const sdk = new NodeSDK(); + await sdk.start(); + + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + const activeProcessor = sdk['_tracerProvider']?.getActiveSpanProcessor(); + + assert(listOfProcessors.length === 0); + assert(activeProcessor instanceof NoopSpanProcessor); + env.OTEL_TRACES_EXPORTER = ''; + }); + + it('use only default exporter when none value is provided with other exporters', async () => { + env.OTEL_TRACES_EXPORTER = 'otlp,zipkin,none'; + const sdk = new NodeSDK(); + await sdk.start(); + + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters); + assert(listOfProcessors.length === 1); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + + delete env.OTEL_TRACES_EXPORTER; + }); + it('log warning that only default exporter will be used since exporter list contains none with other exports ', async () => { + env.OTEL_TRACES_EXPORTER = 'otlp,zipkin,none'; + const sdk = new NodeSDK(); + await sdk.start(); + + assert.strictEqual( + stubLoggerError.args[0][0], 'OTEL_TRACES_EXPORTER contains "none" along with other exporters. Using default otlp exporter.' + ); + delete env.OTEL_TRACES_EXPORTER; + }); + it('should warn that provided exporter value is unrecognized and not able to be set up', async () => { + env.OTEL_TRACES_EXPORTER = 'invalid'; + const sdk = new NodeSDK(); + await sdk.start(); + + assert.strictEqual( + stubLoggerError.args[0][0], 'Unrecognized OTEL_TRACES_EXPORTER value: invalid.' + ); + + assert.strictEqual( + stubLoggerError.args[1][0], 'Unable to set up trace exporter(s) due to invalid exporter and/or protocol values.' + ); + + delete env.OTEL_TRACES_EXPORTER; + }); + it('setup zipkin, jaeger and otlp exporters', async () => { + env.OTEL_TRACES_EXPORTER = 'zipkin, otlp, jaeger'; + env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'grpc'; + const sdk = new NodeSDK(); + await sdk.start(); + + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + assert(sdk['_tracerProvider'] instanceof TracerProviderWithEnvExporters); + assert(listOfProcessors.length === 3); + assert(listOfProcessors[0] instanceof BatchSpanProcessor); + assert(listOfProcessors[1] instanceof BatchSpanProcessor); + assert(listOfProcessors[2] instanceof BatchSpanProcessor); + + delete env.OTEL_TRACES_EXPORTER; + delete env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL; + }); + it('use the console exporter', async () => { + env.OTEL_TRACES_EXPORTER = 'console, otlp'; + const sdk = new NodeSDK(); + await sdk.start(); + + const listOfProcessors = sdk['_tracerProvider']!['_registeredSpanProcessors']!; + assert(listOfProcessors.length === 2); + assert(listOfProcessors[0] instanceof SimpleSpanProcessor); + assert(listOfProcessors[1] instanceof BatchSpanProcessor); + delete env.OTEL_TRACES_EXPORTER; + }); +}); diff --git a/experimental/packages/opentelemetry-sdk-node/tsconfig.json b/experimental/packages/opentelemetry-sdk-node/tsconfig.json index 3d1db30739..55448ab788 100644 --- a/experimental/packages/opentelemetry-sdk-node/tsconfig.json +++ b/experimental/packages/opentelemetry-sdk-node/tsconfig.json @@ -18,6 +18,12 @@ { "path": "../../../packages/opentelemetry-core" }, + { + "path": "../../../packages/opentelemetry-exporter-jaeger" + }, + { + "path": "../../../packages/opentelemetry-exporter-zipkin" + }, { "path": "../../../packages/opentelemetry-resources" }, @@ -30,6 +36,15 @@ { "path": "../../../packages/opentelemetry-semantic-conventions" }, + { + "path": "../exporter-trace-otlp-grpc" + }, + { + "path": "../exporter-trace-otlp-http" + }, + { + "path": "../exporter-trace-otlp-proto" + }, { "path": "../opentelemetry-api-metrics" }, diff --git a/packages/opentelemetry-core/src/utils/environment.ts b/packages/opentelemetry-core/src/utils/environment.ts index 05ba058f0f..8d50e2cb9b 100644 --- a/packages/opentelemetry-core/src/utils/environment.ts +++ b/packages/opentelemetry-core/src/utils/environment.ts @@ -102,7 +102,10 @@ export type ENVIRONMENT = { OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY?: string, OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE?: string, OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE?: string, - OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE?: string + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE?: string, + OTEL_EXPORTER_OTLP_PROTOCOL?: string, + OTEL_EXPORTER_OTLP_TRACES_PROTOCOL?: string, + OTEL_EXPORTER_OTLP_METRICS_PROTOCOL?: string, } & ENVIRONMENT_NUMBERS & ENVIRONMENT_LISTS; @@ -154,7 +157,7 @@ export const DEFAULT_ENVIRONMENT: Required = { OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT: DEFAULT_ATTRIBUTE_COUNT_LIMIT, OTEL_SPAN_EVENT_COUNT_LIMIT: 128, OTEL_SPAN_LINK_COUNT_LIMIT: 128, - OTEL_TRACES_EXPORTER: 'none', + OTEL_TRACES_EXPORTER: 'otlp', OTEL_TRACES_SAMPLER: TracesSamplerValues.ParentBasedAlwaysOn, OTEL_TRACES_SAMPLER_ARG: '', OTEL_EXPORTER_OTLP_INSECURE: '', @@ -171,7 +174,10 @@ export const DEFAULT_ENVIRONMENT: Required = { OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY: '', OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: '', OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE: '', - OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE: '' + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE: '', + OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf', + OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: 'http/protobuf', + OTEL_EXPORTER_OTLP_METRICS_PROTOCOL: 'http/protobuf', }; /** From e91cac503c0bab95b429ff3c4b23249653882054 Mon Sep 17 00:00:00 2001 From: Marc Hassan Date: Fri, 30 Sep 2022 01:55:09 -0400 Subject: [PATCH 34/77] fix(node-sdk): move `@opentelemetry/semantic-conventions` to `dependencies` (#3283) Co-authored-by: Valentin Marchaud --- experimental/CHANGELOG.md | 2 ++ experimental/packages/opentelemetry-sdk-node/package.json | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 04482240f8..1c4a3fd8ed 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -12,6 +12,8 @@ All notable changes to experimental packages in this project will be documented ### :bug: (Bug Fix) +* fix(node-sdk): move `@opentelemetry/semantic-conventions` to `dependencies` [#3283](https://github.com/open-telemetry/opentelemetry-js/pull/3283) @mhassan1 + ### :books: (Refine Doc) * docs(metrics-exporters): fix wrong exporter const name in example [#3270](https://github.com/open-telemetry/opentelemetry-js/issues/3270) @pichlermarc diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index d4f0f48a38..763e1be9aa 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -55,7 +55,8 @@ "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-metrics": "0.33.0", "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/sdk-trace-node": "1.7.0" + "@opentelemetry/sdk-trace-node": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0" @@ -63,7 +64,6 @@ "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", "@opentelemetry/context-async-hooks": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0", "@types/mocha": "9.1.1", "@types/node": "18.6.5", "@types/semver": "7.3.9", From 1864a9a50c66024c2b78452d3ea6f691dd83692d Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Wed, 5 Oct 2022 17:26:15 +0200 Subject: [PATCH 35/77] fix(exporters): do not append trailing '/' when URL contains path (#3274) --- experimental/CHANGELOG.md | 1 + .../src/platform/browser/OTLPTraceExporter.ts | 2 +- .../src/platform/node/OTLPTraceExporter.ts | 2 +- .../src/OTLPTraceExporter.ts | 2 +- .../platform/browser/OTLPMetricExporter.ts | 2 +- .../src/platform/node/OTLPMetricExporter.ts | 2 +- .../src/OTLPMetricExporter.ts | 2 +- .../packages/otlp-exporter-base/src/util.ts | 17 +++++++---- .../test/common/util.test.ts | 30 +++++++++++++------ 9 files changed, 39 insertions(+), 21 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 1c4a3fd8ed..f14d274c65 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to experimental packages in this project will be documented ### :bug: (Bug Fix) * fix(node-sdk): move `@opentelemetry/semantic-conventions` to `dependencies` [#3283](https://github.com/open-telemetry/opentelemetry-js/pull/3283) @mhassan1 +* fix(exporters): do not append trailing '/' when URL contains path [#3274](https://github.com/open-telemetry/opentelemetry-js/pull/3274) @pichlermarc ### :books: (Refine Doc) diff --git a/experimental/packages/exporter-trace-otlp-http/src/platform/browser/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-http/src/platform/browser/OTLPTraceExporter.ts index ff478ead7c..ec12def8f2 100644 --- a/experimental/packages/exporter-trace-otlp-http/src/platform/browser/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-http/src/platform/browser/OTLPTraceExporter.ts @@ -53,7 +53,7 @@ export class OTLPTraceExporter return typeof config.url === 'string' ? config.url : getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT.length > 0 - ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) + ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) : getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0 ? appendResourcePathToUrl(getEnv().OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) : DEFAULT_COLLECTOR_URL; diff --git a/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts index aeec62259b..528a2735c3 100644 --- a/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-http/src/platform/node/OTLPTraceExporter.ts @@ -52,7 +52,7 @@ export class OTLPTraceExporter return typeof config.url === 'string' ? config.url : getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT.length > 0 - ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) + ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) : getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0 ? appendResourcePathToUrl(getEnv().OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) : DEFAULT_COLLECTOR_URL; diff --git a/experimental/packages/exporter-trace-otlp-proto/src/OTLPTraceExporter.ts b/experimental/packages/exporter-trace-otlp-proto/src/OTLPTraceExporter.ts index f523110024..d5c40a8214 100644 --- a/experimental/packages/exporter-trace-otlp-proto/src/OTLPTraceExporter.ts +++ b/experimental/packages/exporter-trace-otlp-proto/src/OTLPTraceExporter.ts @@ -54,7 +54,7 @@ export class OTLPTraceExporter return typeof config.url === 'string' ? config.url : getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT.length > 0 - ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) + ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) : getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0 ? appendResourcePathToUrl(getEnv().OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) : DEFAULT_COLLECTOR_URL; diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts index 2a7b14d219..afc42de108 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts @@ -45,7 +45,7 @@ class OTLPExporterBrowserProxy extends OTLPExporterBrowserBase 0 - ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) + ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_METRICS_ENDPOINT) : getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0 ? appendResourcePathToUrl(getEnv().OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) : DEFAULT_COLLECTOR_URL; diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts index 2008b88662..579fe95696 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts @@ -49,7 +49,7 @@ class OTLPExporterNodeProxy extends OTLPExporterNodeBase 0 - ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) + ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_METRICS_ENDPOINT) : getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0 ? appendResourcePathToUrl(getEnv().OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) : DEFAULT_COLLECTOR_URL; diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts index dec361e522..e3d8a60155 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts @@ -52,7 +52,7 @@ class OTLPMetricExporterNodeProxy extends OTLPProtoExporterNodeBase 0 - ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) + ? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_METRICS_ENDPOINT) : getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0 ? appendResourcePathToUrl(getEnv().OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_COLLECTOR_RESOURCE_PATH) : DEFAULT_COLLECTOR_URL; diff --git a/experimental/packages/otlp-exporter-base/src/util.ts b/experimental/packages/otlp-exporter-base/src/util.ts index bfe9209758..6290153bcb 100644 --- a/experimental/packages/otlp-exporter-base/src/util.ts +++ b/experimental/packages/otlp-exporter-base/src/util.ts @@ -53,14 +53,19 @@ export function appendResourcePathToUrl(url: string, path: string): string { /** * Adds root path to signal specific endpoint when endpoint contains no path part and no root path * @param url - * @param path * @returns url */ -export function appendRootPathToUrlIfNeeded(url: string, path: string): string { - if (!url.includes(path) && !url.endsWith('/')) { - url = url + '/'; +export function appendRootPathToUrlIfNeeded(url: string): string { + try { + const parsedUrl = new URL(url); + if (parsedUrl.pathname === '') { + parsedUrl.pathname = parsedUrl.pathname + '/'; + } + return parsedUrl.toString(); + } catch { + diag.warn(`Could not parse export URL: '${url}'`); + return url; } - return url; } /** @@ -83,7 +88,7 @@ export function configureExporterTimeout(timeoutMillis: number | undefined): num function getExporterTimeoutFromEnv(): number { const definedTimeout = Number(getEnv().OTEL_EXPORTER_OTLP_TRACES_TIMEOUT ?? - getEnv().OTEL_EXPORTER_OTLP_TIMEOUT); + getEnv().OTEL_EXPORTER_OTLP_TIMEOUT); if (definedTimeout <= 0) { // OTLP exporter configured timeout - using default value of 10000ms diff --git a/experimental/packages/otlp-exporter-base/test/common/util.test.ts b/experimental/packages/otlp-exporter-base/test/common/util.test.ts index cc29de641d..d78b719faa 100644 --- a/experimental/packages/otlp-exporter-base/test/common/util.test.ts +++ b/experimental/packages/otlp-exporter-base/test/common/util.test.ts @@ -20,7 +20,7 @@ import { diag } from '@opentelemetry/api'; import { parseHeaders, appendResourcePathToUrl, - appendRootPathToUrlIfNeeded + appendRootPathToUrlIfNeeded, } from '../../src/util'; describe('utils', () => { @@ -84,23 +84,35 @@ describe('utils', () => { describe('appendRootPathToUrlIfNeeded - specifc signal http endpoint', () => { it('should append root path when missing', () => { const url = 'http://foo.bar'; - const resourcePath = 'v1/traces'; - const finalUrl = appendRootPathToUrlIfNeeded(url, resourcePath); + const finalUrl = appendRootPathToUrlIfNeeded(url); assert.strictEqual(finalUrl, url + '/'); }); it('should not append root path and return same url', () => { const url = 'http://foo.bar/'; - const resourcePath = 'v1/traces'; - const finalUrl = appendRootPathToUrlIfNeeded(url, resourcePath); + const finalUrl = appendRootPathToUrlIfNeeded(url); assert.strictEqual(finalUrl, url); }); - it('should append root path when url contains resource path', () => { - const url = 'http://foo.bar/v1/traces'; - const resourcePath = 'v1/traces'; + it('should not append root path when url contains resource path', () => { + { + const url = 'http://foo.bar/v1/traces'; + + const finalUrl = appendRootPathToUrlIfNeeded(url); + assert.strictEqual(finalUrl, url); + } + { + const url = 'https://endpoint/something'; + + const finalUrl = appendRootPathToUrlIfNeeded(url); + assert.strictEqual(finalUrl, url); + } + }); + + it('should not change string when url is not parseable', () => { + const url = 'this is not a URL'; - const finalUrl = appendRootPathToUrlIfNeeded(url, resourcePath); + const finalUrl = appendRootPathToUrlIfNeeded(url); assert.strictEqual(finalUrl, url); }); }); From b934cbc486184720654f7db18d2af9256d679649 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Fri, 7 Oct 2022 16:21:18 +0800 Subject: [PATCH 36/77] docs: merge package api docs (#3255) Co-authored-by: Daniel Dyla --- README.md | 6 +++--- api/README.md | 8 ++++---- api/package.json | 2 +- {api/docs => doc}/context.md | 0 {api/docs => doc}/library-author.md | 0 {api/docs => doc}/propagation.md | 0 {api/docs => doc}/sdk-registration.md | 0 {api/docs => doc}/tracing.md | 0 packages/opentelemetry-sdk-trace-node/README.md | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) rename {api/docs => doc}/context.md (100%) rename {api/docs => doc}/library-author.md (100%) rename {api/docs => doc}/propagation.md (100%) rename {api/docs => doc}/sdk-registration.md (100%) rename {api/docs => doc}/tracing.md (100%) diff --git a/README.md b/README.md index d0d7dd65eb..2c3e786c40 100644 --- a/README.md +++ b/README.md @@ -394,13 +394,13 @@ Collector exporter packages and types are renamed: [PR-1925](https://github.com/open-telemetry/opentelemetry-js/pull/1925) feat(diag-logger): part 2 - breaking changes - remove api.Logger, api.NoopLogger, core.LogLevel, core.ConsoleLogger -- These PR's remove the previous ```Logger``` and ```LogLevel``` implementations and change the way you should use the replacement ```DiagLogger``` and ```DiagLogLevel```, below are simple examples of how to change your existing usages. +- These PR's remove the previous `Logger` and `LogLevel` implementations and change the way you should use the replacement `DiagLogger` and `DiagLogLevel`, below are simple examples of how to change your existing usages. #### Setting the global diagnostic logger -The new global [```api.diag```](https://github.com/open-telemetry/opentelemetry-js-api/blob/main/src/api/diag.ts) provides the ability to set the global diagnostic logger ```setLogger()``` and logging level ```setLogLevel()```, it is also a ```DiagLogger``` implementation and should be directly to log diagnostic messages. +The new global [`api.diag`](https://github.com/open-telemetry/opentelemetry-js/blob/main/api/src/api/diag.ts) provides the ability to set the global diagnostic logger `setLogger()` and logging level `setLogLevel()`, it is also a `DiagLogger` implementation and should be directly to log diagnostic messages. -All included logger references have been removed in preference to using the global ```api.diag``` directly, so you no longer need to pass around the logger instance via function parameters or included as part of the configuration for a component. +All included logger references have been removed in preference to using the global `api.diag` directly, so you no longer need to pass around the logger instance via function parameters or included as part of the configuration for a component. ```javascript import { diag, DiagConsoleLogger, DiagLogLevel } from "@opentelemetry/api"; diff --git a/api/README.md b/api/README.md index 363cfac136..dc44969675 100644 --- a/api/README.md +++ b/api/README.md @@ -15,7 +15,7 @@ Codecov Status - + license
      @@ -132,9 +132,9 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [opentelemetry-js]: https://github.com/open-telemetry/opentelemetry-js [discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions -[license-url]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/LICENSE +[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/api/LICENSE [license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat [npm-url]: https://www.npmjs.com/package/@opentelemetry/api [npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi.svg -[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/tracing.md -[docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/sdk-registration.md +[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/tracing.md +[docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/sdk-registration.md diff --git a/api/package.json b/api/package.json index 012fd629ef..c4649842a5 100644 --- a/api/package.json +++ b/api/package.json @@ -10,7 +10,7 @@ "./build/esm/platform/index.js": "./build/esm/platform/browser/index.js", "./build/src/platform/index.js": "./build/src/platform/browser/index.js" }, - "repository": "https://github.com/open-telemetry/opentelemetry-js-api.git", + "repository": "open-telemetry/opentelemetry-js", "scripts": { "clean": "tsc --build --clean", "codecov:browser": "nyc report --reporter=json && codecov -f coverage/*.json -p ../", diff --git a/api/docs/context.md b/doc/context.md similarity index 100% rename from api/docs/context.md rename to doc/context.md diff --git a/api/docs/library-author.md b/doc/library-author.md similarity index 100% rename from api/docs/library-author.md rename to doc/library-author.md diff --git a/api/docs/propagation.md b/doc/propagation.md similarity index 100% rename from api/docs/propagation.md rename to doc/propagation.md diff --git a/api/docs/sdk-registration.md b/doc/sdk-registration.md similarity index 100% rename from api/docs/sdk-registration.md rename to doc/sdk-registration.md diff --git a/api/docs/tracing.md b/doc/tracing.md similarity index 100% rename from api/docs/tracing.md rename to doc/tracing.md diff --git a/packages/opentelemetry-sdk-trace-node/README.md b/packages/opentelemetry-sdk-trace-node/README.md index 417a380405..c54d11e04a 100644 --- a/packages/opentelemetry-sdk-trace-node/README.md +++ b/packages/opentelemetry-sdk-trace-node/README.md @@ -117,6 +117,6 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions [license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE [license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat -[def-context]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/context.md +[def-context]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/context.md [npm-url]: https://www.npmjs.com/package/@opentelemetry/sdk-trace-node [npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fsdk-trace-node.svg From 40ee3825a420feeb682dfb8a546dc8106c420819 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Sun, 9 Oct 2022 10:42:11 +0200 Subject: [PATCH 37/77] chore(deps): update dependency @types/mocha to v10 (#3286) --- api/package.json | 2 +- experimental/packages/api-logs/package.json | 2 +- experimental/packages/exporter-trace-otlp-grpc/package.json | 2 +- experimental/packages/exporter-trace-otlp-http/package.json | 2 +- experimental/packages/exporter-trace-otlp-proto/package.json | 2 +- experimental/packages/opentelemetry-api-metrics/package.json | 2 +- .../opentelemetry-exporter-metrics-otlp-grpc/package.json | 2 +- .../opentelemetry-exporter-metrics-otlp-http/package.json | 2 +- .../opentelemetry-exporter-metrics-otlp-proto/package.json | 2 +- .../packages/opentelemetry-exporter-prometheus/package.json | 2 +- .../packages/opentelemetry-instrumentation-fetch/package.json | 2 +- .../packages/opentelemetry-instrumentation-grpc/package.json | 2 +- .../packages/opentelemetry-instrumentation-http/package.json | 2 +- .../opentelemetry-instrumentation-xml-http-request/package.json | 2 +- .../packages/opentelemetry-instrumentation/package.json | 2 +- experimental/packages/opentelemetry-sdk-metrics/package.json | 2 +- experimental/packages/opentelemetry-sdk-node/package.json | 2 +- experimental/packages/otlp-exporter-base/package.json | 2 +- experimental/packages/otlp-grpc-exporter-base/package.json | 2 +- experimental/packages/otlp-proto-exporter-base/package.json | 2 +- experimental/packages/otlp-transformer/package.json | 2 +- packages/opentelemetry-context-async-hooks/package.json | 2 +- packages/opentelemetry-context-zone-peer-dep/package.json | 2 +- packages/opentelemetry-context-zone/package.json | 2 +- packages/opentelemetry-core/package.json | 2 +- packages/opentelemetry-exporter-jaeger/package.json | 2 +- packages/opentelemetry-exporter-zipkin/package.json | 2 +- packages/opentelemetry-propagator-b3/package.json | 2 +- packages/opentelemetry-propagator-jaeger/package.json | 2 +- packages/opentelemetry-resources/package.json | 2 +- packages/opentelemetry-sdk-trace-base/package.json | 2 +- packages/opentelemetry-sdk-trace-node/package.json | 2 +- packages/opentelemetry-sdk-trace-web/package.json | 2 +- packages/opentelemetry-semantic-conventions/package.json | 2 +- packages/opentelemetry-shim-opentracing/package.json | 2 +- 35 files changed, 35 insertions(+), 35 deletions(-) diff --git a/api/package.json b/api/package.json index c4649842a5..4fb085886d 100644 --- a/api/package.json +++ b/api/package.json @@ -60,7 +60,7 @@ "access": "public" }, "devDependencies": { - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/experimental/packages/api-logs/package.json b/experimental/packages/api-logs/package.json index 25dc650922..44955363e6 100644 --- a/experimental/packages/api-logs/package.json +++ b/experimental/packages/api-logs/package.json @@ -65,7 +65,7 @@ "@opentelemetry/api": "^1.0.0" }, "devDependencies": { - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/webpack-env": "1.16.3", "codecov": "3.8.3", diff --git a/experimental/packages/exporter-trace-otlp-grpc/package.json b/experimental/packages/exporter-trace-otlp-grpc/package.json index a4b177ebb0..fb00a9d7b0 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/package.json +++ b/experimental/packages/exporter-trace-otlp-grpc/package.json @@ -50,7 +50,7 @@ "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", "@opentelemetry/otlp-exporter-base": "0.33.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/experimental/packages/exporter-trace-otlp-http/package.json b/experimental/packages/exporter-trace-otlp-http/package.json index 4abc90ed7a..2f07cb3436 100644 --- a/experimental/packages/exporter-trace-otlp-http/package.json +++ b/experimental/packages/exporter-trace-otlp-http/package.json @@ -65,7 +65,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/experimental/packages/exporter-trace-otlp-proto/package.json b/experimental/packages/exporter-trace-otlp-proto/package.json index 271246ad00..83b387d958 100644 --- a/experimental/packages/exporter-trace-otlp-proto/package.json +++ b/experimental/packages/exporter-trace-otlp-proto/package.json @@ -49,7 +49,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/experimental/packages/opentelemetry-api-metrics/package.json b/experimental/packages/opentelemetry-api-metrics/package.json index 3118cdb019..2bc05ba2d9 100644 --- a/experimental/packages/opentelemetry-api-metrics/package.json +++ b/experimental/packages/opentelemetry-api-metrics/package.json @@ -64,7 +64,7 @@ "@opentelemetry/api": "^1.0.0" }, "devDependencies": { - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/webpack-env": "1.16.3", "codecov": "3.8.3", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json index 40d8fb7a35..d0b4b2054b 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json @@ -50,7 +50,7 @@ "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", "@opentelemetry/api-metrics": "0.33.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json index 245bc38e36..8cae41c826 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json @@ -65,7 +65,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json index 60f678472d..45266a7df1 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json @@ -50,7 +50,7 @@ "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", "@opentelemetry/api-metrics": "0.33.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/experimental/packages/opentelemetry-exporter-prometheus/package.json b/experimental/packages/opentelemetry-exporter-prometheus/package.json index 0067320ed4..e45cdd33c6 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/package.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/package.json @@ -44,7 +44,7 @@ }, "devDependencies": { "@opentelemetry/api": "^1.0.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/package.json b/experimental/packages/opentelemetry-instrumentation-fetch/package.json index d9448b1e6e..03b44659b2 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/package.json +++ b/experimental/packages/opentelemetry-instrumentation-fetch/package.json @@ -59,7 +59,7 @@ "@opentelemetry/context-zone": "1.7.0", "@opentelemetry/propagator-b3": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/package.json b/experimental/packages/opentelemetry-instrumentation-grpc/package.json index e2bcb44f1f..90e683e23b 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/package.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/package.json @@ -52,7 +52,7 @@ "@opentelemetry/core": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0", "@opentelemetry/sdk-trace-node": "1.7.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/semver": "7.3.9", "@types/sinon": "10.0.13", diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index f5aed8faea..e46808bc91 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -50,7 +50,7 @@ "@opentelemetry/sdk-trace-base": "1.7.0", "@opentelemetry/sdk-trace-node": "1.7.0", "@types/got": "9.6.12", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/request-promise-native": "1.0.18", "@types/semver": "7.3.9", diff --git a/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json b/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json index fa029f09f2..715097b692 100644 --- a/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json +++ b/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json @@ -59,7 +59,7 @@ "@opentelemetry/context-zone": "1.7.0", "@opentelemetry/propagator-b3": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/experimental/packages/opentelemetry-instrumentation/package.json b/experimental/packages/opentelemetry-instrumentation/package.json index e3ead29861..102389ed51 100644 --- a/experimental/packages/opentelemetry-instrumentation/package.json +++ b/experimental/packages/opentelemetry-instrumentation/package.json @@ -79,7 +79,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/semver": "7.3.9", "@types/shimmer": "1.0.2", diff --git a/experimental/packages/opentelemetry-sdk-metrics/package.json b/experimental/packages/opentelemetry-sdk-metrics/package.json index 6931480a4f..0dbb0f9cae 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/package.json +++ b/experimental/packages/opentelemetry-sdk-metrics/package.json @@ -56,7 +56,7 @@ "devDependencies": { "@opentelemetry/api": "^1.0.0", "@types/lodash.merge": "4.6.6", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index 763e1be9aa..b531360e89 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", "@opentelemetry/context-async-hooks": "1.7.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/semver": "7.3.9", "@types/sinon": "10.0.13", diff --git a/experimental/packages/otlp-exporter-base/package.json b/experimental/packages/otlp-exporter-base/package.json index 63c86f9d33..bca5ca1f2f 100644 --- a/experimental/packages/otlp-exporter-base/package.json +++ b/experimental/packages/otlp-exporter-base/package.json @@ -65,7 +65,7 @@ }, "devDependencies": { "@opentelemetry/api": "^1.0.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/experimental/packages/otlp-grpc-exporter-base/package.json b/experimental/packages/otlp-grpc-exporter-base/package.json index 3f73103f33..7f29e1be4f 100644 --- a/experimental/packages/otlp-grpc-exporter-base/package.json +++ b/experimental/packages/otlp-grpc-exporter-base/package.json @@ -54,7 +54,7 @@ "@opentelemetry/otlp-transformer": "0.33.0", "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/experimental/packages/otlp-proto-exporter-base/package.json b/experimental/packages/otlp-proto-exporter-base/package.json index bdb3660638..d41a554e10 100644 --- a/experimental/packages/otlp-proto-exporter-base/package.json +++ b/experimental/packages/otlp-proto-exporter-base/package.json @@ -46,7 +46,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/experimental/packages/otlp-transformer/package.json b/experimental/packages/otlp-transformer/package.json index f91adbb1c2..5b24ff3971 100644 --- a/experimental/packages/otlp-transformer/package.json +++ b/experimental/packages/otlp-transformer/package.json @@ -56,7 +56,7 @@ }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/webpack-env": "1.16.3", "codecov": "3.8.3", "istanbul-instrumenter-loader": "3.0.1", diff --git a/packages/opentelemetry-context-async-hooks/package.json b/packages/opentelemetry-context-async-hooks/package.json index 7ab2edb96b..7a9385f8ce 100644 --- a/packages/opentelemetry-context-async-hooks/package.json +++ b/packages/opentelemetry-context-async-hooks/package.json @@ -45,7 +45,7 @@ }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "codecov": "3.8.3", "mocha": "10.0.0", diff --git a/packages/opentelemetry-context-zone-peer-dep/package.json b/packages/opentelemetry-context-zone-peer-dep/package.json index c69038e0de..550f3adc63 100644 --- a/packages/opentelemetry-context-zone-peer-dep/package.json +++ b/packages/opentelemetry-context-zone-peer-dep/package.json @@ -55,7 +55,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/packages/opentelemetry-context-zone/package.json b/packages/opentelemetry-context-zone/package.json index d8eec0d82b..acfe75bec9 100644 --- a/packages/opentelemetry-context-zone/package.json +++ b/packages/opentelemetry-context-zone/package.json @@ -51,7 +51,7 @@ }, "devDependencies": { "@babel/core": "7.16.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/packages/opentelemetry-core/package.json b/packages/opentelemetry-core/package.json index 0232d62469..31412164ec 100644 --- a/packages/opentelemetry-core/package.json +++ b/packages/opentelemetry-core/package.json @@ -65,7 +65,7 @@ }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/packages/opentelemetry-exporter-jaeger/package.json b/packages/opentelemetry-exporter-jaeger/package.json index d16251d86c..dc926c5695 100644 --- a/packages/opentelemetry-exporter-jaeger/package.json +++ b/packages/opentelemetry-exporter-jaeger/package.json @@ -46,7 +46,7 @@ "devDependencies": { "@opentelemetry/api": "^1.0.0", "@opentelemetry/resources": "1.7.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/packages/opentelemetry-exporter-zipkin/package.json b/packages/opentelemetry-exporter-zipkin/package.json index 8cdc04dc7d..15ce13dbc4 100644 --- a/packages/opentelemetry-exporter-zipkin/package.json +++ b/packages/opentelemetry-exporter-zipkin/package.json @@ -62,7 +62,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/packages/opentelemetry-propagator-b3/package.json b/packages/opentelemetry-propagator-b3/package.json index 60d74a7aef..97e44060c8 100644 --- a/packages/opentelemetry-propagator-b3/package.json +++ b/packages/opentelemetry-propagator-b3/package.json @@ -58,7 +58,7 @@ }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "codecov": "3.8.3", "istanbul-instrumenter-loader": "3.0.1", diff --git a/packages/opentelemetry-propagator-jaeger/package.json b/packages/opentelemetry-propagator-jaeger/package.json index fded131245..c85137a3d1 100644 --- a/packages/opentelemetry-propagator-jaeger/package.json +++ b/packages/opentelemetry-propagator-jaeger/package.json @@ -55,7 +55,7 @@ }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/packages/opentelemetry-resources/package.json b/packages/opentelemetry-resources/package.json index ed7964a019..e834d693a1 100644 --- a/packages/opentelemetry-resources/package.json +++ b/packages/opentelemetry-resources/package.json @@ -62,7 +62,7 @@ }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/packages/opentelemetry-sdk-trace-base/package.json b/packages/opentelemetry-sdk-trace-base/package.json index 970c8b5c83..5c8e879958 100644 --- a/packages/opentelemetry-sdk-trace-base/package.json +++ b/packages/opentelemetry-sdk-trace-base/package.json @@ -65,7 +65,7 @@ }, "devDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/packages/opentelemetry-sdk-trace-node/package.json b/packages/opentelemetry-sdk-trace-node/package.json index 91c1dc5035..0c5b86ba7a 100644 --- a/packages/opentelemetry-sdk-trace-node/package.json +++ b/packages/opentelemetry-sdk-trace-node/package.json @@ -48,7 +48,7 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0", "@opentelemetry/resources": "1.7.0", "@opentelemetry/semantic-conventions": "1.7.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/semver": "7.3.9", "@types/sinon": "10.0.13", diff --git a/packages/opentelemetry-sdk-trace-web/package.json b/packages/opentelemetry-sdk-trace-web/package.json index ace6d3108b..3c8d18b65b 100644 --- a/packages/opentelemetry-sdk-trace-web/package.json +++ b/packages/opentelemetry-sdk-trace-web/package.json @@ -61,7 +61,7 @@ "@opentelemetry/propagator-b3": "1.7.0", "@opentelemetry/resources": "1.7.0", "@types/jquery": "3.5.8", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "@types/webpack-env": "1.16.3", diff --git a/packages/opentelemetry-semantic-conventions/package.json b/packages/opentelemetry-semantic-conventions/package.json index 6d0cb6227a..b9e59edd16 100644 --- a/packages/opentelemetry-semantic-conventions/package.json +++ b/packages/opentelemetry-semantic-conventions/package.json @@ -49,7 +49,7 @@ "access": "public" }, "devDependencies": { - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", "codecov": "3.8.3", diff --git a/packages/opentelemetry-shim-opentracing/package.json b/packages/opentelemetry-shim-opentracing/package.json index 795b7a9bec..51ea010f0f 100644 --- a/packages/opentelemetry-shim-opentracing/package.json +++ b/packages/opentelemetry-shim-opentracing/package.json @@ -46,7 +46,7 @@ "@opentelemetry/propagator-b3": "1.7.0", "@opentelemetry/propagator-jaeger": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", "@types/node": "18.6.5", "codecov": "3.8.3", "mocha": "10.0.0", From ef6fcdcd1a7e5234758e3bcc9ff6c29db5ff4d23 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Tue, 11 Oct 2022 21:04:48 +0800 Subject: [PATCH 38/77] feat(sdk-trace): re-export sdk-trace-base in sdk-trace-node and web (#3319) --- CHANGELOG.md | 2 ++ .../exporter-trace-otlp-http/README.md | 6 ++-- .../README.md | 8 +++-- .../README.md | 7 ++-- .../README.md | 7 ++-- .../README.md | 7 ++-- packages/opentelemetry-context-zone/README.md | 7 ++-- .../opentelemetry-sdk-trace-base/README.md | 36 ++++++++++++------- .../opentelemetry-sdk-trace-node/src/index.ts | 1 + .../opentelemetry-sdk-trace-web/README.md | 7 ++-- .../opentelemetry-sdk-trace-web/src/index.ts | 1 + 11 files changed, 61 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52fea3af5b..dc96d88150 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. ### :rocket: (Enhancement) +* feat(sdk-trace): re-export sdk-trace-base in sdk-trace-node and web [#3319](https://github.com/open-telemetry/opentelemetry-js/pull/3319) @legendecas + ### :bug: (Bug Fix) ### :books: (Refine Doc) diff --git a/experimental/packages/exporter-trace-otlp-http/README.md b/experimental/packages/exporter-trace-otlp-http/README.md index 5afdf0d9e0..ef4259fcd1 100644 --- a/experimental/packages/exporter-trace-otlp-http/README.md +++ b/experimental/packages/exporter-trace-otlp-http/README.md @@ -25,8 +25,10 @@ To see documentation and sample code for the metric exporter, see the [exporter- The OTLPTraceExporter in Web expects the endpoint to end in `/v1/traces`. ```js -import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; +import { + BatchSpanProcessor, + WebTracerProvider, +} from '@opentelemetry/sdk-trace-web'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; const collectorOptions = { diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/README.md b/experimental/packages/opentelemetry-instrumentation-fetch/README.md index 67ecbd6082..2b5336be0b 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/README.md +++ b/experimental/packages/opentelemetry-instrumentation-fetch/README.md @@ -16,9 +16,11 @@ npm install --save @opentelemetry/instrumentation-fetch ## Usage ```js -'use strict'; -import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; +import { + ConsoleSpanExporter, + SimpleSpanProcessor, + WebTracerProvider, +} from '@opentelemetry/sdk-trace-web'; import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch'; import { ZoneContextManager } from '@opentelemetry/context-zone'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; diff --git a/experimental/packages/opentelemetry-instrumentation-http/README.md b/experimental/packages/opentelemetry-instrumentation-http/README.md index 5973ceb796..312eb73bd7 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/README.md +++ b/experimental/packages/opentelemetry-instrumentation-http/README.md @@ -24,8 +24,11 @@ To load a specific instrumentation (HTTP in this case), specify it in the Node T ```js const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http'); -const { ConsoleSpanExporter, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base'); -const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); +const { + ConsoleSpanExporter, + NodeTracerProvider, + SimpleSpanProcessor, +} = require('@opentelemetry/sdk-trace-node'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const provider = new NodeTracerProvider(); diff --git a/experimental/packages/opentelemetry-instrumentation-xml-http-request/README.md b/experimental/packages/opentelemetry-instrumentation-xml-http-request/README.md index c02aa030d2..8c96869460 100644 --- a/experimental/packages/opentelemetry-instrumentation-xml-http-request/README.md +++ b/experimental/packages/opentelemetry-instrumentation-xml-http-request/README.md @@ -16,8 +16,11 @@ npm install --save @opentelemetry/instrumentation-xml-http-request ## Usage ```js -import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; +import { + ConsoleSpanExporter, + SimpleSpanProcessor, + WebTracerProvider, +} from '@opentelemetry/sdk-trace-web'; import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request'; import { ZoneContextManager } from '@opentelemetry/context-zone'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; diff --git a/packages/opentelemetry-context-zone-peer-dep/README.md b/packages/opentelemetry-context-zone-peer-dep/README.md index e8c08b74c9..a505b9fbdd 100644 --- a/packages/opentelemetry-context-zone-peer-dep/README.md +++ b/packages/opentelemetry-context-zone-peer-dep/README.md @@ -20,8 +20,11 @@ npm install --save @opentelemetry/context-zone-peer-dep ```js import { context, trace } from '@opentelemetry/api'; -import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; +import { + ConsoleSpanExporter, + SimpleSpanProcessor, + WebTracerProvider, +} from '@opentelemetry/sdk-trace-web'; import { ZoneContextManager } from '@opentelemetry/context-zone-peer-dep'; const providerWithZone = new WebTracerProvider(); diff --git a/packages/opentelemetry-context-zone/README.md b/packages/opentelemetry-context-zone/README.md index 19ba530901..0162f9645d 100644 --- a/packages/opentelemetry-context-zone/README.md +++ b/packages/opentelemetry-context-zone/README.md @@ -17,8 +17,11 @@ npm install --save @opentelemetry/context-zone ```js import { context, trace } from '@opentelemetry/api'; -import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; +import { + ConsoleSpanExporter, + SimpleSpanProcessor, + WebTracerProvider, +} from '@opentelemetry/sdk-trace-web'; import { ZoneContextManager } from '@opentelemetry/context-zone'; const providerWithZone = new WebTracerProvider(); diff --git a/packages/opentelemetry-sdk-trace-base/README.md b/packages/opentelemetry-sdk-trace-base/README.md index c4a40cc6f5..6d7b655894 100644 --- a/packages/opentelemetry-sdk-trace-base/README.md +++ b/packages/opentelemetry-sdk-trace-base/README.md @@ -57,10 +57,12 @@ Samples every trace regardless of upstream sampling decisions. > This is used as a default Sampler ```js -const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); -const { AlwaysOnSampler } = require("@opentelemetry/core"); +const { + AlwaysOnSampler, + BasicTracerProvider, +} = require("@opentelemetry/sdk-trace-base"); -const tracerProvider = new NodeTracerProvider({ +const tracerProvider = new BasicTracerProvider({ sampler: new AlwaysOnSampler() }); ``` @@ -70,10 +72,12 @@ const tracerProvider = new NodeTracerProvider({ Doesn't sample any trace, regardless of upstream sampling decisions. ```js -const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); -const { AlwaysOffSampler } = require("@opentelemetry/core"); +const { + AlwaysOffSampler, + BasicTracerProvider, +} = require("@opentelemetry/sdk-trace-base"); -const tracerProvider = new NodeTracerProvider({ +const tracerProvider = new BasicTracerProvider({ sampler: new AlwaysOffSampler() }); ``` @@ -86,10 +90,12 @@ Any trace that would be sampled at a given percentage will also be sampled at an The `TraceIDRatioSampler` may be used with the `ParentBasedSampler` to respect the sampled flag of an incoming trace. ```js -const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); -const { TraceIdRatioBasedSampler } = require("@opentelemetry/core"); +const { + BasicTracerProvider, + TraceIdRatioBasedSampler, +} = require("@opentelemetry/sdk-trace-base"); -const tracerProvider = new NodeTracerProvider({ +const tracerProvider = new BasicTracerProvider({ // See details of ParentBasedSampler below sampler: new ParentBasedSampler({ // Trace ID Ratio Sampler accepts a positional argument @@ -130,10 +136,14 @@ Optional parameters: |present|false|false|`localParentNotSampled()`| ```js -const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); -const { ParentBasedSampler, AlwaysOffSampler, TraceIdRatioBasedSampler } = require("@opentelemetry/core"); - -const tracerProvider = new NodeTracerProvider({ +const { + AlwaysOffSampler, + BasicTracerProvider, + ParentBasedSampler, + TraceIdRatioBasedSampler, +} = require("@opentelemetry/sdk-trace-base"); + +const tracerProvider = new BasicTracerProvider({ sampler: new ParentBasedSampler({ // By default, the ParentBasedSampler will respect the parent span's sampling // decision. This is configurable by providing a different sampler to use diff --git a/packages/opentelemetry-sdk-trace-node/src/index.ts b/packages/opentelemetry-sdk-trace-node/src/index.ts index 44e347c09e..8f6c5b9311 100644 --- a/packages/opentelemetry-sdk-trace-node/src/index.ts +++ b/packages/opentelemetry-sdk-trace-node/src/index.ts @@ -16,3 +16,4 @@ export { NodeTracerConfig } from './config'; export * from './NodeTracerProvider'; +export * from '@opentelemetry/sdk-trace-base'; diff --git a/packages/opentelemetry-sdk-trace-web/README.md b/packages/opentelemetry-sdk-trace-web/README.md index cd7e448e67..8eccf7fc13 100644 --- a/packages/opentelemetry-sdk-trace-web/README.md +++ b/packages/opentelemetry-sdk-trace-web/README.md @@ -31,8 +31,11 @@ npm install --save @opentelemetry/sdk-trace-web ## Usage ```js -import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; +import { + ConsoleSpanExporter, + SimpleSpanProcessor, + WebTracerProvider, +} from '@opentelemetry/sdk-trace-web'; import { DocumentLoad } from '@opentelemetry/plugin-document-load'; import { ZoneContextManager } from '@opentelemetry/context-zone'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; diff --git a/packages/opentelemetry-sdk-trace-web/src/index.ts b/packages/opentelemetry-sdk-trace-web/src/index.ts index a506be00ce..d7bfeaf382 100644 --- a/packages/opentelemetry-sdk-trace-web/src/index.ts +++ b/packages/opentelemetry-sdk-trace-web/src/index.ts @@ -19,3 +19,4 @@ export * from './StackContextManager'; export * from './enums/PerformanceTimingNames'; export * from './types'; export * from './utils'; +export * from '@opentelemetry/sdk-trace-base'; From aa263e5c27f579523d11e18209dc5aeeb67676ea Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Wed, 12 Oct 2022 17:06:11 +0200 Subject: [PATCH 39/77] fix(build): pin checkout actions for web build to 3.0.2 (#3321) --- .github/workflows/unit-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 21c99fbf5e..8fc5e17ba2 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -104,7 +104,7 @@ jobs: - name: Permission Setup run: sudo chmod -R 777 /github /__w - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v3.0.2 - name: restore lerna id: cache @@ -144,7 +144,7 @@ jobs: - name: Permission Setup run: sudo chmod -R 777 /github /__w - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v3.0.2 - name: restore lerna id: cache From efb0275ffe0e07a779629d465a6f2342a7485001 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 14 Oct 2022 03:42:09 -0400 Subject: [PATCH 40/77] ci: run browser tests without circle (#3328) * ci: run browser tests without circle * Reduce scope * Bring back other tests * Apply to webworker tests * Changelog * Use specific node version * Review comments * Downgrade node in both places --- .github/workflows/unit-test.yml | 23 ++++++++--------------- CHANGELOG.md | 2 ++ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 8fc5e17ba2..7dea0d9044 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -55,8 +55,6 @@ jobs: run: npm run codecov if: ${{ matrix.node_version == '14' }} node-windows-tests: - strategy: - fail-fast: false runs-on: windows-latest env: NPM_CONFIG_UNSAFE_PERM: true @@ -96,15 +94,15 @@ jobs: run: npm run test browser-tests: runs-on: ubuntu-latest - container: - image: circleci/node:16-browsers env: NPM_CONFIG_UNSAFE_PERM: true steps: - - name: Permission Setup - run: sudo chmod -R 777 /github /__w - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3 + + - uses: actions/setup-node@v3 + with: + node-version: 16 - name: restore lerna id: cache @@ -126,8 +124,6 @@ jobs: - name: Build 🔧 run: | - npm run compile - # run additional compilation variants npx lerna run compile - name: Unit tests @@ -136,15 +132,14 @@ jobs: run: npm run codecov:browser webworker-tests: runs-on: ubuntu-latest - container: - image: circleci/node:16-browsers env: NPM_CONFIG_UNSAFE_PERM: true steps: - - name: Permission Setup - run: sudo chmod -R 777 /github /__w - name: Checkout uses: actions/checkout@v3.0.2 + - uses: actions/setup-node@v3 + with: + node-version: 16 - name: restore lerna id: cache @@ -166,8 +161,6 @@ jobs: - name: Build 🔧 run: | - npm run compile - # run additional compilation variants npx lerna run compile - name: Unit tests diff --git a/CHANGELOG.md b/CHANGELOG.md index dc96d88150..5af8762b41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ All notable changes to this project will be documented in this file. ### :house: (Internal) +* ci: run browser tests without circle [#3328](https://github.com/open-telemetry/opentelemetry-js/pull/3328) @dyladan + ## 1.7.0 ### :bug: (Bug Fix) From 07a16b7c90016ca171525228ba4ddf0a7823d297 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 14 Oct 2022 09:43:33 -0400 Subject: [PATCH 41/77] Test API with old node versions (#3296) Co-authored-by: Chengzhong Wu --- .github/workflows/unit-test.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 7dea0d9044..734bd6b29d 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -167,3 +167,31 @@ jobs: run: npm run test:webworker - name: Report Coverage run: npm run codecov:webworker + api-eol-node-test: + strategy: + fail-fast: false + matrix: + node_version: + - "8" + - "10" + - "12" + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node_version }} + + - name: Build + working-directory: ./api + run: | + npm install --ignore-scripts + npm install @types/mocha@^7 mocha@^7 ts-loader@^8 ts-mocha@^8 + node ../scripts/version-update.js + tsc --build tsconfig.json tsconfig.esm.json + + - name: Test + working-directory: ./api + run: npm test From a7d053ae5a9fb073ccc3b639c3359fba19594e3d Mon Sep 17 00:00:00 2001 From: Anthony Telljohann Date: Fri, 14 Oct 2022 11:10:42 -0400 Subject: [PATCH 42/77] fix(resources): fix when attribute values contain spaces (#3302) Co-authored-by: Daniel Dyla --- CHANGELOG.md | 3 +++ .../src/detectors/EnvDetector.ts | 4 ++-- .../test/detectors/node/EnvDetector.test.ts | 10 +++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5af8762b41..b17fd36d5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ All notable changes to this project will be documented in this file. ### :bug: (Bug Fix) +* fix(resources): fix EnvDetector throwing errors when attribute values contain spaces + [#3295](https://github.com/open-telemetry/opentelemetry-js/issues/3295) + ### :books: (Refine Doc) ### :house: (Internal) diff --git a/packages/opentelemetry-resources/src/detectors/EnvDetector.ts b/packages/opentelemetry-resources/src/detectors/EnvDetector.ts index 782f664a1a..44f15dcdfe 100644 --- a/packages/opentelemetry-resources/src/detectors/EnvDetector.ts +++ b/packages/opentelemetry-resources/src/detectors/EnvDetector.ts @@ -110,7 +110,7 @@ class EnvDetector implements Detector { let [key, value] = keyValuePair; // Leading and trailing whitespaces are trimmed. key = key.trim(); - value = value.trim().split('^"|"$').join(''); + value = value.trim().split(/^"|"$/).join(''); if (!this._isValidAndNotEmpty(key)) { throw new Error(`Attribute key ${this._ERROR_MESSAGE_INVALID_CHARS}`); } @@ -136,7 +136,7 @@ class EnvDetector implements Detector { private _isPrintableString(str: string): boolean { for (let i = 0; i < str.length; i++) { const ch: string = str.charAt(i); - if (ch <= ' ' || ch >= '~') { + if (ch < ' ' || ch >= '~') { return false; } } diff --git a/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts b/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts index 2a2746e14b..486de2b4bb 100644 --- a/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts +++ b/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; import { envDetector, Resource } from '../../../src'; import { assertK8sResource, @@ -26,7 +25,7 @@ describeNode('envDetector() on Node.js', () => { describe('with valid env', () => { before(() => { process.env.OTEL_RESOURCE_ATTRIBUTES = - 'k8s.pod.name="pod-xyz-123",k8s.cluster.name="c1",k8s.namespace.name="default"'; + 'k8s.pod.name="pod-xyz-123",k8s.cluster.name="c1",k8s.namespace.name="default",k8s.deployment.name="deployment name"'; }); after(() => { @@ -36,9 +35,10 @@ describeNode('envDetector() on Node.js', () => { it('should return resource information from environment variable', async () => { const resource: Resource = await envDetector.detect(); assertK8sResource(resource, { - [SemanticResourceAttributes.K8S_POD_NAME]: 'pod-xyz-123', - [SemanticResourceAttributes.K8S_CLUSTER_NAME]: 'c1', - [SemanticResourceAttributes.K8S_NAMESPACE_NAME]: 'default', + podName: 'pod-xyz-123', + clusterName: 'c1', + namespaceName: 'default', + deploymentName: 'deployment name' }); }); }); From 92f235964dd0fb764f5a5b4aadd5a17d62d14e84 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Mon, 17 Oct 2022 10:27:07 +0800 Subject: [PATCH 43/77] fix(instrumentation): debug log on no modules defined for instrumentation (#3308) Co-authored-by: Daniel Dyla Co-authored-by: Valentin Marchaud --- experimental/CHANGELOG.md | 1 + .../src/platform/node/instrumentation.ts | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index f14d274c65..9b6d0b4625 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to experimental packages in this project will be documented * fix(node-sdk): move `@opentelemetry/semantic-conventions` to `dependencies` [#3283](https://github.com/open-telemetry/opentelemetry-js/pull/3283) @mhassan1 * fix(exporters): do not append trailing '/' when URL contains path [#3274](https://github.com/open-telemetry/opentelemetry-js/pull/3274) @pichlermarc +* fix(instrumentation): debug log on no modules defined for instrumentation [#3308](https://github.com/open-telemetry/opentelemetry-js/pull/3308) @legendecas ### :books: (Refine Doc) diff --git a/experimental/packages/opentelemetry-instrumentation/src/platform/node/instrumentation.ts b/experimental/packages/opentelemetry-instrumentation/src/platform/node/instrumentation.ts index 70dac85332..5bc0921778 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/platform/node/instrumentation.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/platform/node/instrumentation.ts @@ -48,9 +48,10 @@ export abstract class InstrumentationBase this._modules = (modules as InstrumentationModuleDefinition[]) || []; if (this._modules.length === 0) { - diag.warn( - 'No modules instrumentation has been defined,' + - ' nothing will be patched' + diag.debug( + 'No modules instrumentation has been defined for ' + + `'${this.instrumentationName}@${this.instrumentationVersion}'` + + ', nothing will be patched' ); } From 3ab8bfcedb478b5a578ed37fd72411d05180bba3 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Mon, 17 Oct 2022 14:16:39 +0200 Subject: [PATCH 44/77] feat(prometheus): serialize resource as target_info gauge (#3300) --- experimental/CHANGELOG.md | 1 + experimental/examples/prometheus/package.json | 6 +-- .../package.json | 3 +- .../src/PrometheusExporter.ts | 23 +++++----- .../src/PrometheusSerializer.ts | 20 ++++++++- .../test/PrometheusExporter.test.ts | 42 +++++++++++++++--- .../test/PrometheusSerializer.test.ts | 44 ++++++++++++++++--- .../tsconfig.json | 3 ++ lerna.json | 1 + 9 files changed, 116 insertions(+), 27 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 9b6d0b4625..595add19a3 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -9,6 +9,7 @@ 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 +* feat(prometheus): serialize resource as target_info gauge [#3300](https://github.com/open-telemetry/opentelemetry-js/pull/3300) @pichlermarc ### :bug: (Bug Fix) diff --git a/experimental/examples/prometheus/package.json b/experimental/examples/prometheus/package.json index 9816279e53..837fcf9b61 100644 --- a/experimental/examples/prometheus/package.json +++ b/experimental/examples/prometheus/package.json @@ -1,6 +1,6 @@ { "name": "prometheus-example", - "version": "0.32.0", + "version": "0.33.0", "description": "Example of using @opentelemetry/sdk-metrics and @opentelemetry/exporter-prometheus", "main": "index.js", "scripts": { @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.0.2", - "@opentelemetry/exporter-prometheus": "0.32.0", - "@opentelemetry/sdk-metrics": "0.32.0" + "@opentelemetry/exporter-prometheus": "0.33.0", + "@opentelemetry/sdk-metrics": "0.33.0" } } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/package.json b/experimental/packages/opentelemetry-exporter-prometheus/package.json index e45cdd33c6..c8305d3c88 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/package.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/package.json @@ -61,7 +61,8 @@ "dependencies": { "@opentelemetry/api-metrics": "0.33.0", "@opentelemetry/core": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0" + "@opentelemetry/sdk-metrics": "0.33.0", + "@opentelemetry/resources": "1.7.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-prometheus" } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts index 42b051e301..4f333eec55 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts @@ -18,15 +18,22 @@ import { diag } from '@opentelemetry/api'; import { globalErrorHandler, } from '@opentelemetry/core'; -import { Aggregation, AggregationTemporality, MetricReader } from '@opentelemetry/sdk-metrics'; -import { createServer, IncomingMessage, Server, ServerResponse } from 'http'; +import { + Aggregation, + AggregationTemporality, + MetricReader +} from '@opentelemetry/sdk-metrics'; +import { + createServer, + IncomingMessage, + Server, + ServerResponse +} from 'http'; import { ExporterConfig } from './export/types'; import { PrometheusSerializer } from './PrometheusSerializer'; /** Node.js v8.x compat */ import { URL } from 'url'; -const NO_REGISTERED_METRICS = '# no registered metrics'; - export class PrometheusExporter extends MetricReader { static readonly DEFAULT_OPTIONS = { host: undefined, @@ -154,7 +161,7 @@ export class PrometheusExporter extends MetricReader { /** * Request handler that responds with the current state of metrics - * @param request Incoming HTTP request of server instance + * @param _request Incoming HTTP request of server instance * @param response HTTP response objet used to response to request */ public getMetricsRequestHandler( @@ -195,11 +202,7 @@ export class PrometheusExporter extends MetricReader { if (errors.length) { diag.error('PrometheusExporter: metrics collection errors', ...errors); } - let result = this._serializer.serialize(resourceMetrics); - if (result === '') { - result = NO_REGISTERED_METRICS; - } - response.end(result); + response.end(this._serializer.serialize(resourceMetrics)); }, err => { response.end(`# failed to export metrics: ${err}`); diff --git a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts index 94144732ac..410cbfbf34 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts @@ -29,6 +29,7 @@ import type { MetricAttributeValue } from '@opentelemetry/api-metrics'; import { hrTimeToMilliseconds } from '@opentelemetry/core'; +import { Resource } from '@opentelemetry/resources'; type PrometheusDataTypeLiteral = | 'counter' @@ -167,6 +168,8 @@ function stringify( }\n`; } +const NO_REGISTERED_METRICS = '# no registered metrics'; + export class PrometheusSerializer { private _prefix: string | undefined; private _appendTimestamp: boolean; @@ -180,10 +183,16 @@ export class PrometheusSerializer { serialize(resourceMetrics: ResourceMetrics): string { let str = ''; + for (const scopeMetrics of resourceMetrics.scopeMetrics) { str += this._serializeScopeMetrics(scopeMetrics); } - return str; + + if (str === '') { + str += NO_REGISTERED_METRICS; + } + + return this._serializeResource(resourceMetrics.resource) + str; } private _serializeScopeMetrics(scopeMetrics: ScopeMetrics) { @@ -311,4 +320,13 @@ export class PrometheusSerializer { return results; } + + protected _serializeResource(resource: Resource): string { + const name = 'target_info'; + const help = `# HELP ${name} Target metadata`; + const type = `# TYPE ${name} gauge`; + + const results = stringify(name, resource.attributes, 1).trim(); + return `${help}\n${type}\n${results}\n`; + } } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts index 080ac599e3..6b60952670 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts @@ -14,16 +14,28 @@ * limitations under the License. */ -import { Meter, ObservableResult } from '@opentelemetry/api-metrics'; +import { + Meter, + ObservableResult +} from '@opentelemetry/api-metrics'; import { MeterProvider } from '@opentelemetry/sdk-metrics'; import * as assert from 'assert'; import * as sinon from 'sinon'; import * as http from 'http'; import { PrometheusExporter } from '../src'; -import { mockedHrTimeMs, mockHrTime } from './util'; +import { + mockedHrTimeMs, + mockHrTime +} from './util'; import { SinonStubbedInstance } from 'sinon'; import { Counter } from '@opentelemetry/api-metrics'; +const serializedEmptyResourceLines = [ + '# HELP target_info Target metadata', + '# TYPE target_info gauge', + 'target_info 1' +]; + describe('PrometheusExporter', () => { beforeEach(() => { mockHrTime(); @@ -249,11 +261,12 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.strictEqual( - lines[0], + lines[serializedEmptyResourceLines.length], '# HELP counter_total a test description' ); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP counter_total a test description', '# TYPE counter_total counter', `counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -283,6 +296,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP metric_observable_gauge a test description', '# TYPE metric_observable_gauge gauge', `metric_observable_gauge{pid="123",core="1"} 0.999 ${mockedHrTimeMs}`, @@ -302,6 +316,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP counter_total a test description', '# TYPE counter_total counter', `counter_total{counterKey1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -331,11 +346,14 @@ describe('PrometheusExporter', () => { }); }); - it('should export a comment if no metrics are registered', async () => { + it('should export resource even if no metrics are registered', async () => { const body = await request('http://localhost:9464/metrics'); const lines = body.split('\n'); - assert.deepStrictEqual(lines, ['# no registered metrics']); + assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, + '# no registered metrics' + ]); }); it('should add a description if missing', async () => { @@ -347,6 +365,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP counter_total description missing', '# TYPE counter_total counter', `counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -363,6 +382,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP counter_bad_name_total description missing', '# TYPE counter_bad_name_total counter', `counter_bad_name_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -380,6 +400,7 @@ describe('PrometheusExporter', () => { const body = await request('http://localhost:9464/metrics'); const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP counter a test description', '# TYPE counter gauge', `counter{key1="attributeValue1"} 20 ${mockedHrTimeMs}`, @@ -387,7 +408,7 @@ describe('PrometheusExporter', () => { ]); }); - it('should export an ObservableCounter as a counter', async() => { + it('should export an ObservableCounter as a counter', async () => { function getValue() { return 20; } @@ -408,6 +429,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP metric_observable_counter a test description', '# TYPE metric_observable_counter counter', `metric_observable_counter{key1="attributeValue1"} 20 ${mockedHrTimeMs}`, @@ -436,6 +458,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP metric_observable_up_down_counter a test description', '# TYPE metric_observable_up_down_counter gauge', `metric_observable_up_down_counter{key1="attributeValue1"} 20 ${mockedHrTimeMs}`, @@ -443,7 +466,7 @@ describe('PrometheusExporter', () => { ]); }); - it('should export a Histogram as a summary', async() => { + it('should export a Histogram as a summary', async () => { const histogram = meter.createHistogram('test_histogram', { description: 'a test description', }); @@ -454,6 +477,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP test_histogram a test description', '# TYPE test_histogram histogram', `test_histogram_count{key1="attributeValue1"} 1 ${mockedHrTimeMs}`, @@ -507,6 +531,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP test_prefix_counter_total description missing', '# TYPE test_prefix_counter_total counter', `test_prefix_counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -535,6 +560,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP counter_total description missing', '# TYPE counter_total counter', `counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -563,6 +589,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP counter_total description missing', '# TYPE counter_total counter', `counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -591,6 +618,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ + ...serializedEmptyResourceLines, '# HELP counter_total description missing', '# TYPE counter_total counter', 'counter_total{key1="attributeValue1"} 10', diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts index 1ae4ab8f53..852946f355 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts @@ -15,7 +15,10 @@ */ import * as assert from 'assert'; -import { MetricAttributes, UpDownCounter } from '@opentelemetry/api-metrics'; +import { + MetricAttributes, + UpDownCounter +} from '@opentelemetry/api-metrics'; import { Aggregation, AggregationTemporality, @@ -31,13 +34,22 @@ import { } from '@opentelemetry/sdk-metrics'; import * as sinon from 'sinon'; import { PrometheusSerializer } from '../src'; -import { mockedHrTimeMs, mockHrTime } from './util'; +import { + mockedHrTimeMs, + mockHrTime +} from './util'; +import { Resource } from '@opentelemetry/resources'; const attributes = { foo1: 'bar1', foo2: 'bar2', }; +const serializedEmptyResource = + '# HELP target_info Target metadata\n' + + '# TYPE target_info gauge\n' + + 'target_info 1\n'; + class TestMetricReader extends MetricReader { constructor() { super({ @@ -278,7 +290,7 @@ describe('PrometheusSerializer', () => { const reader = new TestMetricReader(); const meterProvider = new MeterProvider({ views: [ - new View({aggregation: new LastValueAggregation(), instrumentName: '*' }) + new View({ aggregation: new LastValueAggregation(), instrumentName: '*' }) ] }); meterProvider.addMetricReader(reader); @@ -361,7 +373,7 @@ describe('PrometheusSerializer', () => { assert.strictEqual( result, '# HELP test foobar\n' + - '# TYPE test histogram\n' + + '# TYPE test histogram\n' + `test_count{val="1"} 3 ${mockedHrTimeMs}\n` + `test_sum{val="1"} 175 ${mockedHrTimeMs}\n` + `test_bucket{val="1",le="1"} 0 ${mockedHrTimeMs}\n` + @@ -465,6 +477,7 @@ describe('PrometheusSerializer', () => { const result = await getCounterResult('test', serializer, { unit: unitOfMetric, exportAll: true }); assert.strictEqual( result, + serializedEmptyResource + '# HELP test_total description missing\n' + `# UNIT test_total ${unitOfMetric}\n` + '# TYPE test_total counter\n' + @@ -478,6 +491,7 @@ describe('PrometheusSerializer', () => { const result = await getCounterResult('test', serializer, { exportAll: true }); assert.strictEqual( result, + serializedEmptyResource + '# HELP test_total description missing\n' + '# TYPE test_total counter\n' + `test_total 1 ${mockedHrTimeMs}\n` @@ -607,7 +621,7 @@ describe('PrometheusSerializer', () => { const serializer = new PrometheusSerializer(); const result = await testSerializer(serializer, 'test_total', counter => { - // if you try to use a attribute name like account-id prometheus will complain + // if you try to use an attribute name like account-id prometheus will complain // with an error like: // error while linting: text format parsing error in line 282: expected '=' after label name, found '-' counter.add(1, ({ @@ -621,4 +635,24 @@ describe('PrometheusSerializer', () => { ); }); }); + + describe('_serializeResource', () => { + it('should serialize resource', () => { + const serializer = new PrometheusSerializer(undefined, true); + const result = serializer['_serializeResource'](new Resource({ + env: 'prod', + hostname: 'myhost', + datacenter: 'sdc', + region: 'europe', + owner: 'frontend' + })); + + assert.strictEqual( + result, + '# HELP target_info Target metadata\n' + + '# TYPE target_info gauge\n' + + 'target_info{env="prod",hostname="myhost",datacenter="sdc",region="europe",owner="frontend"} 1\n' + ); + }); + }); }); diff --git a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json index 138ffc3aad..1283f8e6d4 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json @@ -15,6 +15,9 @@ { "path": "../../../packages/opentelemetry-core" }, + { + "path": "../../../packages/opentelemetry-resources" + }, { "path": "../opentelemetry-api-metrics" }, diff --git a/lerna.json b/lerna.json index 5c0f76b9c2..d97ab02a62 100644 --- a/lerna.json +++ b/lerna.json @@ -5,6 +5,7 @@ "api", "packages/*", "experimental/packages/*", + "experimental/examples/*", "experimental/backwards-compatability/*", "integration-tests/*", "selenium-tests", From ec8ff16370fba4086ee6bbf342316342b55139f9 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 17 Oct 2022 17:17:30 -0400 Subject: [PATCH 45/77] fix: enforce consistent span durations (#3327) --- CHANGELOG.md | 2 ++ packages/opentelemetry-sdk-trace-base/src/Span.ts | 6 ++++-- .../test/common/Span.test.ts | 12 ++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b17fd36d5b..99a4cef09f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file. ### :bug: (Bug Fix) +* fix(sdk-trace): enforce consistent span durations + [#3327](https://github.com/open-telemetry/opentelemetry-js/pull/3327) @dyladan * fix(resources): fix EnvDetector throwing errors when attribute values contain spaces [#3295](https://github.com/open-telemetry/opentelemetry-js/issues/3295) diff --git a/packages/opentelemetry-sdk-trace-base/src/Span.ts b/packages/opentelemetry-sdk-trace-base/src/Span.ts index fe0b0d0470..058507b7f7 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Span.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Span.ts @@ -15,7 +15,7 @@ */ import * as api from '@opentelemetry/api'; -import { Context, SpanAttributeValue } from '@opentelemetry/api'; +import { Context, HrTime, SpanAttributeValue } from '@opentelemetry/api'; import { Clock, hrTimeDuration, @@ -191,10 +191,12 @@ export class Span implements api.Span, ReadableSpan { if (this._duration[0] < 0) { api.diag.warn( - 'Inconsistent start and end time, startTime > endTime', + 'Inconsistent start and end time, startTime > endTime. Setting span duration to 0ms.', this.startTime, this.endTime ); + this.endTime = this.startTime.slice() as HrTime; + this._duration = [0, 0]; } this._spanProcessor.onEnd(this); diff --git a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts index 4573efbbf4..792c1f88df 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts @@ -128,6 +128,18 @@ describe('Span', () => { assert.ok(hrTimeToNanoseconds(span.duration) >= 0); }); + it('should ensure duration is never negative even if provided with inconsistent times', () => { + const span = new Span( + tracer, + ROOT_CONTEXT, + name, + spanContext, + SpanKind.SERVER + ); + span.end(hrTimeToMilliseconds(span.startTime) - 1); + assert.ok(hrTimeToNanoseconds(span.duration) >= 0); + }); + it('should have valid event.time', () => { const span = new Span( tracer, From 6ede1ee179d8e6c60b3e1527da47f4877912ee42 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 19 Oct 2022 11:03:33 -0400 Subject: [PATCH 46/77] Remove got temporarily (#3347) --- experimental/CHANGELOG.md | 3 +++ .../packages/opentelemetry-instrumentation-http/package.json | 2 -- .../test/functionals/http-package.test.ts | 5 +++-- .../test/functionals/https-package.test.ts | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 595add19a3..f3416bb377 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -23,6 +23,9 @@ All notable changes to experimental packages in this project will be documented ### :house: (Internal) +* ci(instrumentation-http): remove got devDependency + [#3347](https://github.com/open-telemetry/opentelemetry-js/issues/3347) @dyladan + ## 0.33.0 ### :boom: Breaking Change diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index e46808bc91..5c4f5b21c7 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -49,7 +49,6 @@ "@opentelemetry/context-async-hooks": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0", "@opentelemetry/sdk-trace-node": "1.7.0", - "@types/got": "9.6.12", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/request-promise-native": "1.0.18", @@ -58,7 +57,6 @@ "@types/superagent": "4.1.13", "axios": "0.24.0", "codecov": "3.8.3", - "got": "9.6.0", "mocha": "10.0.0", "nock": "13.0.11", "nyc": "15.1.0", diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-package.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-package.test.ts index 8da3577ddb..51b15dd6f3 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-package.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-package.test.ts @@ -35,7 +35,8 @@ instrumentation.disable(); import * as http from 'http'; import * as request from 'request-promise-native'; import * as superagent from 'superagent'; -import * as got from 'got'; +// Temporarily removed. See https://github.com/open-telemetry/opentelemetry-js/issues/3344 +// import * as got from 'got'; import * as nock from 'nock'; import axios, { AxiosResponse } from 'axios'; @@ -80,7 +81,7 @@ describe('Packages', () => { [ { name: 'axios', httpPackage: axios }, //keep first { name: 'superagent', httpPackage: superagent }, - { name: 'got', httpPackage: { get: (url: string) => got(url) } }, + // { name: 'got', httpPackage: { get: (url: string) => got(url) } }, { name: 'request', httpPackage: { get: (url: string) => request(url) }, diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-package.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-package.test.ts index 5f1c11d4a7..3fd164c243 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-package.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-package.test.ts @@ -35,7 +35,8 @@ instrumentation.disable(); import * as http from 'http'; import * as request from 'request-promise-native'; import * as superagent from 'superagent'; -import * as got from 'got'; +// Temporarily removed. See https://github.com/open-telemetry/opentelemetry-js/issues/3344 +// import * as got from 'got'; import * as nock from 'nock'; import axios, { AxiosResponse } from 'axios'; @@ -80,7 +81,7 @@ describe('Packages', () => { [ { name: 'axios', httpPackage: axios }, //keep first { name: 'superagent', httpPackage: superagent }, - { name: 'got', httpPackage: { get: (url: string) => got(url) } }, + // { name: 'got', httpPackage: { get: (url: string) => got(url) } }, { name: 'request', httpPackage: { get: (url: string) => request(url) }, From 0d4c71fc50f8be5fe85dc38eeb622580422d92cd Mon Sep 17 00:00:00 2001 From: Purvi Kanal Date: Wed, 19 Oct 2022 15:44:50 -0400 Subject: [PATCH 47/77] feat: enable tree shaking (#3329) Co-authored-by: Daniel Dyla --- CHANGELOG.md | 1 + experimental/CHANGELOG.md | 1 + experimental/packages/api-logs/package.json | 3 ++- experimental/packages/exporter-trace-otlp-grpc/package.json | 3 ++- experimental/packages/exporter-trace-otlp-http/package.json | 3 ++- experimental/packages/exporter-trace-otlp-proto/package.json | 3 ++- experimental/packages/opentelemetry-api-metrics/package.json | 3 ++- .../opentelemetry-exporter-metrics-otlp-grpc/package.json | 3 ++- .../opentelemetry-exporter-metrics-otlp-http/package.json | 3 ++- .../opentelemetry-exporter-metrics-otlp-proto/package.json | 3 ++- .../packages/opentelemetry-exporter-prometheus/package.json | 3 ++- .../packages/opentelemetry-instrumentation-fetch/package.json | 3 ++- .../packages/opentelemetry-instrumentation-grpc/package.json | 3 ++- .../packages/opentelemetry-instrumentation-http/package.json | 3 ++- .../package.json | 3 ++- .../packages/opentelemetry-instrumentation/package.json | 3 ++- experimental/packages/opentelemetry-sdk-metrics/package.json | 3 ++- experimental/packages/opentelemetry-sdk-node/package.json | 3 ++- experimental/packages/otlp-exporter-base/package.json | 3 ++- experimental/packages/otlp-grpc-exporter-base/package.json | 3 ++- experimental/packages/otlp-proto-exporter-base/package.json | 3 ++- experimental/packages/otlp-transformer/package.json | 3 ++- packages/opentelemetry-context-async-hooks/package.json | 3 ++- packages/opentelemetry-core/package.json | 3 ++- packages/opentelemetry-exporter-jaeger/package.json | 3 ++- packages/opentelemetry-exporter-zipkin/package.json | 3 ++- packages/opentelemetry-propagator-b3/package.json | 3 ++- packages/opentelemetry-propagator-jaeger/package.json | 3 ++- packages/opentelemetry-resources/package.json | 3 ++- packages/opentelemetry-sdk-trace-base/package.json | 3 ++- packages/opentelemetry-sdk-trace-node/package.json | 3 ++- packages/opentelemetry-sdk-trace-web/package.json | 3 ++- packages/opentelemetry-semantic-conventions/package.json | 3 ++- packages/opentelemetry-shim-opentracing/package.json | 3 ++- packages/template/package.json | 1 + 35 files changed, 67 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99a4cef09f..f69e2ae6e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. ### :rocket: (Enhancement) * feat(sdk-trace): re-export sdk-trace-base in sdk-trace-node and web [#3319](https://github.com/open-telemetry/opentelemetry-js/pull/3319) @legendecas +* feat: enable tree shaking [#3329](https://github.com/open-telemetry/opentelemetry-js/pull/3329) @pkanal ### :bug: (Bug Fix) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index f3416bb377..688384d220 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -9,6 +9,7 @@ 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 +* feat: enable tree shaking [#3329](https://github.com/open-telemetry/opentelemetry-js/pull/3329) @pkanal * feat(prometheus): serialize resource as target_info gauge [#3300](https://github.com/open-telemetry/opentelemetry-js/pull/3300) @pichlermarc ### :bug: (Bug Fix) diff --git a/experimental/packages/api-logs/package.json b/experimental/packages/api-logs/package.json index 44955363e6..fe0a0cb73e 100644 --- a/experimental/packages/api-logs/package.json +++ b/experimental/packages/api-logs/package.json @@ -83,5 +83,6 @@ "typescript": "4.4.4", "webpack": "4.46.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/api-logs" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/api-logs", + "sideEffects": false } diff --git a/experimental/packages/exporter-trace-otlp-grpc/package.json b/experimental/packages/exporter-trace-otlp-grpc/package.json index fb00a9d7b0..1bd113f7cd 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/package.json +++ b/experimental/packages/exporter-trace-otlp-grpc/package.json @@ -75,5 +75,6 @@ "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-grpc" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-grpc", + "sideEffects": false } diff --git a/experimental/packages/exporter-trace-otlp-http/package.json b/experimental/packages/exporter-trace-otlp-http/package.json index 2f07cb3436..3883b148fb 100644 --- a/experimental/packages/exporter-trace-otlp-http/package.json +++ b/experimental/packages/exporter-trace-otlp-http/package.json @@ -100,5 +100,6 @@ "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-http" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-http", + "sideEffects": false } diff --git a/experimental/packages/exporter-trace-otlp-proto/package.json b/experimental/packages/exporter-trace-otlp-proto/package.json index 83b387d958..dda47143ca 100644 --- a/experimental/packages/exporter-trace-otlp-proto/package.json +++ b/experimental/packages/exporter-trace-otlp-proto/package.json @@ -74,5 +74,6 @@ "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-proto" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-proto", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-api-metrics/package.json b/experimental/packages/opentelemetry-api-metrics/package.json index 2bc05ba2d9..3629d3de90 100644 --- a/experimental/packages/opentelemetry-api-metrics/package.json +++ b/experimental/packages/opentelemetry-api-metrics/package.json @@ -82,5 +82,6 @@ "typescript": "4.4.4", "webpack": "4.46.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-api-metrics" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-api-metrics", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json index d0b4b2054b..f4031ccf1f 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json @@ -76,5 +76,6 @@ "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-metrics": "0.33.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json index 8cae41c826..0740d5913e 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json @@ -101,5 +101,6 @@ "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-metrics": "0.33.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-http" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-http", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json index 45266a7df1..0f36c0bebb 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json @@ -76,5 +76,6 @@ "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-metrics": "0.33.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-proto" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-proto", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-exporter-prometheus/package.json b/experimental/packages/opentelemetry-exporter-prometheus/package.json index c8305d3c88..bb841bacd4 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/package.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/package.json @@ -64,5 +64,6 @@ "@opentelemetry/sdk-metrics": "0.33.0", "@opentelemetry/resources": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-prometheus" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-prometheus", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/package.json b/experimental/packages/opentelemetry-instrumentation-fetch/package.json index 03b44659b2..3e7e3336fc 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/package.json +++ b/experimental/packages/opentelemetry-instrumentation-fetch/package.json @@ -92,5 +92,6 @@ "@opentelemetry/sdk-trace-web": "1.7.0", "@opentelemetry/semantic-conventions": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-fetch" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-fetch", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/package.json b/experimental/packages/opentelemetry-instrumentation-grpc/package.json index 90e683e23b..eb1ed7c949 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/package.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/package.json @@ -75,5 +75,6 @@ "@opentelemetry/instrumentation": "0.33.0", "@opentelemetry/semantic-conventions": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-grpc" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-grpc", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index 5c4f5b21c7..ef2a792705 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -79,5 +79,6 @@ "@opentelemetry/semantic-conventions": "1.7.0", "semver": "^7.3.5" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json b/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json index 715097b692..40b340b5cd 100644 --- a/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json +++ b/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json @@ -92,5 +92,6 @@ "@opentelemetry/sdk-trace-web": "1.7.0", "@opentelemetry/semantic-conventions": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-xml-http-request" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-xml-http-request", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-instrumentation/package.json b/experimental/packages/opentelemetry-instrumentation/package.json index 102389ed51..abc09deb23 100644 --- a/experimental/packages/opentelemetry-instrumentation/package.json +++ b/experimental/packages/opentelemetry-instrumentation/package.json @@ -108,5 +108,6 @@ }, "engines": { "node": ">=14" - } + }, + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-sdk-metrics/package.json b/experimental/packages/opentelemetry-sdk-metrics/package.json index 0dbb0f9cae..f53dc3cacf 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/package.json +++ b/experimental/packages/opentelemetry-sdk-metrics/package.json @@ -82,5 +82,6 @@ "@opentelemetry/resources": "1.7.0", "lodash.merge": "4.6.2" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-metrics" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-metrics", + "sideEffects": false } diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index b531360e89..8a60ba30b7 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -78,5 +78,6 @@ "ts-mocha": "10.0.0", "typescript": "4.4.4" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-node" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-node", + "sideEffects": false } diff --git a/experimental/packages/otlp-exporter-base/package.json b/experimental/packages/otlp-exporter-base/package.json index bca5ca1f2f..0d6eadfb0b 100644 --- a/experimental/packages/otlp-exporter-base/package.json +++ b/experimental/packages/otlp-exporter-base/package.json @@ -81,5 +81,6 @@ "peerDependencies": { "@opentelemetry/api": "^1.0.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-exporter-base" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-exporter-base", + "sideEffects": false } diff --git a/experimental/packages/otlp-grpc-exporter-base/package.json b/experimental/packages/otlp-grpc-exporter-base/package.json index 7f29e1be4f..1c17da3744 100644 --- a/experimental/packages/otlp-grpc-exporter-base/package.json +++ b/experimental/packages/otlp-grpc-exporter-base/package.json @@ -76,5 +76,6 @@ "@opentelemetry/core": "1.7.0", "@opentelemetry/otlp-exporter-base": "0.33.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-grpc-exporter-base" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-grpc-exporter-base", + "sideEffects": false } diff --git a/experimental/packages/otlp-proto-exporter-base/package.json b/experimental/packages/otlp-proto-exporter-base/package.json index d41a554e10..f10673d9f3 100644 --- a/experimental/packages/otlp-proto-exporter-base/package.json +++ b/experimental/packages/otlp-proto-exporter-base/package.json @@ -68,5 +68,6 @@ "@opentelemetry/otlp-exporter-base": "0.33.0", "protobufjs": "7.1.1" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-proto-exporter-base" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-proto-exporter-base", + "sideEffects": false } diff --git a/experimental/packages/otlp-transformer/package.json b/experimental/packages/otlp-transformer/package.json index 5b24ff3971..471c94cda9 100644 --- a/experimental/packages/otlp-transformer/package.json +++ b/experimental/packages/otlp-transformer/package.json @@ -82,5 +82,6 @@ "@opentelemetry/sdk-metrics": "0.33.0", "@opentelemetry/sdk-trace-base": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-transformer" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-transformer", + "sideEffects": false } diff --git a/packages/opentelemetry-context-async-hooks/package.json b/packages/opentelemetry-context-async-hooks/package.json index 7a9385f8ce..07c85471a0 100644 --- a/packages/opentelemetry-context-async-hooks/package.json +++ b/packages/opentelemetry-context-async-hooks/package.json @@ -57,5 +57,6 @@ "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.3.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-context-async-hooks" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-context-async-hooks", + "sideEffects": false } diff --git a/packages/opentelemetry-core/package.json b/packages/opentelemetry-core/package.json index 31412164ec..8334561f5b 100644 --- a/packages/opentelemetry-core/package.json +++ b/packages/opentelemetry-core/package.json @@ -93,5 +93,6 @@ "dependencies": { "@opentelemetry/semantic-conventions": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-core" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-core", + "sideEffects": false } diff --git a/packages/opentelemetry-exporter-jaeger/package.json b/packages/opentelemetry-exporter-jaeger/package.json index dc926c5695..0578ba2643 100644 --- a/packages/opentelemetry-exporter-jaeger/package.json +++ b/packages/opentelemetry-exporter-jaeger/package.json @@ -67,5 +67,6 @@ "@opentelemetry/semantic-conventions": "1.7.0", "jaeger-client": "^3.15.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-exporter-jaeger" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-exporter-jaeger", + "sideEffects": false } diff --git a/packages/opentelemetry-exporter-zipkin/package.json b/packages/opentelemetry-exporter-zipkin/package.json index 15ce13dbc4..fbed197c0d 100644 --- a/packages/opentelemetry-exporter-zipkin/package.json +++ b/packages/opentelemetry-exporter-zipkin/package.json @@ -96,5 +96,6 @@ "@opentelemetry/sdk-trace-base": "1.7.0", "@opentelemetry/semantic-conventions": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-exporter-zipkin" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-exporter-zipkin", + "sideEffects": false } diff --git a/packages/opentelemetry-propagator-b3/package.json b/packages/opentelemetry-propagator-b3/package.json index 97e44060c8..a54d56e95e 100644 --- a/packages/opentelemetry-propagator-b3/package.json +++ b/packages/opentelemetry-propagator-b3/package.json @@ -69,5 +69,6 @@ "ts-mocha": "10.0.0", "typescript": "4.4.4" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-b3" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-b3", + "sideEffects": false } diff --git a/packages/opentelemetry-propagator-jaeger/package.json b/packages/opentelemetry-propagator-jaeger/package.json index c85137a3d1..98aba129a6 100644 --- a/packages/opentelemetry-propagator-jaeger/package.json +++ b/packages/opentelemetry-propagator-jaeger/package.json @@ -82,5 +82,6 @@ "dependencies": { "@opentelemetry/core": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-jaeger" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-jaeger", + "sideEffects": false } diff --git a/packages/opentelemetry-resources/package.json b/packages/opentelemetry-resources/package.json index e834d693a1..84cb29a7af 100644 --- a/packages/opentelemetry-resources/package.json +++ b/packages/opentelemetry-resources/package.json @@ -92,5 +92,6 @@ "@opentelemetry/core": "1.7.0", "@opentelemetry/semantic-conventions": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-resources" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-resources", + "sideEffects": false } diff --git a/packages/opentelemetry-sdk-trace-base/package.json b/packages/opentelemetry-sdk-trace-base/package.json index 5c8e879958..a062b9c4d7 100644 --- a/packages/opentelemetry-sdk-trace-base/package.json +++ b/packages/opentelemetry-sdk-trace-base/package.json @@ -95,5 +95,6 @@ "@opentelemetry/resources": "1.7.0", "@opentelemetry/semantic-conventions": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-base" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-base", + "sideEffects": false } diff --git a/packages/opentelemetry-sdk-trace-node/package.json b/packages/opentelemetry-sdk-trace-node/package.json index 0c5b86ba7a..cbf5bd9e37 100644 --- a/packages/opentelemetry-sdk-trace-node/package.json +++ b/packages/opentelemetry-sdk-trace-node/package.json @@ -71,5 +71,6 @@ "@opentelemetry/sdk-trace-base": "1.7.0", "semver": "^7.3.5" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node", + "sideEffects": false } diff --git a/packages/opentelemetry-sdk-trace-web/package.json b/packages/opentelemetry-sdk-trace-web/package.json index 3c8d18b65b..65afa52b30 100644 --- a/packages/opentelemetry-sdk-trace-web/package.json +++ b/packages/opentelemetry-sdk-trace-web/package.json @@ -95,5 +95,6 @@ "@opentelemetry/sdk-trace-base": "1.7.0", "@opentelemetry/semantic-conventions": "1.7.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web", + "sideEffects": false } diff --git a/packages/opentelemetry-semantic-conventions/package.json b/packages/opentelemetry-semantic-conventions/package.json index b9e59edd16..c7cbcc040b 100644 --- a/packages/opentelemetry-semantic-conventions/package.json +++ b/packages/opentelemetry-semantic-conventions/package.json @@ -61,5 +61,6 @@ "ts-mocha": "10.0.0", "typescript": "4.4.4" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-semantic-conventions" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-semantic-conventions", + "sideEffects": false } diff --git a/packages/opentelemetry-shim-opentracing/package.json b/packages/opentelemetry-shim-opentracing/package.json index 51ea010f0f..f73fb08774 100644 --- a/packages/opentelemetry-shim-opentracing/package.json +++ b/packages/opentelemetry-shim-opentracing/package.json @@ -63,5 +63,6 @@ "@opentelemetry/semantic-conventions": "1.7.0", "opentracing": "^0.14.4" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-shim-opentracing" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-shim-opentracing", + "sideEffects": false } diff --git a/packages/template/package.json b/packages/template/package.json index 6b8cc9759e..77493ccde3 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -68,6 +68,7 @@ "LICENSE", "README.md" ], + "sideEffects": false, "Add these to files if browser is supported": [ "build/esm/**/*.js", "build/esm/**/*.js.map", From bbc1811b02df1194aa50dec590c05339bb633774 Mon Sep 17 00:00:00 2001 From: Marc Hassan Date: Thu, 20 Oct 2022 15:51:42 -0400 Subject: [PATCH 48/77] feat(instrumentation): implement `require-in-the-middle` singleton (#3161) Co-authored-by: Daniel Dyla Co-authored-by: Rauno Viskus --- experimental/CHANGELOG.md | 1 + .../src/platform/node/ModuleNameTrie.ts | 86 ++++++++++++ .../node/RequireInTheMiddleSingleton.ts | 111 +++++++++++++++ .../src/platform/node/instrumentation.ts | 10 +- .../test/node/ModuleNameTrie.test.ts | 68 ++++++++++ .../node/RequireInTheMiddleSingleton.test.ts | 126 ++++++++++++++++++ 6 files changed, 397 insertions(+), 5 deletions(-) create mode 100644 experimental/packages/opentelemetry-instrumentation/src/platform/node/ModuleNameTrie.ts create mode 100644 experimental/packages/opentelemetry-instrumentation/src/platform/node/RequireInTheMiddleSingleton.ts create mode 100644 experimental/packages/opentelemetry-instrumentation/test/node/ModuleNameTrie.test.ts create mode 100644 experimental/packages/opentelemetry-instrumentation/test/node/RequireInTheMiddleSingleton.test.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 688384d220..f9ead87184 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) +* feat(instrumentation): implement `require-in-the-middle` singleton [#3161](https://github.com/open-telemetry/opentelemetry-js/pull/3161) @mhassan1 * feat(sdk-node): configure trace exporter with environment variables [#3143](https://github.com/open-telemetry/opentelemetry-js/pull/3143) @svetlanabrennan * feat: enable tree shaking [#3329](https://github.com/open-telemetry/opentelemetry-js/pull/3329) @pkanal * feat(prometheus): serialize resource as target_info gauge [#3300](https://github.com/open-telemetry/opentelemetry-js/pull/3300) @pichlermarc diff --git a/experimental/packages/opentelemetry-instrumentation/src/platform/node/ModuleNameTrie.ts b/experimental/packages/opentelemetry-instrumentation/src/platform/node/ModuleNameTrie.ts new file mode 100644 index 0000000000..3230fea99c --- /dev/null +++ b/experimental/packages/opentelemetry-instrumentation/src/platform/node/ModuleNameTrie.ts @@ -0,0 +1,86 @@ +/* + * 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 type { Hooked } from './RequireInTheMiddleSingleton'; + +export const ModuleNameSeparator = '/'; + +/** + * Node in a `ModuleNameTrie` + */ +class ModuleNameTrieNode { + hooks: Array<{ hook: Hooked, insertedId: number }> = []; + children: Map = new Map(); +} + +/** + * Trie containing nodes that represent a part of a module name (i.e. the parts separated by forward slash) + */ +export class ModuleNameTrie { + private _trie: ModuleNameTrieNode = new ModuleNameTrieNode(); + private _counter: number = 0; + + /** + * Insert a module hook into the trie + * + * @param {Hooked} hook Hook + */ + insert(hook: Hooked) { + let trieNode = this._trie; + + for (const moduleNamePart of hook.moduleName.split(ModuleNameSeparator)) { + let nextNode = trieNode.children.get(moduleNamePart); + if (!nextNode) { + nextNode = new ModuleNameTrieNode(); + trieNode.children.set(moduleNamePart, nextNode); + } + trieNode = nextNode; + } + trieNode.hooks.push({ hook, insertedId: this._counter++ }); + } + + /** + * Search for matching hooks in the trie + * + * @param {string} moduleName Module name + * @param {boolean} maintainInsertionOrder Whether to return the results in insertion order + * @returns {Hooked[]} Matching hooks + */ + search(moduleName: string, { maintainInsertionOrder }: { maintainInsertionOrder?: boolean } = {}): Hooked[] { + let trieNode = this._trie; + const results: ModuleNameTrieNode['hooks'] = []; + + for (const moduleNamePart of moduleName.split(ModuleNameSeparator)) { + const nextNode = trieNode.children.get(moduleNamePart); + if (!nextNode) { + break; + } + results.push(...nextNode.hooks); + trieNode = nextNode; + } + + if (results.length === 0) { + return []; + } + if (results.length === 1) { + return [results[0].hook]; + } + if (maintainInsertionOrder) { + results.sort((a, b) => a.insertedId - b.insertedId); + } + return results.map(({ hook }) => hook); + } +} diff --git a/experimental/packages/opentelemetry-instrumentation/src/platform/node/RequireInTheMiddleSingleton.ts b/experimental/packages/opentelemetry-instrumentation/src/platform/node/RequireInTheMiddleSingleton.ts new file mode 100644 index 0000000000..812db52b68 --- /dev/null +++ b/experimental/packages/opentelemetry-instrumentation/src/platform/node/RequireInTheMiddleSingleton.ts @@ -0,0 +1,111 @@ +/* + * 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 RequireInTheMiddle from 'require-in-the-middle'; +import * as path from 'path'; +import { ModuleNameTrie, ModuleNameSeparator } from './ModuleNameTrie'; + +export type Hooked = { + moduleName: string + onRequire: RequireInTheMiddle.OnRequireFn +}; + +/** + * Whether Mocha is running in this process + * Inspired by https://github.com/AndreasPizsa/detect-mocha + * + * @type {boolean} + */ +const isMocha = ['afterEach','after','beforeEach','before','describe','it'].every(fn => { + // @ts-expect-error TS7053: Element implicitly has an 'any' type + return typeof global[fn] === 'function'; +}); + +/** + * Singleton class for `require-in-the-middle` + * Allows instrumentation plugins to patch modules with only a single `require` patch + * WARNING: Because this class will create its own `require-in-the-middle` (RITM) instance, + * we should minimize the number of new instances of this class. + * Multiple instances of `@opentelemetry/instrumentation` (e.g. multiple versions) in a single process + * will result in multiple instances of RITM, which will have an impact + * on the performance of instrumentation hooks being applied. + */ +export class RequireInTheMiddleSingleton { + private _moduleNameTrie: ModuleNameTrie = new ModuleNameTrie(); + private static _instance?: RequireInTheMiddleSingleton; + + private constructor() { + this._initialize(); + } + + private _initialize() { + RequireInTheMiddle( + // Intercept all `require` calls; we will filter the matching ones below + null, + { internals: true }, + (exports, name, basedir) => { + // For internal files on Windows, `name` will use backslash as the path separator + const normalizedModuleName = normalizePathSeparators(name); + + const matches = this._moduleNameTrie.search(normalizedModuleName, { maintainInsertionOrder: true }); + + for (const { onRequire } of matches) { + exports = onRequire(exports, name, basedir); + } + + return exports; + } + ); + } + + /** + * Register a hook with `require-in-the-middle` + * + * @param {string} moduleName Module name + * @param {RequireInTheMiddle.OnRequireFn} onRequire Hook function + * @returns {Hooked} Registered hook + */ + register(moduleName: string, onRequire: RequireInTheMiddle.OnRequireFn): Hooked { + const hooked = { moduleName, onRequire }; + this._moduleNameTrie.insert(hooked); + return hooked; + } + + /** + * Get the `RequireInTheMiddleSingleton` singleton + * + * @returns {RequireInTheMiddleSingleton} Singleton of `RequireInTheMiddleSingleton` + */ + static getInstance(): RequireInTheMiddleSingleton { + // Mocha runs all test suites in the same process + // This prevents test suites from sharing a singleton + if (isMocha) return new RequireInTheMiddleSingleton(); + + return this._instance = this._instance ?? new RequireInTheMiddleSingleton(); + } +} + +/** + * Normalize the path separators to forward slash in a module name or path + * + * @param {string} moduleNameOrPath Module name or path + * @returns {string} Normalized module name or path + */ +function normalizePathSeparators(moduleNameOrPath: string): string { + return path.sep !== ModuleNameSeparator + ? moduleNameOrPath.split(path.sep).join(ModuleNameSeparator) + : moduleNameOrPath; +} diff --git a/experimental/packages/opentelemetry-instrumentation/src/platform/node/instrumentation.ts b/experimental/packages/opentelemetry-instrumentation/src/platform/node/instrumentation.ts index 5bc0921778..d80985431c 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/platform/node/instrumentation.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/platform/node/instrumentation.ts @@ -16,9 +16,9 @@ import * as types from '../../types'; import * as path from 'path'; -import * as RequireInTheMiddle from 'require-in-the-middle'; import { satisfies } from 'semver'; import { InstrumentationAbstract } from '../../instrumentation'; +import { RequireInTheMiddleSingleton, Hooked } from './RequireInTheMiddleSingleton'; import { InstrumentationModuleDefinition } from './types'; import { diag } from '@opentelemetry/api'; @@ -29,7 +29,8 @@ export abstract class InstrumentationBase extends InstrumentationAbstract implements types.Instrumentation { private _modules: InstrumentationModuleDefinition[]; - private _hooks: RequireInTheMiddle.Hooked[] = []; + private _hooks: Hooked[] = []; + private _requireInTheMiddleSingleton: RequireInTheMiddleSingleton = RequireInTheMiddleSingleton.getInstance(); private _enabled = false; constructor( @@ -160,9 +161,8 @@ export abstract class InstrumentationBase this._warnOnPreloadedModules(); for (const module of this._modules) { this._hooks.push( - RequireInTheMiddle( - [module.name], - { internals: true }, + this._requireInTheMiddleSingleton.register( + module.name, (exports, name, baseDir) => { return this._onRequire( (module as unknown) as InstrumentationModuleDefinition< diff --git a/experimental/packages/opentelemetry-instrumentation/test/node/ModuleNameTrie.test.ts b/experimental/packages/opentelemetry-instrumentation/test/node/ModuleNameTrie.test.ts new file mode 100644 index 0000000000..c3d72c89d7 --- /dev/null +++ b/experimental/packages/opentelemetry-instrumentation/test/node/ModuleNameTrie.test.ts @@ -0,0 +1,68 @@ +/* + * 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 { Hooked } from '../../src/platform/node/RequireInTheMiddleSingleton'; +import { ModuleNameTrie } from '../../src/platform/node/ModuleNameTrie'; + +describe('ModuleNameTrie', () => { + describe('search', () => { + const trie = new ModuleNameTrie(); + const inserts = [ + { moduleName: 'a', onRequire: () => {} }, + { moduleName: 'a/b', onRequire: () => {} }, + { moduleName: 'a', onRequire: () => {} }, + { moduleName: 'a/c', onRequire: () => {} }, + { moduleName: 'd', onRequire: () => {} } + ] as Hooked[]; + inserts.forEach(trie.insert.bind(trie)); + + it('should return a list of exact matches (no results)', () => { + assert.deepEqual(trie.search('e'), []); + }); + + it('should return a list of exact matches (one result)', () => { + assert.deepEqual(trie.search('d'), [inserts[4]]); + }); + + it('should return a list of exact matches (more than one result)', () => { + assert.deepEqual(trie.search('a'), [ + inserts[0], + inserts[2] + ]); + }); + + describe('maintainInsertionOrder = false', () => { + it('should return a list of matches in prefix order', () => { + assert.deepEqual(trie.search('a/b'), [ + inserts[0], + inserts[2], + inserts[1] + ]); + }); + }); + + describe('maintainInsertionOrder = true', () => { + it('should return a list of matches in insertion order', () => { + assert.deepEqual(trie.search('a/b', { maintainInsertionOrder: true }), [ + inserts[0], + inserts[1], + inserts[2] + ]); + }); + }); + }); +}); diff --git a/experimental/packages/opentelemetry-instrumentation/test/node/RequireInTheMiddleSingleton.test.ts b/experimental/packages/opentelemetry-instrumentation/test/node/RequireInTheMiddleSingleton.test.ts new file mode 100644 index 0000000000..724dced720 --- /dev/null +++ b/experimental/packages/opentelemetry-instrumentation/test/node/RequireInTheMiddleSingleton.test.ts @@ -0,0 +1,126 @@ +/* + * 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 * as sinon from 'sinon'; +import * as path from 'path'; +import * as RequireInTheMiddle from 'require-in-the-middle'; +import { RequireInTheMiddleSingleton } from '../../src/platform/node/RequireInTheMiddleSingleton'; + +const requireInTheMiddleSingleton = RequireInTheMiddleSingleton.getInstance(); + +type AugmentedExports = { + __ritmOnRequires?: string[] +}; + +const makeOnRequiresStub = (label: string): sinon.SinonStub => sinon.stub().callsFake(((exports: AugmentedExports) => { + exports.__ritmOnRequires ??= []; + exports.__ritmOnRequires.push(label); + return exports; +}) as RequireInTheMiddle.OnRequireFn); + +describe('RequireInTheMiddleSingleton', () => { + describe('register', () => { + const onRequireFsStub = makeOnRequiresStub('fs'); + const onRequireFsPromisesStub = makeOnRequiresStub('fs-promises'); + const onRequireCodecovStub = makeOnRequiresStub('codecov'); + const onRequireCodecovLibStub = makeOnRequiresStub('codecov-lib'); + const onRequireCpxStub = makeOnRequiresStub('cpx'); + const onRequireCpxLibStub = makeOnRequiresStub('cpx-lib'); + + before(() => { + requireInTheMiddleSingleton.register('fs', onRequireFsStub); + requireInTheMiddleSingleton.register('fs/promises', onRequireFsPromisesStub); + requireInTheMiddleSingleton.register('codecov', onRequireCodecovStub); + requireInTheMiddleSingleton.register('codecov/lib/codecov.js', onRequireCodecovLibStub); + requireInTheMiddleSingleton.register('cpx', onRequireCpxStub); + requireInTheMiddleSingleton.register('cpx/lib/copy-sync.js', onRequireCpxLibStub); + }); + + beforeEach(() => { + onRequireFsStub.resetHistory(); + onRequireFsPromisesStub.resetHistory(); + onRequireCodecovStub.resetHistory(); + onRequireCodecovLibStub.resetHistory(); + onRequireCpxStub.resetHistory(); + onRequireCpxLibStub.resetHistory(); + }); + + it('should return a hooked object', () => { + const moduleName = 'm'; + const onRequire = makeOnRequiresStub('m'); + const hooked = requireInTheMiddleSingleton.register(moduleName, onRequire); + assert.deepStrictEqual(hooked, { moduleName, onRequire }); + }); + + describe('core module', () => { + describe('AND module name matches', () => { + it('should call `onRequire`', () => { + const exports = require('fs'); + assert.deepStrictEqual(exports.__ritmOnRequires, ['fs']); + sinon.assert.calledOnceWithExactly(onRequireFsStub, exports, 'fs', undefined); + sinon.assert.notCalled(onRequireFsPromisesStub); + }); + }); + describe('AND module name does not match', () => { + it('should not call `onRequire`', () => { + const exports = require('crypto'); + assert.equal(exports.__ritmOnRequires, undefined); + sinon.assert.notCalled(onRequireFsStub); + }); + }); + }); + + describe('core module with sub-path', () => { + describe('AND module name matches', () => { + it('should call `onRequire`', () => { + const exports = require('fs/promises'); + assert.deepStrictEqual(exports.__ritmOnRequires, ['fs', 'fs-promises']); + sinon.assert.calledOnceWithExactly(onRequireFsPromisesStub, exports, 'fs/promises', undefined); + sinon.assert.calledOnceWithMatch(onRequireFsStub, { __ritmOnRequires: ['fs', 'fs-promises'] }, 'fs/promises', undefined); + }); + }); + }); + + describe('non-core module', () => { + describe('AND module name matches', () => { + const baseDir = path.dirname(require.resolve('codecov')); + const modulePath = path.join('codecov', 'lib', 'codecov.js'); + it('should call `onRequire`', () => { + const exports = require('codecov'); + assert.deepStrictEqual(exports.__ritmOnRequires, ['codecov']); + sinon.assert.calledWithExactly(onRequireCodecovStub, exports, 'codecov', baseDir); + sinon.assert.calledWithMatch(onRequireCodecovStub, { __ritmOnRequires: ['codecov', 'codecov-lib'] }, modulePath, baseDir); + sinon.assert.calledWithMatch(onRequireCodecovLibStub, { __ritmOnRequires: ['codecov', 'codecov-lib'] }, modulePath, baseDir); + }).timeout(30000); + }); + }); + + describe('non-core module with sub-path', () => { + describe('AND module name matches', () => { + const baseDir = path.resolve(path.dirname(require.resolve('cpx')), '..'); + const modulePath = path.join('cpx', 'lib', 'copy-sync.js'); + it('should call `onRequire`', () => { + const exports = require('cpx/lib/copy-sync'); + assert.deepStrictEqual(exports.__ritmOnRequires, ['cpx', 'cpx-lib']); + sinon.assert.calledWithMatch(onRequireCpxStub, { __ritmOnRequires: ['cpx', 'cpx-lib'] }, modulePath, baseDir); + sinon.assert.calledWithExactly(onRequireCpxStub, exports, modulePath, baseDir); + sinon.assert.calledWithExactly(onRequireCpxLibStub, exports, modulePath, baseDir); + }); + }); + }); + }); +}); From 292a53df665be48c1425eca371397c9f00ae9e44 Mon Sep 17 00:00:00 2001 From: Hector Hernandez <39923391+hectorhdzg@users.noreply.github.com> Date: Thu, 20 Oct 2022 18:56:29 -0700 Subject: [PATCH 49/77] feat: add tracing suppresing for Metrics Export (#3332) --- experimental/CHANGELOG.md | 1 + .../export/PeriodicExportingMetricReader.ts | 21 +++------ packages/opentelemetry-core/src/index.ts | 4 ++ .../src/internal/exporter.ts | 38 ++++++++++++++++ .../test/internal/exporter.test.ts | 43 +++++++++++++++++++ .../src/export/SimpleSpanProcessor.ts | 30 ++++++------- 6 files changed, 108 insertions(+), 29 deletions(-) create mode 100644 packages/opentelemetry-core/src/internal/exporter.ts create mode 100644 packages/opentelemetry-core/test/internal/exporter.test.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index f9ead87184..b25c11fb3c 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) +* feat(metrics-sdk): Add tracing suppresing for Metrics Export [#3332](https://github.com/open-telemetry/opentelemetry-js/pull/3332) @hectorhdzg * feat(instrumentation): implement `require-in-the-middle` singleton [#3161](https://github.com/open-telemetry/opentelemetry-js/pull/3161) @mhassan1 * feat(sdk-node): configure trace exporter with environment variables [#3143](https://github.com/open-telemetry/opentelemetry-js/pull/3143) @svetlanabrennan * feat: enable tree shaking [#3329](https://github.com/open-telemetry/opentelemetry-js/pull/3329) @pkanal diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts index e4f78d1cf0..2a686181cc 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts @@ -16,6 +16,7 @@ import * as api from '@opentelemetry/api'; import { + internal, ExportResultCode, globalErrorHandler, unrefTimer @@ -85,20 +86,12 @@ export class PeriodicExportingMetricReader extends MetricReader { api.diag.error('PeriodicExportingMetricReader: metrics collection errors', ...errors); } - return new Promise((resolve, reject) => { - this._exporter.export(resourceMetrics, result => { - if (result.code !== ExportResultCode.SUCCESS) { - reject( - result.error ?? - new Error( - `PeriodicExportingMetricReader: metrics export failed (error ${result.error})` - ) - ); - } else { - resolve(); - } - }); - }); + const result = await internal._export(this._exporter, resourceMetrics); + if (result.code !== ExportResultCode.SUCCESS) { + throw new Error( + `PeriodicExportingMetricReader: metrics export failed (error ${result.error})` + ); + } } protected override onInitialized(): void { diff --git a/packages/opentelemetry-core/src/index.ts b/packages/opentelemetry-core/src/index.ts index fd8d3c6778..6c0834fe0f 100644 --- a/packages/opentelemetry-core/src/index.ts +++ b/packages/opentelemetry-core/src/index.ts @@ -42,3 +42,7 @@ export * from './utils/url'; export * from './utils/wrap'; export * from './utils/callback'; export * from './version'; +import { _export } from './internal/exporter'; +export const internal = { + _export +}; diff --git a/packages/opentelemetry-core/src/internal/exporter.ts b/packages/opentelemetry-core/src/internal/exporter.ts new file mode 100644 index 0000000000..a489b35eac --- /dev/null +++ b/packages/opentelemetry-core/src/internal/exporter.ts @@ -0,0 +1,38 @@ +/* + * 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 } from '@opentelemetry/api'; +import { ExportResult } from '../ExportResult'; +import { suppressTracing } from '../trace/suppress-tracing'; + +export interface Exporter { + export(arg: T, resultCallback: (result: ExportResult) => void): void; +} + +/** +* @internal +* Shared functionality used by Exporters while exporting data, including suppresion of Traces. +*/ +export function _export(exporter: Exporter, arg: T): Promise { + return new Promise(resolve => { + // prevent downstream exporter calls from generating spans + context.with(suppressTracing(context.active()), () => { + exporter.export(arg, (result: ExportResult) => { + resolve(result); + }); + }); + }); +} diff --git a/packages/opentelemetry-core/test/internal/exporter.test.ts b/packages/opentelemetry-core/test/internal/exporter.test.ts new file mode 100644 index 0000000000..1ca256d659 --- /dev/null +++ b/packages/opentelemetry-core/test/internal/exporter.test.ts @@ -0,0 +1,43 @@ +/* + * 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 * as sinon from 'sinon'; +import { ExportResult, ExportResultCode } from '../../src'; +import * as suppress from '../../src/trace/suppress-tracing'; +import { _export } from '../../src/internal/exporter'; + +describe('exporter', () => { + const sandbox = sinon.createSandbox(); + + afterEach(() => { + sandbox.restore(); + }); + + class TestExporter { + export(arg: any, resultCallback: (result: ExportResult) => void) { + resultCallback({ code: ExportResultCode.SUCCESS }); + } + } + + it('_export should suppress tracing', async () => { + const suppressSpy = sandbox.spy(suppress, 'suppressTracing'); + const exporter = new TestExporter(); + const result = await _export(exporter, ['Test1']); + assert.strictEqual(result.code, ExportResultCode.SUCCESS); + assert.ok(suppressSpy.calledOnce); + }); +}); diff --git a/packages/opentelemetry-sdk-trace-base/src/export/SimpleSpanProcessor.ts b/packages/opentelemetry-sdk-trace-base/src/export/SimpleSpanProcessor.ts index c775bdf6d4..a510ad02a6 100644 --- a/packages/opentelemetry-sdk-trace-base/src/export/SimpleSpanProcessor.ts +++ b/packages/opentelemetry-sdk-trace-base/src/export/SimpleSpanProcessor.ts @@ -14,12 +14,13 @@ * limitations under the License. */ -import { context, Context, TraceFlags } from '@opentelemetry/api'; +import { Context, TraceFlags } from '@opentelemetry/api'; import { + internal, ExportResultCode, globalErrorHandler, - suppressTracing, BindOnceFuture, + ExportResult } from '@opentelemetry/core'; import { Span } from '../Span'; import { SpanProcessor } from '../SpanProcessor'; @@ -45,7 +46,7 @@ export class SimpleSpanProcessor implements SpanProcessor { } // does nothing. - onStart(_span: Span, _parentContext: Context): void {} + onStart(_span: Span, _parentContext: Context): void { } onEnd(span: ReadableSpan): void { if (this._shutdownOnce.isCalled) { @@ -56,18 +57,17 @@ export class SimpleSpanProcessor implements SpanProcessor { return; } - // prevent downstream exporter calls from generating spans - context.with(suppressTracing(context.active()), () => { - this._exporter.export([span], result => { - if (result.code !== ExportResultCode.SUCCESS) { - globalErrorHandler( - result.error ?? - new Error( - `SimpleSpanProcessor: span export failed (status ${result})` - ) - ); - } - }); + internal._export(this._exporter, [span]).then((result: ExportResult) => { + if (result.code !== ExportResultCode.SUCCESS) { + globalErrorHandler( + result.error ?? + new Error( + `SimpleSpanProcessor: span export failed (status ${result})` + ) + ); + } + }).catch(error => { + globalErrorHandler(error); }); } From 30a81bdcd7243db1764d7a9f214f861f92f4ed45 Mon Sep 17 00:00:00 2001 From: Siim Kallas Date: Fri, 21 Oct 2022 12:34:29 +0300 Subject: [PATCH 50/77] chore: fix grpc and proto-loader deps (#3337) * chore: fix grpc and proto-looader deps * doc: update changelog --- experimental/CHANGELOG.md | 1 + experimental/packages/exporter-trace-otlp-grpc/package.json | 4 ++-- experimental/packages/exporter-trace-otlp-proto/package.json | 1 - .../opentelemetry-exporter-metrics-otlp-grpc/package.json | 4 ++-- .../opentelemetry-exporter-metrics-otlp-proto/package.json | 1 - .../packages/opentelemetry-instrumentation-grpc/package.json | 4 ++-- experimental/packages/otlp-grpc-exporter-base/package.json | 4 ++-- experimental/packages/otlp-proto-exporter-base/package.json | 1 - 8 files changed, 9 insertions(+), 11 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index b25c11fb3c..44e89e8133 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to experimental packages in this project will be documented * feat(sdk-node): configure trace exporter with environment variables [#3143](https://github.com/open-telemetry/opentelemetry-js/pull/3143) @svetlanabrennan * feat: enable tree shaking [#3329](https://github.com/open-telemetry/opentelemetry-js/pull/3329) @pkanal * feat(prometheus): serialize resource as target_info gauge [#3300](https://github.com/open-telemetry/opentelemetry-js/pull/3300) @pichlermarc +* deps: remove unused proto-loader dependencies and update grpc-js and proto-loader versions [#3337](https://github.com/open-telemetry/opentelemetry-js/pull/3337) @seemk ### :bug: (Bug Fix) diff --git a/experimental/packages/exporter-trace-otlp-grpc/package.json b/experimental/packages/exporter-trace-otlp-grpc/package.json index 1bd113f7cd..05ba15892c 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/package.json +++ b/experimental/packages/exporter-trace-otlp-grpc/package.json @@ -48,6 +48,7 @@ }, "devDependencies": { "@babel/core": "7.16.0", + "@grpc/proto-loader": "^0.7.3", "@opentelemetry/api": "^1.0.0", "@opentelemetry/otlp-exporter-base": "0.33.0", "@types/mocha": "10.0.0", @@ -67,8 +68,7 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@grpc/grpc-js": "^1.5.9", - "@grpc/proto-loader": "^0.6.9", + "@grpc/grpc-js": "^1.7.1", "@opentelemetry/core": "1.7.0", "@opentelemetry/otlp-grpc-exporter-base": "0.33.0", "@opentelemetry/otlp-transformer": "0.33.0", diff --git a/experimental/packages/exporter-trace-otlp-proto/package.json b/experimental/packages/exporter-trace-otlp-proto/package.json index dda47143ca..b9a6927640 100644 --- a/experimental/packages/exporter-trace-otlp-proto/package.json +++ b/experimental/packages/exporter-trace-otlp-proto/package.json @@ -66,7 +66,6 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@grpc/proto-loader": "^0.6.9", "@opentelemetry/core": "1.7.0", "@opentelemetry/otlp-exporter-base": "0.33.0", "@opentelemetry/otlp-proto-exporter-base": "0.33.0", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json index f4031ccf1f..d7dc5a21a8 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json @@ -48,6 +48,7 @@ }, "devDependencies": { "@babel/core": "7.16.0", + "@grpc/proto-loader": "^0.7.3", "@opentelemetry/api": "^1.0.0", "@opentelemetry/api-metrics": "0.33.0", "@types/mocha": "10.0.0", @@ -67,8 +68,7 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@grpc/grpc-js": "^1.5.9", - "@grpc/proto-loader": "^0.6.9", + "@grpc/grpc-js": "^1.7.1", "@opentelemetry/core": "1.7.0", "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", "@opentelemetry/otlp-grpc-exporter-base": "0.33.0", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json index 0f36c0bebb..bad7943e6e 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json @@ -67,7 +67,6 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@grpc/proto-loader": "0.6.9", "@opentelemetry/core": "1.7.0", "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", "@opentelemetry/otlp-exporter-base": "0.33.0", diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/package.json b/experimental/packages/opentelemetry-instrumentation-grpc/package.json index eb1ed7c949..8d9f69ef1c 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/package.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/package.json @@ -45,8 +45,8 @@ "access": "public" }, "devDependencies": { - "@grpc/grpc-js": "1.5.9", - "@grpc/proto-loader": "0.6.9", + "@grpc/grpc-js": "^1.7.1", + "@grpc/proto-loader": "^0.7.3", "@opentelemetry/api": "^1.0.0", "@opentelemetry/context-async-hooks": "1.7.0", "@opentelemetry/core": "1.7.0", diff --git a/experimental/packages/otlp-grpc-exporter-base/package.json b/experimental/packages/otlp-grpc-exporter-base/package.json index 1c17da3744..b164cec8dd 100644 --- a/experimental/packages/otlp-grpc-exporter-base/package.json +++ b/experimental/packages/otlp-grpc-exporter-base/package.json @@ -71,8 +71,8 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@grpc/grpc-js": "^1.5.9", - "@grpc/proto-loader": "^0.6.9", + "@grpc/grpc-js": "^1.7.1", + "@grpc/proto-loader": "^0.7.3", "@opentelemetry/core": "1.7.0", "@opentelemetry/otlp-exporter-base": "0.33.0" }, diff --git a/experimental/packages/otlp-proto-exporter-base/package.json b/experimental/packages/otlp-proto-exporter-base/package.json index f10673d9f3..aaec196080 100644 --- a/experimental/packages/otlp-proto-exporter-base/package.json +++ b/experimental/packages/otlp-proto-exporter-base/package.json @@ -63,7 +63,6 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@grpc/proto-loader": "^0.6.9", "@opentelemetry/core": "1.7.0", "@opentelemetry/otlp-exporter-base": "0.33.0", "protobufjs": "7.1.1" From 4420402e166c844c539c4831a3a349622c0bf81a Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Mon, 24 Oct 2022 15:10:32 +0200 Subject: [PATCH 51/77] feat(metrics-exporters): configure temporality via env var(#3305) Co-authored-by: Daniel Dyla --- experimental/CHANGELOG.md | 1 + .../README.md | 43 +++++++------ .../src/OTLPMetricExporter.ts | 5 +- .../README.md | 46 ++++++-------- .../src/OTLPMetricExporterBase.ts | 37 ++++++++++-- .../src/OTLPMetricExporterOptions.ts | 2 - .../platform/browser/OTLPMetricExporter.ts | 6 +- .../src/platform/node/OTLPMetricExporter.ts | 6 +- .../common/CollectorMetricExporter.test.ts | 26 +++++--- .../test/node/CollectorMetricExporter.test.ts | 60 ++++++++++++++++--- .../README.md | 13 ++++ .../src/OTLPMetricExporter.ts | 5 +- .../src/utils/environment.ts | 2 + 13 files changed, 169 insertions(+), 83 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 44e89e8133..7913109e53 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to experimental packages in this project will be documented * feat: enable tree shaking [#3329](https://github.com/open-telemetry/opentelemetry-js/pull/3329) @pkanal * feat(prometheus): serialize resource as target_info gauge [#3300](https://github.com/open-telemetry/opentelemetry-js/pull/3300) @pichlermarc * deps: remove unused proto-loader dependencies and update grpc-js and proto-loader versions [#3337](https://github.com/open-telemetry/opentelemetry-js/pull/3337) @seemk +* feat(metrics-exporters): configure temporality via environment variable [#3305](https://github.com/open-telemetry/opentelemetry-js/pull/3305) @pichlermarc ### :bug: (Bug Fix) diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md index e00bf05e41..3aee8d08a4 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md @@ -17,16 +17,19 @@ npm install --save @opentelemetry/exporter-metrics-otlp-grpc ## Service Name The OpenTelemetry Collector Exporter does not have a service name configuration. -In order to set the service name, use the `service.name` resource attribute as prescribed in the [OpenTelemetry Resource Semantic Conventions][semconv-resource-service-name]. -To see sample code and documentation for the traces exporter, as well as instructions for using TLS, visit the [Collector Trace Exporter for web and node][trace-exporter-url]. +In order to set the service name, use the `service.name` resource attribute as prescribed in +the [OpenTelemetry Resource Semantic Conventions][semconv-resource-service-name]. +To see sample code and documentation for the traces exporter, as well as instructions for using TLS, visit +the [Collector Trace Exporter for web and node][trace-exporter-url]. ## Metrics in Node - GRPC -The OTLPMetricsExporter in Node expects the URL to only be the hostname. It will not work with `/v1/metrics`. All options that work with trace also work with metrics. +The OTLPMetricsExporter in Node expects the URL to only be the hostname. It will not work with `/v1/metrics`. All +options that work with trace also work with metrics. ```js const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); -const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc'); +const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc'); const collectorOptions = { // url is optional and can be omitted - default is http://localhost:4317 url: 'http://:', @@ -52,20 +55,24 @@ counter.add(10, { 'key': 'value' }); ## Environment Variable Configuration - | Environment variable | Description | - |----------------------|-------------| - | OTEL_EXPORTER_OTLP_METRICS_COMPRESSION | The compression type to use on OTLP metric requests. Options include gzip. By default no compression will be used. | - | OTEL_EXPORTER_OTLP_COMPRESSION | The compression type to use on OTLP trace, metric, and log requests. Options include gzip. By default no compression will be used. | - | OTEL_EXPORTER_OTLP_METRICS_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for metric requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. | - | OTEL_EXPORTER_OTLP_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for trace, metric and log requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. | - | OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP metric server's TLS credentials. By default the host platform's trusted root certificate is used.| - | OTEL_EXPORTER_OTLP_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP trace, metric, or log server's TLS credentials. By default the host platform's trusted root certificate is used. | - | OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP metric client's TLS credentials. Must provide a client certificate/chain when providing a private client key. By default no client key file is used. | - | OTEL_EXPORTER_OTLP_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP trace, metric or log client's TLS credentials. Must provide a client certificate/chain when providing a private client key. By default no client key file is used. | - | OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP metric server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. | - | OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP trace, metric and log server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. | - - > Settings configured programmatically take precedence over environment variables. Per-signal environment variables take precedence over non-per-signal environment variables. +In addition to settings passed to the constructor, the exporter also supports configuration via environment variables: + +| Environment variable | Description | +|----------------------|-------------| +| OTEL_EXPORTER_OTLP_ENDPOINT | The endpoint to send metrics to. This will also be used for the traces exporter if `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` is not configured. By default `localhost:4317` will be used. | +| OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | The endpoint to send metrics to. By default `localhost:4317` will be used. | +| OTEL_EXPORTER_OTLP_COMPRESSION | The compression type to use on OTLP trace, metric, and log requests. Options include gzip. By default no compression will be used. | +| OTEL_EXPORTER_OTLP_METRICS_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for metric requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. | +| OTEL_EXPORTER_OTLP_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for trace, metric and log requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. | +| OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP metric server's TLS credentials. By default the host platform's trusted root certificate is used.| +| OTEL_EXPORTER_OTLP_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP trace, metric, or log server's TLS credentials. By default the host platform's trusted root certificate is used. | +| OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP metric client's TLS credentials. Must provide a client certificate/chain when providing a private client key. By default no client key file is used. | +| OTEL_EXPORTER_OTLP_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP trace, metric or log client's TLS credentials. Must provide a client certificate/chain when providing a private client key. By default no client key file is used. | +| OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP metric server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. | +| OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP trace, metric and log server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. | +| OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | The exporters aggregation temporality preference. Valid values are `cumulative`, and `delta`. `cumulative` selects cumulative temporality for all instrument kinds. `delta` selects delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds, and selects cumulative aggregation for UpDownCounter and Asynchronous UpDownCounter instrument kinds. By default `cumulative` is used. | + +> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take precedence over non-per-signal environment variables. ## Running opentelemetry-collector locally to see the metrics diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts index 5f7d979fd3..3a512e3df4 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/src/OTLPMetricExporter.ts @@ -15,7 +15,6 @@ */ import { - defaultOptions, OTLPMetricExporterBase, OTLPMetricExporterOptions } from '@opentelemetry/exporter-metrics-otlp-http'; @@ -33,7 +32,7 @@ import { createExportMetricsServiceRequest, IExportMetricsServiceRequest } from class OTLPMetricExporterProxy extends OTLPGRPCExporterNodeBase { - constructor(config: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions= defaultOptions) { + constructor(config?: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions) { super(config); const headers = baggageUtils.parseKeyPairsIntoRecord(getEnv().OTEL_EXPORTER_OTLP_METRICS_HEADERS); this.metadata ||= new Metadata(); @@ -73,7 +72,7 @@ class OTLPMetricExporterProxy extends OTLPGRPCExporterNodeBase{ - constructor(config: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions) { super(new OTLPMetricExporterProxy(config), config); } } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md index d495e53b38..4dcbda9dae 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md @@ -17,8 +17,10 @@ npm install --save @opentelemetry/exporter-metrics-otlp-http ## Service Name The OpenTelemetry Collector Metrics Exporter does not have a service name configuration. -In order to set the service name, use the `service.name` resource attribute as prescribed in the [OpenTelemetry Resource Semantic Conventions][semconv-resource-service-name]. -To see sample code and documentation for the traces exporter, visit the [Collector Trace Exporter for web and node][trace-exporter-url]. +In order to set the service name, use the `service.name` resource attribute as prescribed in +the [OpenTelemetry Resource Semantic Conventions][semconv-resource-service-name]. +To see sample code and documentation for the traces exporter, visit +the [Collector Trace Exporter for web and node][trace-exporter-url]. ## Metrics in Web @@ -27,6 +29,7 @@ The OTLPMetricExporter in Web expects the endpoint to end in `/v1/metrics`. ```js import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'; + const collectorOptions = { url: '', // url is optional and can be omitted - default is http://localhost:4318/v1/metrics headers: {}, // an optional object containing custom headers to be sent with each request @@ -50,7 +53,7 @@ counter.add(10, { 'key': 'value' }); ```js const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); -const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http'); +const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http'); const collectorOptions = { url: '', // url is optional and can be omitted - default is http://localhost:4318/v1/metrics concurrencyLimit: 1, // an optional limit on pending requests @@ -70,35 +73,18 @@ counter.add(10, { 'key': 'value' }); ``` -## GRPC - -For exporting metrics with GRPC please check [exporter-metrics-otlp-grpc][npm-url-grpc] - -## PROTOBUF - -For exporting metrics with PROTOBUF please check [exporter-metrics-otlp-proto][npm-url-proto] - -## Configuration options as environment variables - -Instead of providing options to `OTLPMetricExporter` and `OTLPTraceExporter` explicitly, environment variables may be provided instead. - -```sh -OTEL_EXPORTER_OTLP_ENDPOINT=https://localhost:4318 -# this will automatically append the version and signal path -# e.g. https://localhost:4318/v1/traces for `OTLPTraceExporter` and https://localhost:4318/v1/metrics for `OTLPMetricExporter` -``` - -If the trace and metric exporter endpoints have different providers, the env var for per-signal endpoints are available to use +## Environment Variable Configuration -```sh -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://trace-service:4318/v1/traces -OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://metric-service:4318/v1/metrics -# version and signal needs to be explicit -``` +In addition to settings passed to the constructor, the exporter also supports configuration via environment variables: -> The per-signal endpoints take precedence and overrides `OTEL_EXPORTER_OTLP_ENDPOINT` +| Environment variable | Description | +|---------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| OTEL_EXPORTER_OTLP_ENDPOINT | The endpoint to send metrics to. This will also be used for the traces exporter if `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` is not configured. By default `http://localhost:4318` will be used. `/v1/metrics` will be automatically appended to configured values. | +| OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | The endpoint to send metrics to. By default `https://localhost:4318/v1/metrics` will be used. `v1/metrics` will not be appended automatically and has to be added explicitly. | +| OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | The exporters aggregation temporality preference. Valid values are `cumulative`, and `delta`. `cumulative` selects cumulative temporality for all instrument kinds. `delta` selects delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds, and selects cumulative aggregation for UpDownCounter and Asynchronous UpDownCounter instrument kinds. By default `cumulative` is used. | -For more details, see [OpenTelemetry Specification on Protocol Exporter][opentelemetry-spec-protocol-exporter]. +> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take +> precedence over non-per-signal environment variables. ## Running opentelemetry-collector locally to see the metrics @@ -110,6 +96,8 @@ For more details, see [OpenTelemetry Specification on Protocol Exporter][opentel - For more information on OpenTelemetry, visit: - For more about OpenTelemetry JavaScript: - For help or feedback on this project, join us in [GitHub Discussions][discussions-url] +- For exporting metrics via gRPC please check [exporter-metrics-otlp-grpc][npm-url-grpc] +- For exporting metrics via protobuf please check [exporter-metrics-otlp-proto][npm-url-proto] ## License diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterBase.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterBase.ts index b970a150d0..fca5a54d25 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterBase.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterBase.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { ExportResult } from '@opentelemetry/core'; +import { + ExportResult, + getEnv +} from '@opentelemetry/core'; import { AggregationTemporality, AggregationTemporalitySelector, @@ -22,9 +25,12 @@ import { PushMetricExporter, ResourceMetrics } from '@opentelemetry/sdk-metrics'; -import { defaultOptions, OTLPMetricExporterOptions } from './OTLPMetricExporterOptions'; +import { + OTLPMetricExporterOptions +} from './OTLPMetricExporterOptions'; import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base'; import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer'; +import { diag } from '@opentelemetry/api'; export const CumulativeTemporalitySelector: AggregationTemporalitySelector = () => AggregationTemporality.CUMULATIVE; @@ -41,14 +47,33 @@ export const DeltaTemporalitySelector: AggregationTemporalitySelector = (instrum } }; -function chooseTemporalitySelector(temporalityPreference?: AggregationTemporality): AggregationTemporalitySelector { - if (temporalityPreference === AggregationTemporality.DELTA) { +function chooseTemporalitySelectorFromEnvironment() { + const env = getEnv(); + const configuredTemporality = env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE.trim().toLowerCase(); + + if (configuredTemporality === 'cumulative') { + return CumulativeTemporalitySelector; + } + if (configuredTemporality === 'delta') { return DeltaTemporalitySelector; } + diag.warn(`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE is set to '${env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE}', but only 'cumulative' and 'delta' are allowed. Using default ('cumulative') instead.`); return CumulativeTemporalitySelector; } +function chooseTemporalitySelector(temporalityPreference?: AggregationTemporality): AggregationTemporalitySelector { + // Directly passed preference has priority. + if (temporalityPreference != null) { + if (temporalityPreference === AggregationTemporality.DELTA) { + return DeltaTemporalitySelector; + } + return CumulativeTemporalitySelector; + } + + return chooseTemporalitySelectorFromEnvironment(); +} + export class OTLPMetricExporterBase> @@ -57,9 +82,9 @@ implements PushMetricExporter { protected _aggregationTemporalitySelector: AggregationTemporalitySelector; constructor(exporter: T, - config: OTLPMetricExporterOptions = defaultOptions) { + config?: OTLPMetricExporterOptions) { this._otlpExporter = exporter; - this._aggregationTemporalitySelector = chooseTemporalitySelector(config.temporalityPreference); + this._aggregationTemporalitySelector = chooseTemporalitySelector(config?.temporalityPreference); } export(metrics: ResourceMetrics, resultCallback: (result: ExportResult) => void): void { diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterOptions.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterOptions.ts index 986a85890b..324c4ea27f 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterOptions.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/OTLPMetricExporterOptions.ts @@ -20,5 +20,3 @@ import { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base'; export interface OTLPMetricExporterOptions extends OTLPExporterConfigBase { temporalityPreference?: AggregationTemporality } -export const defaultExporterTemporality = AggregationTemporality.CUMULATIVE; -export const defaultOptions = {temporalityPreference: defaultExporterTemporality}; diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts index afc42de108..00c7c0c32c 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/browser/OTLPMetricExporter.ts @@ -16,7 +16,7 @@ import { ResourceMetrics } from '@opentelemetry/sdk-metrics'; import { baggageUtils, getEnv } from '@opentelemetry/core'; -import { defaultOptions, OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; +import { OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; import { OTLPMetricExporterBase } from '../../OTLPMetricExporterBase'; import { OTLPExporterBrowserBase, @@ -31,7 +31,7 @@ const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURC class OTLPExporterBrowserProxy extends OTLPExporterBrowserBase { - constructor(config: OTLPMetricExporterOptions & OTLPExporterConfigBase = defaultOptions) { + constructor(config?: OTLPMetricExporterOptions & OTLPExporterConfigBase) { super(config); this._headers = Object.assign( this._headers, @@ -60,7 +60,7 @@ class OTLPExporterBrowserProxy extends OTLPExporterBrowserBase { - constructor(config: OTLPExporterConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterConfigBase & OTLPMetricExporterOptions) { super(new OTLPExporterBrowserProxy(config), config); } } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts index 579fe95696..d09693a253 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/src/platform/node/OTLPMetricExporter.ts @@ -16,7 +16,7 @@ import { ResourceMetrics } from '@opentelemetry/sdk-metrics'; import { getEnv, baggageUtils} from '@opentelemetry/core'; -import { defaultOptions, OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; +import { OTLPMetricExporterOptions } from '../../OTLPMetricExporterOptions'; import { OTLPMetricExporterBase } from '../../OTLPMetricExporterBase'; import { OTLPExporterNodeBase, @@ -31,7 +31,7 @@ const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURC class OTLPExporterNodeProxy extends OTLPExporterNodeBase { - constructor(config: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions) { super(config); this.headers = Object.assign( this.headers, @@ -60,7 +60,7 @@ class OTLPExporterNodeProxy extends OTLPExporterNodeBase { - constructor(config: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions) { super(new OTLPExporterNodeProxy(config), config); } } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/common/CollectorMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/common/CollectorMetricExporter.test.ts index 38c0b3bcc7..406e20f612 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/common/CollectorMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/common/CollectorMetricExporter.test.ts @@ -20,22 +20,34 @@ import { } from '@opentelemetry/sdk-metrics'; import * as assert from 'assert'; import * as sinon from 'sinon'; -import { collect, mockCounter, mockObservableGauge, setUp, shutdown } from '../metricsHelper'; -import { OTLPExporterBase, OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base'; +import { + collect, + mockCounter, + mockObservableGauge, + setUp, + shutdown +} from '../metricsHelper'; +import { + OTLPExporterBase, + OTLPExporterConfigBase +} from '@opentelemetry/otlp-exporter-base'; import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer'; type CollectorExporterConfig = OTLPExporterConfigBase; -class OTLPMetricExporter extends OTLPExporterBase< - CollectorExporterConfig, + +class OTLPMetricExporter extends OTLPExporterBase { + IExportMetricsServiceRequest> { onInit() {} + onShutdown() {} + send() {} + getDefaultUrl(config: CollectorExporterConfig) { return config.url || ''; } + convert(metrics: ResourceMetrics[]): IExportMetricsServiceRequest { return { resourceMetrics: [] }; } @@ -125,7 +137,7 @@ describe('OTLPMetricExporter - common', () => { describe('when exporter is shutdown', () => { it( 'should not export anything but return callback with code' + - ' "FailedNotRetryable"', + ' "FailedNotRetryable"', async () => { await collectorExporter.shutdown(); spySend.resetHistory(); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts index 77c5023153..68dd569d89 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/node/CollectorMetricExporter.test.ts @@ -15,12 +15,17 @@ */ -import { diag, DiagLogger } from '@opentelemetry/api'; +import { + diag, + DiagLogger +} from '@opentelemetry/api'; import * as core from '@opentelemetry/core'; import * as assert from 'assert'; import * as http from 'http'; import * as sinon from 'sinon'; import { + CumulativeTemporalitySelector, + DeltaTemporalitySelector, OTLPMetricExporterOptions } from '../../src'; @@ -28,22 +33,31 @@ import { OTLPMetricExporter } from '../../src/platform/node'; import { + collect, ensureCounterIsCorrect, ensureExportMetricsServiceRequestIsSet, - ensureObservableGaugeIsCorrect, ensureHistogramIsCorrect, + ensureObservableGaugeIsCorrect, + HISTOGRAM_AGGREGATION_VIEW, mockCounter, - mockObservableGauge, mockHistogram, - collect, - shutdown, + mockObservableGauge, setUp, - HISTOGRAM_AGGREGATION_VIEW, + shutdown, } from '../metricsHelper'; import { MockedResponse } from './nodeHelpers'; -import { AggregationTemporality, ResourceMetrics } from '@opentelemetry/sdk-metrics'; -import { Stream, PassThrough } from 'stream'; -import { OTLPExporterError, OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base'; +import { + AggregationTemporality, + ResourceMetrics +} from '@opentelemetry/sdk-metrics'; +import { + PassThrough, + Stream +} from 'stream'; +import { + OTLPExporterError, + OTLPExporterNodeConfigBase +} from '@opentelemetry/otlp-exporter-base'; import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer'; let fakeRequest: PassThrough; @@ -190,6 +204,34 @@ describe('OTLPMetricExporter - node with json over http', () => { envSource.OTEL_EXPORTER_OTLP_METRICS_HEADERS = ''; envSource.OTEL_EXPORTER_OTLP_HEADERS = ''; }); + it('should use delta temporality defined via env', () => { + for (const envValue of ['delta', 'DELTA', 'DeLTa', 'delta ']) { + envSource.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = envValue; + const exporter = new OTLPMetricExporter(); + assert.strictEqual(exporter['_aggregationTemporalitySelector'], DeltaTemporalitySelector); + } + }); + it('should use cumulative temporality defined via env', () => { + for (const envValue of ['cumulative', 'CUMULATIVE', 'CuMULaTIvE', 'cumulative ']) { + envSource.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = envValue; + const exporter = new OTLPMetricExporter(); + assert.strictEqual(exporter['_aggregationTemporalitySelector'], CumulativeTemporalitySelector); + } + }); + it('should configure cumulative temporality with invalid value in env', () => { + for (const envValue of ['invalid', ' ']) { + envSource.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = envValue; + const exporter = new OTLPMetricExporter(); + assert.strictEqual(exporter['_aggregationTemporalitySelector'], CumulativeTemporalitySelector); + } + }); + it('should respect explicit config over environment variable', () => { + envSource.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = 'cumulative'; + const exporter = new OTLPMetricExporter({ + temporalityPreference: AggregationTemporality.DELTA + }); + assert.strictEqual(exporter['_aggregationTemporalitySelector'], DeltaTemporalitySelector); + }); }); describe('export', () => { diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md index a5d812236d..6a2e160bac 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md @@ -43,6 +43,19 @@ counter.add(10, { 'key': 'value' }); ``` +## Environment Variable Configuration + +In addition to settings passed to the constructor, the exporter also supports configuration via environment variables: + +| Environment variable | Description | +|---------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| OTEL_EXPORTER_OTLP_ENDPOINT | The endpoint to send metrics to. This will also be used for the traces exporter if `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` is not configured. By default `http://localhost:4318` will be used. `/v1/metrics` will be automatically appended to configured values. | +| OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | The endpoint to send metrics to. By default `https://localhost:4318/v1/metrics` will be used. `v1/metrics` will not be appended automatically and has to be added explicitly. | +| OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | The exporters aggregation temporality preference. Valid values are `cumulative`, and `delta`. `cumulative` selects cumulative temporality for all instrument kinds. `delta` selects delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds, and selects cumulative aggregation for UpDownCounter and Asynchronous UpDownCounter instrument kinds. By default `cumulative` is used. | + +> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take +> precedence over non-per-signal environment variables. + ## Running opentelemetry-collector locally to see the metrics 1. Go to `examples/otlp-exporter-node` diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts index e3d8a60155..e62a8e0ece 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/src/OTLPMetricExporter.ts @@ -15,7 +15,6 @@ */ import { - defaultOptions, OTLPMetricExporterOptions } from '@opentelemetry/exporter-metrics-otlp-http'; import { ServiceClientType, OTLPProtoExporterNodeBase } from '@opentelemetry/otlp-proto-exporter-base'; @@ -34,7 +33,7 @@ const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURC class OTLPMetricExporterNodeProxy extends OTLPProtoExporterNodeBase { - constructor(config: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions) { super(config); this.headers = Object.assign( this.headers, @@ -64,7 +63,7 @@ class OTLPMetricExporterNodeProxy extends OTLPProtoExporterNodeBase { - constructor(config: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions = defaultOptions) { + constructor(config?: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions) { super(new OTLPMetricExporterNodeProxy(config), config); } } diff --git a/packages/opentelemetry-core/src/utils/environment.ts b/packages/opentelemetry-core/src/utils/environment.ts index 8d50e2cb9b..fcb0614c61 100644 --- a/packages/opentelemetry-core/src/utils/environment.ts +++ b/packages/opentelemetry-core/src/utils/environment.ts @@ -106,6 +106,7 @@ export type ENVIRONMENT = { OTEL_EXPORTER_OTLP_PROTOCOL?: string, OTEL_EXPORTER_OTLP_TRACES_PROTOCOL?: string, OTEL_EXPORTER_OTLP_METRICS_PROTOCOL?: string, + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE?: string } & ENVIRONMENT_NUMBERS & ENVIRONMENT_LISTS; @@ -178,6 +179,7 @@ export const DEFAULT_ENVIRONMENT: Required = { OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf', OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: 'http/protobuf', OTEL_EXPORTER_OTLP_METRICS_PROTOCOL: 'http/protobuf', + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE: 'cumulative' }; /** From d808e2957f84d127db1a5a3b283227cd21a28719 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 26 Oct 2022 15:36:52 -0400 Subject: [PATCH 52/77] Add semver check to metrics API (#3357) --- experimental/CHANGELOG.md | 3 + .../src/api/global-utils.ts | 55 ------- .../src/api/metrics.ts | 32 +--- .../src/internal/global-utils.ts | 96 ++++++++++++ .../src/internal/semver.ts | 140 +++++++++++++++++ .../test/{api => internal}/global.test.ts | 66 ++++++-- .../test/internal/semver.test.ts | 148 ++++++++++++++++++ .../test/internal/version.test.ts | 30 ++++ 8 files changed, 478 insertions(+), 92 deletions(-) delete mode 100644 experimental/packages/opentelemetry-api-metrics/src/api/global-utils.ts create mode 100644 experimental/packages/opentelemetry-api-metrics/src/internal/global-utils.ts create mode 100644 experimental/packages/opentelemetry-api-metrics/src/internal/semver.ts rename experimental/packages/opentelemetry-api-metrics/test/{api => internal}/global.test.ts (50%) create mode 100644 experimental/packages/opentelemetry-api-metrics/test/internal/semver.test.ts create mode 100644 experimental/packages/opentelemetry-api-metrics/test/internal/version.test.ts diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 7913109e53..6d2de9fb60 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -6,6 +6,9 @@ All notable changes to experimental packages in this project will be documented ### :boom: Breaking Change +* Add semver check to metrics API [#3357](https://github.com/open-telemetry/opentelemetry-js/pull/3357) @dyladan + * Previously API versions were only considered compatible if the API was exactly the same + ### :rocket: (Enhancement) * feat(metrics-sdk): Add tracing suppresing for Metrics Export [#3332](https://github.com/open-telemetry/opentelemetry-js/pull/3332) @hectorhdzg diff --git a/experimental/packages/opentelemetry-api-metrics/src/api/global-utils.ts b/experimental/packages/opentelemetry-api-metrics/src/api/global-utils.ts deleted file mode 100644 index e371d5165d..0000000000 --- a/experimental/packages/opentelemetry-api-metrics/src/api/global-utils.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 { MeterProvider } from '../types/MeterProvider'; -import { _globalThis } from '../platform'; - -export const GLOBAL_METRICS_API_KEY = Symbol.for( - 'io.opentelemetry.js.api.metrics' -); - -type Get = (version: number) => T; -type OtelGlobal = Partial<{ - [GLOBAL_METRICS_API_KEY]: Get; -}>; - -export const _global = _globalThis as OtelGlobal; - -/** - * Make a function which accepts a version integer and returns the instance of an API if the version - * is compatible, or a fallback version (usually NOOP) if it is not. - * - * @param requiredVersion Backwards compatibility version which is required to return the instance - * @param instance Instance which should be returned if the required version is compatible - * @param fallback Fallback instance, usually NOOP, which will be returned if the required version is not compatible - */ -export function makeGetter( - requiredVersion: number, - instance: T, - fallback: T -): Get { - return (version: number): T => - version === requiredVersion ? instance : fallback; -} - -/** - * A number which should be incremented each time a backwards incompatible - * change is made to the API. This number is used when an API package - * attempts to access the global API to ensure it is getting a compatible - * version. If the global API is not compatible with the API package - * attempting to get it, a NOOP API implementation will be returned. - */ -export const API_BACKWARDS_COMPATIBILITY_VERSION = 4; diff --git a/experimental/packages/opentelemetry-api-metrics/src/api/metrics.ts b/experimental/packages/opentelemetry-api-metrics/src/api/metrics.ts index 3e5fb6015a..b3f9bac6b6 100644 --- a/experimental/packages/opentelemetry-api-metrics/src/api/metrics.ts +++ b/experimental/packages/opentelemetry-api-metrics/src/api/metrics.ts @@ -17,12 +17,7 @@ import { Meter, MeterOptions } from '../types/Meter'; import { MeterProvider } from '../types/MeterProvider'; import { NOOP_METER_PROVIDER } from '../NoopMeterProvider'; -import { - API_BACKWARDS_COMPATIBILITY_VERSION, - GLOBAL_METRICS_API_KEY, - makeGetter, - _global, -} from './global-utils'; +import { getGlobal, registerGlobal, unregisterGlobal } from '../internal/global-utils'; /** * Singleton object which represents the entry point to the OpenTelemetry Metrics API @@ -43,31 +38,18 @@ export class MetricsAPI { } /** - * Set the current global meter. Returns the initialized global meter provider. + * Set the current global meter provider. + * Returns true if the meter provider was successfully registered, else false. */ - public setGlobalMeterProvider(provider: MeterProvider): MeterProvider { - if (_global[GLOBAL_METRICS_API_KEY]) { - // global meter provider has already been set - return this.getMeterProvider(); - } - - _global[GLOBAL_METRICS_API_KEY] = makeGetter( - API_BACKWARDS_COMPATIBILITY_VERSION, - provider, - NOOP_METER_PROVIDER - ); - - return provider; + public setGlobalMeterProvider(provider: MeterProvider): boolean { + return registerGlobal('metrics', provider); } /** * Returns the global meter provider. */ public getMeterProvider(): MeterProvider { - return ( - _global[GLOBAL_METRICS_API_KEY]?.(API_BACKWARDS_COMPATIBILITY_VERSION) ?? - NOOP_METER_PROVIDER - ); + return getGlobal('metrics') || NOOP_METER_PROVIDER; } /** @@ -79,6 +61,6 @@ export class MetricsAPI { /** Remove the global meter provider */ public disable(): void { - delete _global[GLOBAL_METRICS_API_KEY]; + unregisterGlobal('metrics'); } } diff --git a/experimental/packages/opentelemetry-api-metrics/src/internal/global-utils.ts b/experimental/packages/opentelemetry-api-metrics/src/internal/global-utils.ts new file mode 100644 index 0000000000..f83c203398 --- /dev/null +++ b/experimental/packages/opentelemetry-api-metrics/src/internal/global-utils.ts @@ -0,0 +1,96 @@ +/* + * 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 { _globalThis } from '../platform'; +import { MeterProvider } from '../types/MeterProvider'; +import { VERSION } from '../version'; +import { isCompatible } from './semver'; + +const major = VERSION.split('.')[0]; +const GLOBAL_OPENTELEMETRY_METRICS_API_KEY = Symbol.for( + `opentelemetry.js.api.metrics.${major}` +); + +const _global = _globalThis as OTelGlobal; + +export function registerGlobal( + type: Type, + instance: OTelGlobalAPI[Type], + allowOverride = false +): boolean { + const api = (_global[GLOBAL_OPENTELEMETRY_METRICS_API_KEY] = _global[ + GLOBAL_OPENTELEMETRY_METRICS_API_KEY + ] ?? { + version: VERSION, + }); + + if (!allowOverride && api[type]) { + // already registered an API of this type + const err = new Error( + `@opentelemetry/api: Attempted duplicate registration of API: ${type}` + ); + diag.error(err.stack || err.message); + return false; + } + + if (api.version !== VERSION) { + // All registered APIs must be of the same version exactly + const err = new Error( + '@opentelemetry/api: All API registration versions must match' + ); + diag.error(err.stack || err.message); + return false; + } + + api[type] = instance; + diag.debug( + `@opentelemetry/api: Registered a global for ${type} v${VERSION}.` + ); + + return true; +} + +export function getGlobal( + type: Type +): OTelGlobalAPI[Type] | undefined { + const globalVersion = _global[GLOBAL_OPENTELEMETRY_METRICS_API_KEY]?.version; + if (!globalVersion || !isCompatible(globalVersion)) { + return; + } + return _global[GLOBAL_OPENTELEMETRY_METRICS_API_KEY]?.[type]; +} + +export function unregisterGlobal(type: keyof OTelGlobalAPI) { + diag.debug( + `@opentelemetry/api-metrics: Unregistering a global for ${type} v${VERSION}.` + ); + const api = _global[GLOBAL_OPENTELEMETRY_METRICS_API_KEY]; + + if (api) { + delete api[type]; + } +} + +type OTelGlobal = { + [GLOBAL_OPENTELEMETRY_METRICS_API_KEY]?: OTelGlobalAPI; +}; + +type OTelGlobalAPI = { + version: string; + + metrics?: MeterProvider; +}; diff --git a/experimental/packages/opentelemetry-api-metrics/src/internal/semver.ts b/experimental/packages/opentelemetry-api-metrics/src/internal/semver.ts new file mode 100644 index 0000000000..076f9b9b51 --- /dev/null +++ b/experimental/packages/opentelemetry-api-metrics/src/internal/semver.ts @@ -0,0 +1,140 @@ +/* + * 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 { VERSION } from '../version'; + +const re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/; + +/** + * Create a function to test an API version to see if it is compatible with the provided ownVersion. + * + * The returned function has the following semantics: + * - Exact match is always compatible + * - Major versions must match exactly + * - 1.x package cannot use global 2.x package + * - 2.x package cannot use global 1.x package + * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API + * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects + * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 + * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor + * - Patch and build tag differences are not considered at this time + * + * @param ownVersion version which should be checked against + */ +export function _makeCompatibilityCheck( + ownVersion: string +): (globalVersion: string) => boolean { + const acceptedVersions = new Set([ownVersion]); + const rejectedVersions = new Set(); + + const myVersionMatch = ownVersion.match(re); + if (!myVersionMatch) { + // we cannot guarantee compatibility so we always return noop + return () => false; + } + + const ownVersionParsed = { + major: +myVersionMatch[1], + minor: +myVersionMatch[2], + patch: +myVersionMatch[3], + prerelease: myVersionMatch[4], + }; + + // if ownVersion has a prerelease tag, versions must match exactly + if (ownVersionParsed.prerelease != null) { + return function isExactmatch(globalVersion: string): boolean { + return globalVersion === ownVersion; + }; + } + + function _reject(v: string) { + rejectedVersions.add(v); + return false; + } + + function _accept(v: string) { + acceptedVersions.add(v); + return true; + } + + return function isCompatible(globalVersion: string): boolean { + if (acceptedVersions.has(globalVersion)) { + return true; + } + + if (rejectedVersions.has(globalVersion)) { + return false; + } + + const globalVersionMatch = globalVersion.match(re); + if (!globalVersionMatch) { + // cannot parse other version + // we cannot guarantee compatibility so we always noop + return _reject(globalVersion); + } + + const globalVersionParsed = { + major: +globalVersionMatch[1], + minor: +globalVersionMatch[2], + patch: +globalVersionMatch[3], + prerelease: globalVersionMatch[4], + }; + + // if globalVersion has a prerelease tag, versions must match exactly + if (globalVersionParsed.prerelease != null) { + return _reject(globalVersion); + } + + // major versions must match + if (ownVersionParsed.major !== globalVersionParsed.major) { + return _reject(globalVersion); + } + + if (ownVersionParsed.major === 0) { + if ( + ownVersionParsed.minor === globalVersionParsed.minor && + ownVersionParsed.patch <= globalVersionParsed.patch + ) { + return _accept(globalVersion); + } + + return _reject(globalVersion); + } + + if (ownVersionParsed.minor <= globalVersionParsed.minor) { + return _accept(globalVersion); + } + + return _reject(globalVersion); + }; +} + +/** + * Test an API version to see if it is compatible with this API. + * + * - Exact match is always compatible + * - Major versions must match exactly + * - 1.x package cannot use global 2.x package + * - 2.x package cannot use global 1.x package + * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API + * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects + * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 + * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor + * - Patch and build tag differences are not considered at this time + * + * @param version version of the API requesting an instance of the global API + */ +export const isCompatible = _makeCompatibilityCheck(VERSION); diff --git a/experimental/packages/opentelemetry-api-metrics/test/api/global.test.ts b/experimental/packages/opentelemetry-api-metrics/test/internal/global.test.ts similarity index 50% rename from experimental/packages/opentelemetry-api-metrics/test/api/global.test.ts rename to experimental/packages/opentelemetry-api-metrics/test/internal/global.test.ts index c48949a3e5..69fbee57c6 100644 --- a/experimental/packages/opentelemetry-api-metrics/test/api/global.test.ts +++ b/experimental/packages/opentelemetry-api-metrics/test/internal/global.test.ts @@ -15,8 +15,11 @@ */ import * as assert from 'assert'; -import { _global, GLOBAL_METRICS_API_KEY } from '../../src/api/global-utils'; +import { getGlobal } from '../../src/internal/global-utils'; +import { _globalThis } from '../../src/platform'; import { NoopMeterProvider } from '../../src/NoopMeterProvider'; +import sinon = require('sinon'); +import { diag } from '@opentelemetry/api'; const api1 = require('../../src') as typeof import('../../src'); @@ -26,18 +29,31 @@ for (const key of Object.keys(require.cache)) { } const api2 = require('../../src') as typeof import('../../src'); +// This will need to be changed manually on major version changes. +// It is intentionally not autogenerated to ensure the author of the change is aware of what they are doing. +const GLOBAL_METRICS_API_SYMBOL_KEY = 'opentelemetry.js.api.metrics.0'; + +const getMockLogger = () => ({ + verbose: sinon.spy(), + debug: sinon.spy(), + info: sinon.spy(), + warn: sinon.spy(), + error: sinon.spy(), +}); + describe('Global Utils', () => { // prove they are separate instances - assert.notStrictEqual(api1, api2); + assert.notEqual(api1, api2); // that return separate noop instances to start assert.notStrictEqual( api1.metrics.getMeterProvider(), - api2.metrics.getMeterProvider() + api2.metrics.getMeterProvider(), ); beforeEach(() => { api1.metrics.disable(); - api2.metrics.disable(); + // @ts-expect-error we are modifying internals for testing purposes here + delete _globalThis[Symbol.for(GLOBAL_METRICS_API_SYMBOL_KEY)]; }); it('should change the global meter provider', () => { @@ -57,20 +73,46 @@ describe('Global Utils', () => { }); it('should disable both if one is disabled', () => { - const original = api1.metrics.getMeterProvider(); + const manager = new NoopMeterProvider(); + api1.metrics.setGlobalMeterProvider(manager); - api1.metrics.setGlobalMeterProvider(new NoopMeterProvider()); - - assert.notStrictEqual(original, api1.metrics.getMeterProvider()); + assert.strictEqual(manager, api1.metrics.getMeterProvider()); api2.metrics.disable(); - assert.strictEqual(original, api1.metrics.getMeterProvider()); + assert.notStrictEqual(manager, api1.metrics.getMeterProvider()); }); it('should return the module NoOp implementation if the version is a mismatch', () => { - const original = api1.metrics.getMeterProvider(); + const newMeterProvider = new NoopMeterProvider(); + api1.metrics.setGlobalMeterProvider(newMeterProvider); + + // ensure new meter provider is returned + assert.strictEqual(api1.metrics.getMeterProvider(), newMeterProvider); + + const globalInstance = getGlobal('metrics'); + assert.ok(globalInstance); + // @ts-expect-error we are modifying internals for testing purposes here + _globalThis[Symbol.for(GLOBAL_METRICS_API_SYMBOL_KEY)].version = '0.0.1'; + + // ensure new meter provider is not returned because version above is incompatible + assert.notStrictEqual( + api1.metrics.getMeterProvider(), + newMeterProvider + ); + }); + + it('should log an error if there is a duplicate registration', () => { + const logger = getMockLogger(); + diag.setLogger(logger); + + api1.metrics.setGlobalMeterProvider(new NoopMeterProvider()); api1.metrics.setGlobalMeterProvider(new NoopMeterProvider()); - const afterSet = _global[GLOBAL_METRICS_API_KEY]!(-1); - assert.strictEqual(original, afterSet); + sinon.assert.calledOnce(logger.error); + assert.strictEqual(logger.error.firstCall.args.length, 1); + assert.ok( + logger.error.firstCall.args[0].startsWith( + 'Error: @opentelemetry/api: Attempted duplicate registration of API: metrics' + ) + ); }); }); diff --git a/experimental/packages/opentelemetry-api-metrics/test/internal/semver.test.ts b/experimental/packages/opentelemetry-api-metrics/test/internal/semver.test.ts new file mode 100644 index 0000000000..e9ac3ec727 --- /dev/null +++ b/experimental/packages/opentelemetry-api-metrics/test/internal/semver.test.ts @@ -0,0 +1,148 @@ +/* + * 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 { + isCompatible, + _makeCompatibilityCheck, +} from '../../src/internal/semver'; +import { VERSION } from '../../src/version'; + +describe('semver', () => { + it('should be compatible if versions are equal', () => { + assert.ok(isCompatible(VERSION)); + }); + + it('returns false if own version cannot be parsed', () => { + const check = _makeCompatibilityCheck('this is not semver'); + assert.ok(!check('1.0.0')); + }); + + it('incompatible if other version cannot be parsed', () => { + const check = _makeCompatibilityCheck('0.1.2'); + assert.ok(!check('this is not semver')); + }); + + describe('>= 1.0.0', () => { + const globalVersion = '5.5.5'; + const vers: [string, boolean][] = [ + // same major/minor run should be compatible + ['5.5.5', true], + ['5.5.6', true], + ['5.5.4', true], + + // prerelease version should not be compatible + ['5.5.5-rc.0', false], + + // if our version has a minor version increase, we may try to call methods which don't exist on the global + ['5.6.5', false], + ['5.6.6', false], + ['5.6.4', false], + + // if the global version is ahead of us by a minor revision, it has at least the methods we know about + ['5.4.5', true], + ['5.4.6', true], + ['5.4.4', true], + + // major version mismatch is always incompatible + ['6.5.5', false], + ['6.5.6', false], + ['6.5.4', false], + ['6.6.5', false], + ['6.6.6', false], + ['6.6.4', false], + ['6.4.5', false], + ['6.4.6', false], + ['6.4.4', false], + ['4.5.5', false], + ['4.5.6', false], + ['4.5.4', false], + ['4.6.5', false], + ['4.6.6', false], + ['4.6.4', false], + ['4.4.5', false], + ['4.4.6', false], + ['4.4.4', false], + ]; + + test(globalVersion, vers); + }); + + describe('< 1.0.0', () => { + const globalVersion = '0.5.5'; + const vers: [string, boolean][] = [ + // same minor/patch should be compatible + ['0.5.5', true], + + // prerelease version should not be compatible + ['0.5.5-rc.0', false], + + // if our version has a patch version increase, we may try to call methods which don't exist on the global + ['0.5.6', false], + + // if the global version is ahead of us by a patch revision, it has at least the methods we know about + ['0.5.4', true], + + // minor version mismatch is always incompatible + ['0.6.5', false], + ['0.6.6', false], + ['0.6.4', false], + ['0.4.5', false], + ['0.4.6', false], + ['0.4.4', false], + + // major version mismatch is always incompatible + ['1.5.5', false], + ['1.5.6', false], + ['1.5.4', false], + ['1.6.5', false], + ['1.6.6', false], + ['1.6.4', false], + ['1.4.5', false], + ['1.4.6', false], + ['1.4.4', false], + ]; + + test(globalVersion, vers); + }); + + describe('global version is prerelease', () => { + const globalVersion = '1.0.0-rc.3'; + const vers: [string, boolean][] = [ + // must match exactly + ['1.0.0', false], + ['1.0.0-rc.2', false], + ['1.0.0-rc.4', false], + + ['1.0.0-rc.3', true], + ]; + + test(globalVersion, vers); + }); +}); + +function test(globalVersion: string, vers: [string, boolean][]) { + describe(`global version is ${globalVersion}`, () => { + for (const [version, compatible] of vers) { + it(`API version ${version} ${ + compatible ? 'should' : 'should not' + } be able to access global`, () => { + const check = _makeCompatibilityCheck(version); + assert.strictEqual(check(globalVersion), compatible); + }); + } + }); +} diff --git a/experimental/packages/opentelemetry-api-metrics/test/internal/version.test.ts b/experimental/packages/opentelemetry-api-metrics/test/internal/version.test.ts new file mode 100644 index 0000000000..4d0e5f2542 --- /dev/null +++ b/experimental/packages/opentelemetry-api-metrics/test/internal/version.test.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 * as assert from 'assert'; +import { VERSION } from '../../src/version'; + +describe('version', () => { + it('should have generated VERSION.ts', () => { + const pjson = require('../../package.json'); + assert.strictEqual(pjson.version, VERSION); + }); + + it('prerelease tag versions are banned', () => { + // see https://github.com/open-telemetry/opentelemetry-js-api/issues/74 + assert.ok(VERSION.match(/^\d+\.\d+\.\d+$/)); + }); +}); From e9347e4671579d18fb62da56836d43802cc64453 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 27 Oct 2022 14:57:16 -0400 Subject: [PATCH 53/77] Release metrics API as 1.0 (#3348) --- CHANGELOG.md | 5 +++++ .../.eslintignore | 0 .../.eslintrc.js | 2 +- .../opentelemetry-api-metrics => api-metrics}/LICENSE | 0 .../README.md | 0 .../karma.conf.js | 4 ++-- .../package.json | 10 +++++----- .../src/NoopMeter.ts | 0 .../src/NoopMeterProvider.ts | 0 .../src/api/metrics.ts | 0 .../src/index.ts | 0 .../src/internal/global-utils.ts | 0 .../src/internal/semver.ts | 0 .../src/platform/browser/globalThis.ts | 0 .../src/platform/browser/index.ts | 0 .../src/platform/index.ts | 0 .../src/platform/node/globalThis.ts | 0 .../src/platform/node/index.ts | 0 .../src/types/Meter.ts | 0 .../src/types/MeterProvider.ts | 0 .../src/types/Metric.ts | 0 .../src/types/ObservableResult.ts | 0 .../test/api/api.test.ts | 0 .../test/index-webpack.ts | 0 .../test/internal/global.test.ts | 2 +- .../test/internal/semver.test.ts | 0 .../test/internal/version.test.ts | 0 .../test/noop-implementations/noop-meter.test.ts | 0 .../test/types/Metric.test.ts | 0 .../tsconfig.all.json | 2 +- .../tsconfig.docs.json | 0 .../tsconfig.esm.json | 2 +- .../tsconfig.esnext.json | 2 +- .../tsconfig.json | 4 ++-- .../tsconfig.json | 6 +++--- .../tsconfig.json | 6 +++--- .../tsconfig.json | 6 +++--- .../opentelemetry-exporter-prometheus/tsconfig.json | 6 +++--- .../opentelemetry-instrumentation-grpc/tsconfig.json | 6 +++--- .../opentelemetry-instrumentation-http/tsconfig.json | 6 +++--- .../opentelemetry-instrumentation/tsconfig.esnext.json | 2 +- .../opentelemetry-instrumentation/tsconfig.json | 2 +- .../opentelemetry-sdk-metrics/tsconfig.esm.json | 2 +- .../opentelemetry-sdk-metrics/tsconfig.esnext.json | 2 +- .../packages/opentelemetry-sdk-metrics/tsconfig.json | 6 +++--- .../packages/opentelemetry-sdk-node/tsconfig.json | 6 +++--- experimental/packages/otlp-transformer/tsconfig.json | 6 +++--- lerna.json | 1 + tsconfig.json | 6 +++--- 49 files changed, 54 insertions(+), 48 deletions(-) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/.eslintignore (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/.eslintrc.js (74%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/LICENSE (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/README.md (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/karma.conf.js (86%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/package.json (93%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/NoopMeter.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/NoopMeterProvider.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/api/metrics.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/index.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/internal/global-utils.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/internal/semver.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/platform/browser/globalThis.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/platform/browser/index.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/platform/index.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/platform/node/globalThis.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/platform/node/index.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/types/Meter.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/types/MeterProvider.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/types/Metric.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/src/types/ObservableResult.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/test/api/api.test.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/test/index-webpack.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/test/internal/global.test.ts (99%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/test/internal/semver.test.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/test/internal/version.test.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/test/noop-implementations/noop-meter.test.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/test/types/Metric.test.ts (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/tsconfig.all.json (78%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/tsconfig.docs.json (100%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/tsconfig.esm.json (78%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/tsconfig.esnext.json (78%) rename {experimental/packages/opentelemetry-api-metrics => api-metrics}/tsconfig.json (69%) diff --git a/CHANGELOG.md b/CHANGELOG.md index f69e2ae6e4..d49dc5e7df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,11 @@ All notable changes to this project will be documented in this file. * ci: run browser tests without circle [#3328](https://github.com/open-telemetry/opentelemetry-js/pull/3328) @dyladan +## Metrics API 1.0.0 + +Metrics API is now stable and generally available. +There are no changes between 1.0.0 and the previous 0.33.0 version. + ## 1.7.0 ### :bug: (Bug Fix) diff --git a/experimental/packages/opentelemetry-api-metrics/.eslintignore b/api-metrics/.eslintignore similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/.eslintignore rename to api-metrics/.eslintignore diff --git a/experimental/packages/opentelemetry-api-metrics/.eslintrc.js b/api-metrics/.eslintrc.js similarity index 74% rename from experimental/packages/opentelemetry-api-metrics/.eslintrc.js rename to api-metrics/.eslintrc.js index b9004d2025..7d5c10c7f9 100644 --- a/experimental/packages/opentelemetry-api-metrics/.eslintrc.js +++ b/api-metrics/.eslintrc.js @@ -4,5 +4,5 @@ module.exports = { "commonjs": true, "shared-node-browser": true }, - ...require('../../../eslint.config.js') + ...require('../eslint.config.js') } diff --git a/experimental/packages/opentelemetry-api-metrics/LICENSE b/api-metrics/LICENSE similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/LICENSE rename to api-metrics/LICENSE diff --git a/experimental/packages/opentelemetry-api-metrics/README.md b/api-metrics/README.md similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/README.md rename to api-metrics/README.md diff --git a/experimental/packages/opentelemetry-api-metrics/karma.conf.js b/api-metrics/karma.conf.js similarity index 86% rename from experimental/packages/opentelemetry-api-metrics/karma.conf.js rename to api-metrics/karma.conf.js index 6174839d65..29b7b9bc5a 100644 --- a/experimental/packages/opentelemetry-api-metrics/karma.conf.js +++ b/api-metrics/karma.conf.js @@ -14,8 +14,8 @@ * limitations under the License. */ -const karmaWebpackConfig = require('../../../karma.webpack'); -const karmaBaseConfig = require('../../../karma.base'); +const karmaWebpackConfig = require('../karma.webpack'); +const karmaBaseConfig = require('../karma.base'); module.exports = (config) => { config.set(Object.assign({}, karmaBaseConfig, { diff --git a/experimental/packages/opentelemetry-api-metrics/package.json b/api-metrics/package.json similarity index 93% rename from experimental/packages/opentelemetry-api-metrics/package.json rename to api-metrics/package.json index 3629d3de90..fc920cbb19 100644 --- a/experimental/packages/opentelemetry-api-metrics/package.json +++ b/api-metrics/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/api-metrics", - "version": "0.33.0", + "version": "1.0.0", "description": "Public metrics API for OpenTelemetry", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -19,15 +19,15 @@ "clean": "tsc --build --clean tsconfig.all.json", "test": "nyc ts-mocha -p tsconfig.json test/**/*.test.ts", "test:browser": "nyc karma start --single-run", - "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../../", - "codecov:browser": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../../", + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../", + "codecov:browser": "nyc report --reporter=json && codecov -f coverage/*.json -p ../", "build": "npm run compile", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", - "version": "node ../../../scripts/version-update.js", + "version": "node ../scripts/version-update.js", "watch": "tsc --build --watch tsconfig.all.json", "precompile": "lerna run version --scope $(npm pkg get name) --include-dependencies", - "prewatch": "node ../../../scripts/version-update.js" + "prewatch": "node ../scripts/version-update.js" }, "keywords": [ "opentelemetry", diff --git a/experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts b/api-metrics/src/NoopMeter.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts rename to api-metrics/src/NoopMeter.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/NoopMeterProvider.ts b/api-metrics/src/NoopMeterProvider.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/NoopMeterProvider.ts rename to api-metrics/src/NoopMeterProvider.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/api/metrics.ts b/api-metrics/src/api/metrics.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/api/metrics.ts rename to api-metrics/src/api/metrics.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/index.ts b/api-metrics/src/index.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/index.ts rename to api-metrics/src/index.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/internal/global-utils.ts b/api-metrics/src/internal/global-utils.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/internal/global-utils.ts rename to api-metrics/src/internal/global-utils.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/internal/semver.ts b/api-metrics/src/internal/semver.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/internal/semver.ts rename to api-metrics/src/internal/semver.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/platform/browser/globalThis.ts b/api-metrics/src/platform/browser/globalThis.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/platform/browser/globalThis.ts rename to api-metrics/src/platform/browser/globalThis.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/platform/browser/index.ts b/api-metrics/src/platform/browser/index.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/platform/browser/index.ts rename to api-metrics/src/platform/browser/index.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/platform/index.ts b/api-metrics/src/platform/index.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/platform/index.ts rename to api-metrics/src/platform/index.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/platform/node/globalThis.ts b/api-metrics/src/platform/node/globalThis.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/platform/node/globalThis.ts rename to api-metrics/src/platform/node/globalThis.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/platform/node/index.ts b/api-metrics/src/platform/node/index.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/platform/node/index.ts rename to api-metrics/src/platform/node/index.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/types/Meter.ts b/api-metrics/src/types/Meter.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/types/Meter.ts rename to api-metrics/src/types/Meter.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/types/MeterProvider.ts b/api-metrics/src/types/MeterProvider.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/types/MeterProvider.ts rename to api-metrics/src/types/MeterProvider.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts b/api-metrics/src/types/Metric.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts rename to api-metrics/src/types/Metric.ts diff --git a/experimental/packages/opentelemetry-api-metrics/src/types/ObservableResult.ts b/api-metrics/src/types/ObservableResult.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/src/types/ObservableResult.ts rename to api-metrics/src/types/ObservableResult.ts diff --git a/experimental/packages/opentelemetry-api-metrics/test/api/api.test.ts b/api-metrics/test/api/api.test.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/test/api/api.test.ts rename to api-metrics/test/api/api.test.ts diff --git a/experimental/packages/opentelemetry-api-metrics/test/index-webpack.ts b/api-metrics/test/index-webpack.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/test/index-webpack.ts rename to api-metrics/test/index-webpack.ts diff --git a/experimental/packages/opentelemetry-api-metrics/test/internal/global.test.ts b/api-metrics/test/internal/global.test.ts similarity index 99% rename from experimental/packages/opentelemetry-api-metrics/test/internal/global.test.ts rename to api-metrics/test/internal/global.test.ts index 69fbee57c6..e239728706 100644 --- a/experimental/packages/opentelemetry-api-metrics/test/internal/global.test.ts +++ b/api-metrics/test/internal/global.test.ts @@ -31,7 +31,7 @@ const api2 = require('../../src') as typeof import('../../src'); // This will need to be changed manually on major version changes. // It is intentionally not autogenerated to ensure the author of the change is aware of what they are doing. -const GLOBAL_METRICS_API_SYMBOL_KEY = 'opentelemetry.js.api.metrics.0'; +const GLOBAL_METRICS_API_SYMBOL_KEY = 'opentelemetry.js.api.metrics.1'; const getMockLogger = () => ({ verbose: sinon.spy(), diff --git a/experimental/packages/opentelemetry-api-metrics/test/internal/semver.test.ts b/api-metrics/test/internal/semver.test.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/test/internal/semver.test.ts rename to api-metrics/test/internal/semver.test.ts diff --git a/experimental/packages/opentelemetry-api-metrics/test/internal/version.test.ts b/api-metrics/test/internal/version.test.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/test/internal/version.test.ts rename to api-metrics/test/internal/version.test.ts diff --git a/experimental/packages/opentelemetry-api-metrics/test/noop-implementations/noop-meter.test.ts b/api-metrics/test/noop-implementations/noop-meter.test.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/test/noop-implementations/noop-meter.test.ts rename to api-metrics/test/noop-implementations/noop-meter.test.ts diff --git a/experimental/packages/opentelemetry-api-metrics/test/types/Metric.test.ts b/api-metrics/test/types/Metric.test.ts similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/test/types/Metric.test.ts rename to api-metrics/test/types/Metric.test.ts diff --git a/experimental/packages/opentelemetry-api-metrics/tsconfig.all.json b/api-metrics/tsconfig.all.json similarity index 78% rename from experimental/packages/opentelemetry-api-metrics/tsconfig.all.json rename to api-metrics/tsconfig.all.json index 06c5491334..4aa747e89f 100644 --- a/experimental/packages/opentelemetry-api-metrics/tsconfig.all.json +++ b/api-metrics/tsconfig.all.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../tsconfig.base.json", "files": [], "references": [ { "path": "./tsconfig.json" }, diff --git a/experimental/packages/opentelemetry-api-metrics/tsconfig.docs.json b/api-metrics/tsconfig.docs.json similarity index 100% rename from experimental/packages/opentelemetry-api-metrics/tsconfig.docs.json rename to api-metrics/tsconfig.docs.json diff --git a/experimental/packages/opentelemetry-api-metrics/tsconfig.esm.json b/api-metrics/tsconfig.esm.json similarity index 78% rename from experimental/packages/opentelemetry-api-metrics/tsconfig.esm.json rename to api-metrics/tsconfig.esm.json index 379f547a46..50611a86af 100644 --- a/experimental/packages/opentelemetry-api-metrics/tsconfig.esm.json +++ b/api-metrics/tsconfig.esm.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.esm.json", + "extends": "../tsconfig.base.esm.json", "compilerOptions": { "rootDir": "src", "outDir": "build/esm", diff --git a/experimental/packages/opentelemetry-api-metrics/tsconfig.esnext.json b/api-metrics/tsconfig.esnext.json similarity index 78% rename from experimental/packages/opentelemetry-api-metrics/tsconfig.esnext.json rename to api-metrics/tsconfig.esnext.json index cb78dd6ff3..0e3427cbc1 100644 --- a/experimental/packages/opentelemetry-api-metrics/tsconfig.esnext.json +++ b/api-metrics/tsconfig.esnext.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.esnext.json", + "extends": "../tsconfig.base.esnext.json", "compilerOptions": { "rootDir": "src", "outDir": "build/esnext", diff --git a/experimental/packages/opentelemetry-api-metrics/tsconfig.json b/api-metrics/tsconfig.json similarity index 69% rename from experimental/packages/opentelemetry-api-metrics/tsconfig.json rename to api-metrics/tsconfig.json index e22548584a..e8b7e27e71 100644 --- a/experimental/packages/opentelemetry-api-metrics/tsconfig.json +++ b/api-metrics/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../tsconfig.base.json", "compilerOptions": { "rootDir": ".", "outDir": "build" @@ -10,7 +10,7 @@ ], "references": [ { - "path": "../../../api" + "path": "../api" } ] } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json index 1be23dd8b2..c2a6041ceb 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json @@ -13,13 +13,13 @@ "path": "../../../api" }, { - "path": "../../../packages/opentelemetry-core" + "path": "../../../api-metrics" }, { - "path": "../../../packages/opentelemetry-resources" + "path": "../../../packages/opentelemetry-core" }, { - "path": "../opentelemetry-api-metrics" + "path": "../../../packages/opentelemetry-resources" }, { "path": "../opentelemetry-exporter-metrics-otlp-http" diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json index 1f981132ba..7a2d809dff 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json @@ -13,13 +13,13 @@ "path": "../../../api" }, { - "path": "../../../packages/opentelemetry-core" + "path": "../../../api-metrics" }, { - "path": "../../../packages/opentelemetry-resources" + "path": "../../../packages/opentelemetry-core" }, { - "path": "../opentelemetry-api-metrics" + "path": "../../../packages/opentelemetry-resources" }, { "path": "../opentelemetry-sdk-metrics" diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json index 63e825da3f..133b1e8bb8 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json @@ -13,13 +13,13 @@ "path": "../../../api" }, { - "path": "../../../packages/opentelemetry-core" + "path": "../../../api-metrics" }, { - "path": "../../../packages/opentelemetry-resources" + "path": "../../../packages/opentelemetry-core" }, { - "path": "../opentelemetry-api-metrics" + "path": "../../../packages/opentelemetry-resources" }, { "path": "../opentelemetry-exporter-metrics-otlp-http" diff --git a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json index 1283f8e6d4..9ac6b6fd90 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json @@ -13,13 +13,13 @@ "path": "../../../api" }, { - "path": "../../../packages/opentelemetry-core" + "path": "../../../api-metrics" }, { - "path": "../../../packages/opentelemetry-resources" + "path": "../../../packages/opentelemetry-core" }, { - "path": "../opentelemetry-api-metrics" + "path": "../../../packages/opentelemetry-resources" }, { "path": "../opentelemetry-sdk-metrics" diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json index c21412396f..25a8b5fb03 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json @@ -12,6 +12,9 @@ { "path": "../../../api" }, + { + "path": "../../../api-metrics" + }, { "path": "../../../packages/opentelemetry-context-async-hooks" }, @@ -27,9 +30,6 @@ { "path": "../../../packages/opentelemetry-semantic-conventions" }, - { - "path": "../opentelemetry-api-metrics" - }, { "path": "../opentelemetry-instrumentation" } diff --git a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json index 94828c26da..c6158c12c1 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json @@ -12,6 +12,9 @@ { "path": "../../../api" }, + { + "path": "../../../api-metrics" + }, { "path": "../../../packages/opentelemetry-context-async-hooks" }, @@ -27,9 +30,6 @@ { "path": "../../../packages/opentelemetry-semantic-conventions" }, - { - "path": "../opentelemetry-api-metrics" - }, { "path": "../opentelemetry-instrumentation" }, diff --git a/experimental/packages/opentelemetry-instrumentation/tsconfig.esnext.json b/experimental/packages/opentelemetry-instrumentation/tsconfig.esnext.json index 5b297a614a..dc405c942c 100644 --- a/experimental/packages/opentelemetry-instrumentation/tsconfig.esnext.json +++ b/experimental/packages/opentelemetry-instrumentation/tsconfig.esnext.json @@ -10,7 +10,7 @@ ], "references": [ { - "path": "../opentelemetry-api-metrics/tsconfig.esnext.json" + "path": "../../../api-metrics/tsconfig.esnext.json" } ] } diff --git a/experimental/packages/opentelemetry-instrumentation/tsconfig.json b/experimental/packages/opentelemetry-instrumentation/tsconfig.json index af53bd1755..ce90824272 100644 --- a/experimental/packages/opentelemetry-instrumentation/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation/tsconfig.json @@ -13,7 +13,7 @@ "path": "../../../api" }, { - "path": "../opentelemetry-api-metrics" + "path": "../../../api-metrics" } ] } diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json index 53f9deefd0..fb267e4d26 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json +++ b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json @@ -10,7 +10,7 @@ ], "references": [ { - "path": "../opentelemetry-api-metrics/tsconfig.esm.json" + "path": "../../../api-metrics/tsconfig.esnext.json" } ] } diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json index 5b297a614a..dc405c942c 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json +++ b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json @@ -10,7 +10,7 @@ ], "references": [ { - "path": "../opentelemetry-api-metrics/tsconfig.esnext.json" + "path": "../../../api-metrics/tsconfig.esnext.json" } ] } diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json index c56be210db..bcce5660d3 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json +++ b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json @@ -13,13 +13,13 @@ "path": "../../../api" }, { - "path": "../../../packages/opentelemetry-core" + "path": "../../../api-metrics" }, { - "path": "../../../packages/opentelemetry-resources" + "path": "../../../packages/opentelemetry-core" }, { - "path": "../opentelemetry-api-metrics" + "path": "../../../packages/opentelemetry-resources" } ] } diff --git a/experimental/packages/opentelemetry-sdk-node/tsconfig.json b/experimental/packages/opentelemetry-sdk-node/tsconfig.json index 55448ab788..1ecf7ce067 100644 --- a/experimental/packages/opentelemetry-sdk-node/tsconfig.json +++ b/experimental/packages/opentelemetry-sdk-node/tsconfig.json @@ -12,6 +12,9 @@ { "path": "../../../api" }, + { + "path": "../../../api-metrics" + }, { "path": "../../../packages/opentelemetry-context-async-hooks" }, @@ -45,9 +48,6 @@ { "path": "../exporter-trace-otlp-proto" }, - { - "path": "../opentelemetry-api-metrics" - }, { "path": "../opentelemetry-instrumentation" }, diff --git a/experimental/packages/otlp-transformer/tsconfig.json b/experimental/packages/otlp-transformer/tsconfig.json index e06d7404a5..64be5006a0 100644 --- a/experimental/packages/otlp-transformer/tsconfig.json +++ b/experimental/packages/otlp-transformer/tsconfig.json @@ -12,6 +12,9 @@ { "path": "../../../api" }, + { + "path": "../../../api-metrics" + }, { "path": "../../../packages/opentelemetry-core" }, @@ -21,9 +24,6 @@ { "path": "../../../packages/opentelemetry-sdk-trace-base" }, - { - "path": "../opentelemetry-api-metrics" - }, { "path": "../opentelemetry-sdk-metrics" } diff --git a/lerna.json b/lerna.json index d97ab02a62..26c6e6b7bb 100644 --- a/lerna.json +++ b/lerna.json @@ -3,6 +3,7 @@ "npmClient": "npm", "packages": [ "api", + "api-metrics", "packages/*", "experimental/packages/*", "experimental/examples/*", diff --git a/tsconfig.json b/tsconfig.json index 10419db907..a1404aedcb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -53,6 +53,9 @@ { "path": "api" }, + { + "path": "api-metrics" + }, { "path": "packages/opentelemetry-context-async-hooks" }, @@ -110,9 +113,6 @@ { "path": "experimental/packages/exporter-trace-otlp-proto" }, - { - "path": "experimental/packages/opentelemetry-api-metrics" - }, { "path": "experimental/packages/opentelemetry-exporter-metrics-otlp-grpc" }, From f31448ed5c63ecdf8c2f96ceddc46bcd8f563e75 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Fri, 28 Oct 2022 22:42:42 +0800 Subject: [PATCH 54/77] fix(resources): strict OTEL_RESOURCE_ATTRIBUTES decoding (#3341) Co-authored-by: Daniel Dyla --- CHANGELOG.md | 2 ++ .../opentelemetry-sdk-node/test/sdk.test.ts | 2 +- .../src/detectors/EnvDetector.ts | 11 +++--- .../detectors/browser/EnvDetector.test.ts | 35 ++++++++++++++++++- .../test/detectors/node/EnvDetector.test.ts | 25 ++++++++++++- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d49dc5e7df..5dda81b650 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ All notable changes to this project will be documented in this file. [#3327](https://github.com/open-telemetry/opentelemetry-js/pull/3327) @dyladan * fix(resources): fix EnvDetector throwing errors when attribute values contain spaces [#3295](https://github.com/open-telemetry/opentelemetry-js/issues/3295) +* fix(resources): strict OTEL_RESOURCE_ATTRIBUTES baggage octet decoding + [#3341](https://github.com/open-telemetry/opentelemetry-js/pull/3341) @legendecas ### :books: (Refine Doc) diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index 12a3833744..bb78a3f7d3 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -416,7 +416,7 @@ describe('Node SDK', () => { describe('with a faulty environment variable', () => { beforeEach(() => { - process.env.OTEL_RESOURCE_ATTRIBUTES = 'bad=~attribute'; + process.env.OTEL_RESOURCE_ATTRIBUTES = 'bad=\\attribute'; }); it('prints correct error messages when EnvDetector has an invalid variable', async () => { diff --git a/packages/opentelemetry-resources/src/detectors/EnvDetector.ts b/packages/opentelemetry-resources/src/detectors/EnvDetector.ts index 44f15dcdfe..b7a98ff4e1 100644 --- a/packages/opentelemetry-resources/src/detectors/EnvDetector.ts +++ b/packages/opentelemetry-resources/src/detectors/EnvDetector.ts @@ -117,7 +117,7 @@ class EnvDetector implements Detector { if (!this._isValid(value)) { throw new Error(`Attribute value ${this._ERROR_MESSAGE_INVALID_VALUE}`); } - attributes[key] = value; + attributes[key] = decodeURIComponent(value); } return attributes; } @@ -130,13 +130,14 @@ class EnvDetector implements Detector { * @returns Whether the String is valid. */ private _isValid(name: string): boolean { - return name.length <= this._MAX_LENGTH && this._isPrintableString(name); + return name.length <= this._MAX_LENGTH && this._isBaggageOctetString(name); } - private _isPrintableString(str: string): boolean { + // https://www.w3.org/TR/baggage/#definition + private _isBaggageOctetString(str: string): boolean { for (let i = 0; i < str.length; i++) { - const ch: string = str.charAt(i); - if (ch < ' ' || ch >= '~') { + const ch = str.charCodeAt(i); + if (ch < 0x21 || ch === 0x2C || ch === 0x3B || ch === 0x5C || ch > 0x7E) { return false; } } diff --git a/packages/opentelemetry-resources/test/detectors/browser/EnvDetector.test.ts b/packages/opentelemetry-resources/test/detectors/browser/EnvDetector.test.ts index 940b5b07c0..da4354f89e 100644 --- a/packages/opentelemetry-resources/test/detectors/browser/EnvDetector.test.ts +++ b/packages/opentelemetry-resources/test/detectors/browser/EnvDetector.test.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import * as assert from 'assert'; import { RAW_ENVIRONMENT } from '@opentelemetry/core'; import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; import { envDetector, Resource } from '../../../src'; @@ -27,7 +28,7 @@ describeBrowser('envDetector() on web browser', () => { describe('with valid env', () => { before(() => { (globalThis as typeof globalThis & RAW_ENVIRONMENT).OTEL_RESOURCE_ATTRIBUTES = - 'webengine.name="chromium",webengine.version="99",webengine.description="Chromium"'; + 'webengine.name="chromium",webengine.version="99",webengine.description="Chromium",custom.key="custom%20value"'; }); after(() => { @@ -41,6 +42,38 @@ describeBrowser('envDetector() on web browser', () => { [SemanticResourceAttributes.WEBENGINE_VERSION]: '99', [SemanticResourceAttributes.WEBENGINE_DESCRIPTION]: 'Chromium', }); + assert.strictEqual(resource.attributes['custom.key'], 'custom value'); + }); + }); + + + describe('with invalid env', () => { + const values = [ + 'webengine.description="with spaces"', + ]; + + for (const value of values) { + describe(`value: '${value}'`, () => { + before(() => { + (globalThis as typeof globalThis & RAW_ENVIRONMENT).OTEL_RESOURCE_ATTRIBUTES = value; + }); + + after(() => { + delete (globalThis as typeof globalThis & RAW_ENVIRONMENT).OTEL_RESOURCE_ATTRIBUTES; + }); + + it('should return empty resource', async () => { + const resource: Resource = await envDetector.detect(); + assertEmptyResource(resource); + }); + }); + } + }); + + describe('with empty env', () => { + it('should return empty resource', async () => { + const resource: Resource = await envDetector.detect(); + assertEmptyResource(resource); }); }); diff --git a/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts b/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts index 486de2b4bb..3f6b63a1f1 100644 --- a/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts +++ b/packages/opentelemetry-resources/test/detectors/node/EnvDetector.test.ts @@ -25,7 +25,7 @@ describeNode('envDetector() on Node.js', () => { describe('with valid env', () => { before(() => { process.env.OTEL_RESOURCE_ATTRIBUTES = - 'k8s.pod.name="pod-xyz-123",k8s.cluster.name="c1",k8s.namespace.name="default",k8s.deployment.name="deployment name"'; + 'k8s.pod.name="pod-xyz-123",k8s.cluster.name="c1",k8s.namespace.name="default",k8s.deployment.name="deployment%20name"'; }); after(() => { @@ -43,6 +43,29 @@ describeNode('envDetector() on Node.js', () => { }); }); + describe('with invalid env', () => { + const values = [ + 'k8s.deployment.name="with spaces"', + ]; + + for (const value of values) { + describe(`value: '${value}'`, () => { + before(() => { + process.env.OTEL_RESOURCE_ATTRIBUTES = value; + }); + + after(() => { + delete process.env.OTEL_RESOURCE_ATTRIBUTES; + }); + + it('should return empty resource', async () => { + const resource: Resource = await envDetector.detect(); + assertEmptyResource(resource); + }); + }); + } + }); + describe('with empty env', () => { it('should return empty resource', async () => { const resource: Resource = await envDetector.detect(); From a3e40da38aafd0809a5a9702bd181c4d4bebfcae Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 28 Oct 2022 13:01:22 -0400 Subject: [PATCH 55/77] Revert #3134 - remove anchored clock (#3359) --- CHANGELOG.md | 2 ++ .../opentelemetry-sdk-trace-base/src/Tracer.ts | 16 ---------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dda81b650..79881b78dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ All notable changes to this project will be documented in this file. [#3327](https://github.com/open-telemetry/opentelemetry-js/pull/3327) @dyladan * fix(resources): fix EnvDetector throwing errors when attribute values contain spaces [#3295](https://github.com/open-telemetry/opentelemetry-js/issues/3295) +* fix(trace): fix an issue which caused negative span durations in web based spans + [#3359](https://github.com/open-telemetry/opentelemetry-js/pull/3359) @dyladan * fix(resources): strict OTEL_RESOURCE_ATTRIBUTES baggage octet decoding [#3341](https://github.com/open-telemetry/opentelemetry-js/pull/3341) @legendecas diff --git a/packages/opentelemetry-sdk-trace-base/src/Tracer.ts b/packages/opentelemetry-sdk-trace-base/src/Tracer.ts index 4af02e2494..23d0f47895 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Tracer.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Tracer.ts @@ -19,8 +19,6 @@ import { InstrumentationLibrary, sanitizeAttributes, isTracingSuppressed, - AnchoredClock, - otperformance, } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; import { BasicTracerProvider } from './BasicTracerProvider'; @@ -74,22 +72,10 @@ export class Tracer implements api.Tracer { context = api.trace.deleteSpan(context); } const parentSpan = api.trace.getSpan(context); - let clock: AnchoredClock | undefined; - if (parentSpan) { - clock = (parentSpan as any)['_clock']; - } - - if (!clock) { - clock = new AnchoredClock(Date, otperformance); - if (parentSpan) { - (parentSpan as any)['_clock'] = clock; - } - } if (isTracingSuppressed(context)) { api.diag.debug('Instrumentation suppressed, returning Noop Span'); const nonRecordingSpan = api.trace.wrapSpanContext(api.INVALID_SPAN_CONTEXT); - (nonRecordingSpan as any)['_clock'] = clock; return nonRecordingSpan; } @@ -134,7 +120,6 @@ export class Tracer implements api.Tracer { if (samplingResult.decision === api.SamplingDecision.NOT_RECORD) { api.diag.debug('Recording is off, propagating context in a non-recording span'); const nonRecordingSpan = api.trace.wrapSpanContext(spanContext); - (nonRecordingSpan as any)['_clock'] = clock; return nonRecordingSpan; } @@ -147,7 +132,6 @@ export class Tracer implements api.Tracer { parentSpanId, links, options.startTime, - clock, ); // Set initial span attributes. The attributes object may have been mutated // by the sampler, so we sanitize the merged attributes before setting them. From 2cee814ea80be70eb4a18193e7cadd8075cc54b9 Mon Sep 17 00:00:00 2001 From: Abinet18 <35442169+Abinet18@users.noreply.github.com> Date: Tue, 1 Nov 2022 17:21:27 -0700 Subject: [PATCH 56/77] Browser detector module (#3292) --- experimental/CHANGELOG.md | 1 + .../.eslintignore | 1 + .../.eslintrc.js | 8 + .../opentelemetry-browser-detector/.npmignore | 4 + .../opentelemetry-browser-detector/LICENSE | 201 ++++++++++++++++++ .../opentelemetry-browser-detector/README.md | 54 +++++ .../karma.conf.js | 24 +++ .../package.json | 77 +++++++ .../src/BrowserDetector.ts | 74 +++++++ .../src/index.ts | 17 ++ .../src/types.ts | 28 +++ .../test/BrowserDetector.test.ts | 88 ++++++++ .../test/index-webpack.ts | 21 ++ .../test/util.ts | 79 +++++++ .../tsconfig.all.json | 9 + .../tsconfig.esm.json | 11 + .../tsconfig.esnext.json | 11 + .../tsconfig.json | 22 ++ tsconfig.json | 3 + 19 files changed, 733 insertions(+) create mode 100644 experimental/packages/opentelemetry-browser-detector/.eslintignore create mode 100644 experimental/packages/opentelemetry-browser-detector/.eslintrc.js create mode 100644 experimental/packages/opentelemetry-browser-detector/.npmignore create mode 100644 experimental/packages/opentelemetry-browser-detector/LICENSE create mode 100644 experimental/packages/opentelemetry-browser-detector/README.md create mode 100644 experimental/packages/opentelemetry-browser-detector/karma.conf.js create mode 100644 experimental/packages/opentelemetry-browser-detector/package.json create mode 100644 experimental/packages/opentelemetry-browser-detector/src/BrowserDetector.ts create mode 100644 experimental/packages/opentelemetry-browser-detector/src/index.ts create mode 100644 experimental/packages/opentelemetry-browser-detector/src/types.ts create mode 100644 experimental/packages/opentelemetry-browser-detector/test/BrowserDetector.test.ts create mode 100644 experimental/packages/opentelemetry-browser-detector/test/index-webpack.ts create mode 100644 experimental/packages/opentelemetry-browser-detector/test/util.ts create mode 100644 experimental/packages/opentelemetry-browser-detector/tsconfig.all.json create mode 100644 experimental/packages/opentelemetry-browser-detector/tsconfig.esm.json create mode 100644 experimental/packages/opentelemetry-browser-detector/tsconfig.esnext.json create mode 100644 experimental/packages/opentelemetry-browser-detector/tsconfig.json diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 6d2de9fb60..a2f7b6b6bd 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to experimental packages in this project will be documented * feat(sdk-node): configure trace exporter with environment variables [#3143](https://github.com/open-telemetry/opentelemetry-js/pull/3143) @svetlanabrennan * feat: enable tree shaking [#3329](https://github.com/open-telemetry/opentelemetry-js/pull/3329) @pkanal * feat(prometheus): serialize resource as target_info gauge [#3300](https://github.com/open-telemetry/opentelemetry-js/pull/3300) @pichlermarc +* feat(detectors): add browser detector module [#3292](https://github.com/open-telemetry/opentelemetry-js/pull/3292) @abinet18 * deps: remove unused proto-loader dependencies and update grpc-js and proto-loader versions [#3337](https://github.com/open-telemetry/opentelemetry-js/pull/3337) @seemk * feat(metrics-exporters): configure temporality via environment variable [#3305](https://github.com/open-telemetry/opentelemetry-js/pull/3305) @pichlermarc diff --git a/experimental/packages/opentelemetry-browser-detector/.eslintignore b/experimental/packages/opentelemetry-browser-detector/.eslintignore new file mode 100644 index 0000000000..378eac25d3 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/.eslintignore @@ -0,0 +1 @@ +build diff --git a/experimental/packages/opentelemetry-browser-detector/.eslintrc.js b/experimental/packages/opentelemetry-browser-detector/.eslintrc.js new file mode 100644 index 0000000000..3ed0fbeba3 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + "env": { + "mocha": true, + "commonjs": true, + "node": true, + }, + ...require('../../../eslint.config.js') +} diff --git a/experimental/packages/opentelemetry-browser-detector/.npmignore b/experimental/packages/opentelemetry-browser-detector/.npmignore new file mode 100644 index 0000000000..9505ba9450 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/.npmignore @@ -0,0 +1,4 @@ +/bin +/coverage +/doc +/test diff --git a/experimental/packages/opentelemetry-browser-detector/LICENSE b/experimental/packages/opentelemetry-browser-detector/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + 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. diff --git a/experimental/packages/opentelemetry-browser-detector/README.md b/experimental/packages/opentelemetry-browser-detector/README.md new file mode 100644 index 0000000000..a1e9002ea9 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/README.md @@ -0,0 +1,54 @@ +# OpenTelemetry Browser Detector + +**Note: This is an experimental package under active development. New releases may include breaking changes.** + +This module provides detector for browser environments + +## Installation + +```bash +npm install --save @opentelemetry/opentelemetry-browser-detector +``` + +## Usage + +```js +import { Resource, detectResources } from '@opentelemetry/resources'; +import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; +import { browserDetector } from '@opentelemetry/opentelemetry-browser-detector'; + +async function start(){ + let resource= new Resource({ + [SemanticResourceAttributes.SERVICE_NAME]: 'Test App Name', + }); + let detectedResources= await detectResources({detectors:[browserDetector]}); + resource=resource.merge(detectedResources); + const provider = new WebTracerProvider({ + resource + }); + + provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter( {url:CONF.url ,headers:{}}),{exportTimeoutMillis:CONF.timeOutMillis,scheduledDelayMillis:CONF.delayMillis})); + provider.register({ + // Changing default contextManager to use ZoneContextManager - supports asynchronous operations - optional + contextManager: new ZoneContextManager(), + }); + +// Registering instrumentations + + registerInstrumentations({ + instrumentations: [ + new DocumentLoadInstrumentation(), + new XMLHttpRequestInstrumentation(), + new FetchInstrumentation(), + ], + }); +} + + +start().then(()=> console.log("Instrumentation started")); + +``` + +The browser identification attributes will be added to the resource spans when traces are created. +These attributes include platform, brands, mobile, language if the browser supports +the userAgentData api, otherwise it will contain only the user_agent informations diff --git a/experimental/packages/opentelemetry-browser-detector/karma.conf.js b/experimental/packages/opentelemetry-browser-detector/karma.conf.js new file mode 100644 index 0000000000..6174839d65 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/karma.conf.js @@ -0,0 +1,24 @@ +/*! + * 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 + * + * 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. + */ + +const karmaWebpackConfig = require('../../../karma.webpack'); +const karmaBaseConfig = require('../../../karma.base'); + +module.exports = (config) => { + config.set(Object.assign({}, karmaBaseConfig, { + webpack: karmaWebpackConfig + })) +}; diff --git a/experimental/packages/opentelemetry-browser-detector/package.json b/experimental/packages/opentelemetry-browser-detector/package.json new file mode 100644 index 0000000000..6fef4a3c9e --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/package.json @@ -0,0 +1,77 @@ +{ + "name": "@opentelemetry/opentelemetry-browser-detector", + "version": "0.33.0", + "description": "OpenTelemetry Resource Detector for Browser", + "main": "build/src/index.js", + "module": "build/esm/index.js", + "esnext": "build/esnext/index.js", + "types": "build/src/index.d.ts", + "repository": "open-telemetry/opentelemetry-js", + "scripts": { + "prepublishOnly": "npm run compile", + "compile": "tsc --build tsconfig.all.json", + "clean": "tsc --build --clean tsconfig.all.json", + "lint": "eslint . --ext .ts", + "lint:fix": "eslint . --ext .ts --fix", + "test": "nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'", + "test:browser": "nyc karma start --single-run", + "tdd": "npm run test -- --watch-extensions ts --watch", + "tdd:browser": "karma start", + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../../", + "version": "node ../../../scripts/version-update.js", + "watch": "tsc --build --watch tsconfig.all.json", + "precompile": "lerna run version --scope $(npm pkg get name) --include-dependencies", + "prewatch": "npm run precompile", + "peer-api-check": "node ../../../scripts/peer-api-check.js" + }, + "keywords": [ + "opentelemetry", + "browser", + "resource", + "detector" + ], + "author": "OpenTelemetry Authors", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "files": [ + "build/esm/**/*.js", + "build/esm/**/*.js.map", + "build/esm/**/*.d.ts", + "build/esnext/**/*.js", + "build/esnext/**/*.js.map", + "build/esnext/**/*.d.ts", + "build/src/**/*.js", + "build/src/**/*.js.map", + "build/src/**/*.d.ts", + "doc", + "LICENSE", + "README.md" + ], + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "@babel/core": "7.16.0", + "@opentelemetry/api": "^1.0.0", + "@types/mocha": "9.1.1", + "@types/node": "18.6.5", + "@types/sinon": "10.0.13", + "codecov": "3.8.3", + "mocha": "10.0.0", + "nyc": "15.1.0", + "sinon": "14.0.0", + "ts-loader": "8.4.0", + "ts-mocha": "10.0.0", + "typescript": "4.4.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "dependencies": { + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/semantic-conventions": "1.7.0" + }, + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/browser-detector" +} diff --git a/experimental/packages/opentelemetry-browser-detector/src/BrowserDetector.ts b/experimental/packages/opentelemetry-browser-detector/src/BrowserDetector.ts new file mode 100644 index 0000000000..d0e9dea278 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/src/BrowserDetector.ts @@ -0,0 +1,74 @@ +/* + * 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 { Detector, Resource, ResourceDetectionConfig } from '@opentelemetry/resources'; +import { ResourceAttributes } from '@opentelemetry/resources'; +import { BROWSER_ATTRIBUTES, UserAgentData } from './types'; + +/** + * BrowserDetector will be used to detect the resources related to browser. + */ +class BrowserDetector implements Detector { + async detect(config?: ResourceDetectionConfig): Promise { + const isBrowser = typeof navigator !== 'undefined'; + if (!isBrowser) { + return Resource.empty(); + } + const browserResource: ResourceAttributes = getBrowserAttributes(); + return this._getResourceAttributes(browserResource, config); + } + /** + * Validates browser resource attribute map from browser variables + * + * @param browserResource The un-sanitized resource attributes from browser as key/value pairs. + * @param config: Config + * @returns The sanitized resource attributes. + */ + private _getResourceAttributes( + browserResource: ResourceAttributes, + _config?: ResourceDetectionConfig + ) { + if ( + !browserResource[BROWSER_ATTRIBUTES.USER_AGENT] && !browserResource[BROWSER_ATTRIBUTES.PLATFORM] + ) { + diag.debug( + 'BrowserDetector failed: Unable to find required browser resources. ' + ); + return Resource.empty(); + } else { + return new Resource(browserResource); + } + } +} + +// Add Browser related attributes to resources +function getBrowserAttributes(): ResourceAttributes { + const browserAttribs : ResourceAttributes = {}; + const userAgentData : UserAgentData | undefined = (navigator as any).userAgentData; + if (userAgentData) { + browserAttribs[BROWSER_ATTRIBUTES.PLATFORM] = userAgentData.platform; + browserAttribs[BROWSER_ATTRIBUTES.BRANDS] = userAgentData.brands.map(b => `${b.brand} ${b.version}`); + browserAttribs[BROWSER_ATTRIBUTES.MOBILE] = userAgentData.mobile; + } else { + browserAttribs[BROWSER_ATTRIBUTES.USER_AGENT] = navigator.userAgent; + } + browserAttribs[BROWSER_ATTRIBUTES.LANGUAGE]=navigator.language; + return browserAttribs; +} + + +export const browserDetector = new BrowserDetector(); diff --git a/experimental/packages/opentelemetry-browser-detector/src/index.ts b/experimental/packages/opentelemetry-browser-detector/src/index.ts new file mode 100644 index 0000000000..7209990763 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/src/index.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './BrowserDetector'; diff --git a/experimental/packages/opentelemetry-browser-detector/src/types.ts b/experimental/packages/opentelemetry-browser-detector/src/types.ts new file mode 100644 index 0000000000..52d8a6610d --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/src/types.ts @@ -0,0 +1,28 @@ +/* + * 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. + */ +export type UserAgentData = { + brands: {brand:string,version:string}[], + platform: string, + mobile: boolean +}; + +export const BROWSER_ATTRIBUTES = { + PLATFORM: 'browser.platform', //TODO replace with SemantecConventions attribute when available + BRANDS: 'browser.brands', + MOBILE: 'browser.mobile', + LANGUAGE: 'browser.language', + USER_AGENT: 'browser.user_agent' +}; diff --git a/experimental/packages/opentelemetry-browser-detector/test/BrowserDetector.test.ts b/experimental/packages/opentelemetry-browser-detector/test/BrowserDetector.test.ts new file mode 100644 index 0000000000..07143c869b --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/test/BrowserDetector.test.ts @@ -0,0 +1,88 @@ +/* + * 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 sinon from 'sinon'; +import { Resource } from '@opentelemetry/resources'; +import { browserDetector } from '../src/BrowserDetector'; +import { + describeBrowser, + assertResource, + assertEmptyResource +} from './util'; + +describeBrowser('browserDetector()', () => { + afterEach(() => { + sinon.restore(); + }); + + it('should return browser information with userAgentData', async () => { + sinon.stub(globalThis, 'navigator').value({ + userAgent: 'dddd', + language: 'en-US', + userAgentData: { + platform: 'platform', + brands:[ + { + brand: 'Chromium', + version: '106' + }, + { + brand: 'Google Chrome', + version: '106' + }, + { + brand: 'Not;A=Brand', + version: '99' + } + ], + mobile: false + } + }); + + const resource: Resource = await browserDetector.detect(); + assertResource(resource, { + platform: 'platform', + brands: [ + 'Chromium 106', + 'Google Chrome 106', + 'Not;A=Brand 99' + ], + mobile: false, + language: 'en-US', + }); + }); + + it('should return browser information with userAgent', async () => { + sinon.stub(globalThis, 'navigator').value({ + userAgent: 'dddd', + language: 'en-US', + userAgentData: undefined, + }); + + const resource: Resource = await browserDetector.detect(); + assertResource(resource, { + language: 'en-US', + user_agent: 'dddd' + }); + }); + + it('should return empty resources if user agent is missing', async () => { + sinon.stub(globalThis, 'navigator').value({ + userAgent: '', + }); + const resource: Resource = await browserDetector.detect(); + assertEmptyResource(resource); + }); +}); diff --git a/experimental/packages/opentelemetry-browser-detector/test/index-webpack.ts b/experimental/packages/opentelemetry-browser-detector/test/index-webpack.ts new file mode 100644 index 0000000000..9cfc10baa1 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/test/index-webpack.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +const testsContext = require.context('.', true, /test$/); +testsContext.keys().forEach(testsContext); + +const srcContext = require.context('.', true, /src$/); +srcContext.keys().forEach(srcContext); diff --git a/experimental/packages/opentelemetry-browser-detector/test/util.ts b/experimental/packages/opentelemetry-browser-detector/test/util.ts new file mode 100644 index 0000000000..62be8b3c2e --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/test/util.ts @@ -0,0 +1,79 @@ +/* + * 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 {Suite} from 'mocha'; +import * as assert from 'assert'; +import {BROWSER_ATTRIBUTES} from '../src/types'; +import {Resource} from '@opentelemetry/resources'; + +export function describeBrowser(title: string, fn: (this: Suite) => void) { + title = `Browser: ${title}`; + if (typeof process === 'object' && process.release?.name === 'node') { + return describe.skip(title, fn); + } + return describe(title, fn); +} + +export const assertResource = ( + resource: Resource, + validations: { + platform?: string, + brands?: string[], + mobile?: boolean, + language?: string, + user_agent?: string + } +) => { + if (validations.platform) { + assert.strictEqual( + resource.attributes[BROWSER_ATTRIBUTES.PLATFORM], + validations.platform + ); + } + if (validations.brands) { + assert.ok(Array.isArray(resource.attributes[BROWSER_ATTRIBUTES.BRANDS])); + assert.deepStrictEqual( + (resource.attributes[BROWSER_ATTRIBUTES.BRANDS] as string[]), + validations.brands + ); + } + if (validations.mobile) { + assert.strictEqual( + (resource.attributes[BROWSER_ATTRIBUTES.MOBILE]), + validations.mobile + ); + } + if (validations.language) { + assert.strictEqual( + (resource.attributes[BROWSER_ATTRIBUTES.LANGUAGE]), + validations.language + ); + } + if (validations.user_agent) { + assert.strictEqual( + (resource.attributes[BROWSER_ATTRIBUTES.USER_AGENT]), + validations.user_agent + ); + } +}; + +/** + * Test utility method to validate an empty resource + * + * @param resource the Resource to validate + */ +export const assertEmptyResource = (resource: Resource) => { + assert.strictEqual(Object.keys(resource.attributes).length, 0); +}; diff --git a/experimental/packages/opentelemetry-browser-detector/tsconfig.all.json b/experimental/packages/opentelemetry-browser-detector/tsconfig.all.json new file mode 100644 index 0000000000..06c5491334 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/tsconfig.all.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "references": [ + { "path": "./tsconfig.json" }, + { "path": "./tsconfig.esm.json" }, + { "path": "./tsconfig.esnext.json" } + ] +} diff --git a/experimental/packages/opentelemetry-browser-detector/tsconfig.esm.json b/experimental/packages/opentelemetry-browser-detector/tsconfig.esm.json new file mode 100644 index 0000000000..379f547a46 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/tsconfig.esm.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.base.esm.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build/esm", + "tsBuildInfoFile": "build/esm/tsconfig.esm.tsbuildinfo" + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/experimental/packages/opentelemetry-browser-detector/tsconfig.esnext.json b/experimental/packages/opentelemetry-browser-detector/tsconfig.esnext.json new file mode 100644 index 0000000000..cb78dd6ff3 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/tsconfig.esnext.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.base.esnext.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build/esnext", + "tsBuildInfoFile": "build/esnext/tsconfig.esnext.tsbuildinfo" + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/experimental/packages/opentelemetry-browser-detector/tsconfig.json b/experimental/packages/opentelemetry-browser-detector/tsconfig.json new file mode 100644 index 0000000000..6294198a83 --- /dev/null +++ b/experimental/packages/opentelemetry-browser-detector/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "build" + }, + "include": [ + "src/**/*.ts", + "test/**/*.ts" + ], + "references": [ + { + "path": "../../../api" + }, + { + "path": "../../../packages/opentelemetry-resources" + }, + { + "path": "../../../packages/opentelemetry-semantic-conventions" + } + ] +} diff --git a/tsconfig.json b/tsconfig.json index a1404aedcb..d6642f0f02 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -113,6 +113,9 @@ { "path": "experimental/packages/exporter-trace-otlp-proto" }, + { + "path": "experimental/packages/opentelemetry-browser-detector" + }, { "path": "experimental/packages/opentelemetry-exporter-metrics-otlp-grpc" }, From bdc603cc761faf49f2a7a2af535ee80f29611d67 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 2 Nov 2022 08:50:04 -0400 Subject: [PATCH 57/77] Update README (#3369) --- README.md | 70 +++++++++++++++++++++++++--------------------------- package.json | 2 +- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 2c3e786c40..160ec8d3e0 100644 --- a/README.md +++ b/README.md @@ -41,43 +41,15 @@ This is the JavaScript version of [OpenTelemetry](https://opentelemetry.io/), a framework for collecting traces and metrics from applications. -## Compatibility Matrix - -| API Version | Core version | Experimental Packages | -| ----------- | ------------ | --------------------- | -| 1.2.x | 1.7.x | 0.33.x | -| 1.2.x | 1.6.x | 0.32.x | -| 1.1.x | 1.5.x | 0.31.x | -| 1.1.x | 1.4.x | 0.30.x | -| 1.1.x | 1.2.x, 1.3.x | 0.29.x | -| 1.1.x | 1.1.x | 0.28.x | -| 1.0.x | 1.0.x | 0.26.x, 0.27.x | -| 1.0.x | 0.26.x | ----- | -| 1.0.x | 0.25.x | ----- | -| 1.0.x | 0.24.x | ----- | -| 1.0.x | 0.23.x | ----- | -| 1.0.x | 0.22.x | ----- | -| 0.21.x | 0.21.x | ----- | -| 0.20.x | 0.20.x | ----- | -| v1.0.0-rc.3 | 0.19.x | ----- | -| 0.18.x | 0.18.x | ----- | -| | 0.17.x | ----- | -| | 0.16.x | ----- | -| | 0.15.x | ----- | -| | 0.14.x | ----- | -| | 0.13.x | ----- | -| | 0.12.x | ----- | -| | 0.11.x | ----- | +## Quick Start -## Versioning - -The current version for each package can be found in the respective `package.json` file for that module. For additional details see the [versioning and stability][spec-versioning] document in the specification. +The following describes how to set up tracing for a basic web application. +For more detailed documentation, see the website at . -## Quick start +### Installation -### Application Owner - -#### Install Dependencies +Dependencies with the `latest` tag on NPM should be compatible with each other. +See the [version compatibility matrix](#package-version-compatibility) below for more information. ```shell npm install --save @opentelemetry/api @@ -87,7 +59,7 @@ npm install --save @opentelemetry/auto-instrumentations-node **Note:** `auto-instrumentations-node` is a meta package from [opentelemetry-js-contrib](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/metapackages/auto-instrumentations-node) that provides a simple way to initialize multiple Node.js instrumentations. -#### Instantiate Tracing +### Set up Tracing ```js // tracing.js @@ -127,7 +99,7 @@ process.on('SIGTERM', () => { }); ``` -#### Run Your Application +### Run Your Application ```shell node -r ./tracing.js app.js @@ -135,7 +107,7 @@ node -r ./tracing.js app.js The above example will emit auto-instrumented telemetry about your Node.js application to the console. For a more in-depth example, see the [Getting Started Guide](https://opentelemetry.io/docs/js/getting-started/). For more information about automatic instrumentation see [@opentelemetry/sdk-trace-node][otel-node], which provides auto-instrumentation for Node.js applications. If the automatic instrumentation does not suit your needs, or you would like to create manual traces, see [@opentelemetry/sdk-trace-base][otel-tracing] -### Library Author +## Library Author If you are a library author looking to build OpenTelemetry into your library, please see [the documentation][docs]. As a library author, it is important that you only depend on properties and methods published on the public API. If you use any properties or methods from the SDK that are not officially a part of the public API, your library may break if an [Application Owner](#application-owner) uses a different SDK implementation. @@ -160,6 +132,30 @@ Please note that versions of Node.JS v8 prior to `v8.12.0` will NOT work, becaus Automated browser tests are run in the latest version of Headless Chrome. There is currently no list of officially supported browsers, but OpenTelemetry is developed using standard web technologies with wide support and should work in currently supported versions of major browsers. +## Package Version Compatibility + +OpenTelemetry is released as a set of distinct packages in 3 categories: API, stable SDK, and experimental. +The API is located at [/api](/api/), the stable SDK packages are in the [/packages](/packages/) directory, and the experimental packages are listed in the [/experimental/packages](/experimental/packages/) directory. +There may also be API packages for experimental signals in the experimental directory. +All stable packages are released with the same version, and all experimental packages are released with the same version. +The below table describes which versions of each set of packages are expected to work together. + +| API | Stable Packages | Experimental Packages | +| ----- | --------------- | --------------------- | +| 1.2.x | 1.7.x | 0.33.x | +| 1.2.x | 1.6.x | 0.32.x | +| 1.1.x | 1.5.x | 0.31.x | +| 1.1.x | 1.4.x | 0.30.x | +| 1.1.x | 1.3.x | 0.29.x | +| 1.1.x | 1.2.x | 0.29.x | +| 1.1.x | 1.1.x | 0.28.x | +| 1.0.x | 1.0.x | 0.27.x | +| 1.0.x | 1.0.x | 0.26.x | + +## Versioning + +The current version for each package can be found in the respective `package.json` file for that module. For additional details see the [versioning and stability][spec-versioning] document in the specification. + ## Feature Status | Signal | API Status | SDK Status | diff --git a/package.json b/package.json index a83a8c46a5..26755f3cb8 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "codecov:browser": "lerna run codecov:browser", "codecov:webworker": "lerna run codecov:webworker", "predocs-test": "npm run docs", - "docs": "typedoc && touch docs/.nojekyll", + "docs": "typedoc --readme none && touch docs/.nojekyll", "docs-deploy": "gh-pages --dotfiles --dist docs", "docs:test": "linkinator docs --silent --retry && linkinator doc/*.md --silent --retry", "lint": "lerna run lint", From 1536a7cbb2078812e9953aff8b1ed0ee53dfff7e Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Fri, 4 Nov 2022 02:53:54 +0800 Subject: [PATCH 58/77] feat(api): merge api-metrics into api (#3374) Co-authored-by: Marc Pichler --- .github/workflows/unit-test.yml | 12 +- CHANGELOG.md | 2 + api-metrics/.eslintrc.js | 8 - api-metrics/LICENSE | 201 ------------------ api-metrics/README.md | 98 --------- api-metrics/karma.conf.js | 24 --- api-metrics/package.json | 87 -------- api-metrics/src/index.ts | 54 ----- api-metrics/src/internal/global-utils.ts | 96 --------- api-metrics/src/internal/semver.ts | 140 ------------ .../src/platform/browser/globalThis.ts | 35 --- api-metrics/test/api/api.test.ts | 49 ----- api-metrics/test/index-webpack.ts | 20 -- api-metrics/test/internal/global.test.ts | 118 ---------- api-metrics/test/internal/semver.test.ts | 148 ------------- api-metrics/test/types/Metric.test.ts | 109 ---------- api-metrics/tsconfig.all.json | 9 - api-metrics/tsconfig.docs.json | 15 -- api-metrics/tsconfig.esm.json | 11 - api-metrics/tsconfig.esnext.json | 11 - api-metrics/tsconfig.json | 16 -- {api-metrics => api}/.eslintignore | 0 api/TODO.md | 11 - api/package.json | 8 +- {api-metrics => api}/src/api/metrics.ts | 15 +- .../index.ts => api/src/context-api.ts | 6 +- api/src/diag-api.ts | 26 +++ api/src/diag/index.ts | 18 -- api/src/index.ts | 163 +++++++++----- api/src/internal/global-utils.ts | 4 +- .../index.ts => api/src/metrics-api.ts | 6 +- .../src/types => api/src/metrics}/Meter.ts | 0 .../src/metrics}/MeterProvider.ts | 0 .../src/types => api/src/metrics}/Metric.ts | 7 +- .../src => api/src/metrics}/NoopMeter.ts | 4 +- .../src/metrics}/NoopMeterProvider.ts | 4 +- .../src/metrics}/ObservableResult.ts | 0 api/src/platform/browser/globalThis.ts | 3 +- .../index.ts => api/src/propagation-api.ts | 6 +- .../globalThis.ts => api/src/trace-api.ts | 8 +- api/test/{ => common}/api/api.test.ts | 41 +++- api/test/{ => common}/baggage/Baggage.test.ts | 2 +- .../context/NoopContextManager.test.ts | 4 +- .../{ => common}/diag/ComponentLogger.test.ts | 2 +- .../{ => common}/diag/consoleLogger.test.ts | 2 +- api/test/{ => common}/diag/logLevel.test.ts | 8 +- api/test/{ => common}/diag/logger.test.ts | 6 +- api/test/{ => common}/internal/global.test.ts | 12 +- api/test/{ => common}/internal/semver.test.ts | 4 +- .../test/common}/internal/version.test.ts | 4 +- api/test/common/metrics/Metric.test.ts | 109 ++++++++++ .../noop-implementations/noop-meter.test.ts | 4 +- .../noop-implementations/noop-span.test.ts | 4 +- .../noop-tracer-provider.test.ts | 4 +- .../noop-implementations/noop-tracer.test.ts | 6 +- .../proxy-tracer.test.ts | 6 +- .../trace/spancontext-utils.test.ts | 4 +- .../trace/tracestate-validators.test.ts | 2 +- .../{ => common}/trace/tracestate.test.ts | 4 +- api/test/index-webpack.ts | 7 +- api/test/index-webpack.worker.ts | 2 +- api/test/internal/version.test.ts | 30 --- api/test/tree-shaking/tree-shaking.test.ts | 119 +++++++++++ .../examples/metrics/index.js | 3 +- examples/opentelemetry-web/package.json | 3 +- examples/otlp-exporter-node/package.json | 3 +- experimental/examples/prometheus/package.json | 2 +- experimental/packages/api-logs/README.md | 4 +- .../package.json | 5 +- .../test/metricsHelper.ts | 2 +- .../tsconfig.json | 3 - .../package.json | 5 +- .../browser/CollectorMetricExporter.test.ts | 3 +- .../test/metricsHelper.ts | 2 +- .../tsconfig.json | 3 - .../package.json | 5 +- .../test/metricsHelper.ts | 2 +- .../tsconfig.json | 3 - .../package.json | 5 +- .../src/PrometheusSerializer.ts | 10 +- .../test/PrometheusExporter.test.ts | 4 +- .../test/PrometheusSerializer.test.ts | 2 +- .../tsconfig.json | 3 - .../package.json | 5 +- .../src/instrumentation.ts | 3 +- .../tsconfig.json | 3 - .../package.json | 5 +- .../src/http.ts | 5 +- .../src/utils.ts | 2 +- .../tsconfig.json | 3 - .../package.json | 5 +- .../src/autoLoader.ts | 3 +- .../src/autoLoaderUtils.ts | 3 +- .../src/instrumentation.ts | 4 +- .../src/types.ts | 3 +- .../src/types_internal.ts | 3 +- .../test/common/autoLoader.test.ts | 11 +- .../tsconfig.esnext.json | 5 - .../tsconfig.json | 3 - .../opentelemetry-sdk-metrics/README.md | 4 +- .../opentelemetry-sdk-metrics/package.json | 5 +- .../src/InstrumentDescriptor.ts | 2 +- .../src/Instruments.ts | 58 +++-- .../opentelemetry-sdk-metrics/src/Meter.ts | 55 +++-- .../src/MeterProvider.ts | 23 +- .../src/ObservableResult.ts | 30 +-- .../src/aggregator/types.ts | 3 +- ...AlignedHistogramBucketExemplarReservoir.ts | 3 +- .../exemplar/AlwaysSampleExemplarFilter.ts | 3 +- .../src/exemplar/Exemplar.ts | 3 +- .../src/exemplar/ExemplarFilter.ts | 3 +- .../src/exemplar/ExemplarReservoir.ts | 3 +- .../src/exemplar/NeverSampleExemplarFilter.ts | 3 +- .../SimpleFixedSizeExemplarReservoir.ts | 3 +- .../src/exemplar/WithTraceExemplarFilter.ts | 3 +- .../src/export/MetricData.ts | 3 +- .../src/state/DeltaMetricProcessor.ts | 3 +- .../src/state/HashMap.ts | 2 +- .../src/state/MultiWritableMetricStorage.ts | 3 +- .../src/state/ObservableRegistry.ts | 6 +- .../src/state/SyncMetricStorage.ts | 3 +- .../src/state/WritableMetricStorage.ts | 3 +- .../opentelemetry-sdk-metrics/src/utils.ts | 2 +- .../src/view/AttributesProcessor.ts | 3 +- .../test/Instruments.test.ts | 2 +- .../test/Meter.test.ts | 2 +- .../test/ObservableResult.test.ts | 2 +- .../test/aggregator/Histogram.test.ts | 3 +- .../test/export/ConsoleMetricExporter.test.ts | 2 +- .../export/InMemoryMetricExporter.test.ts | 2 +- .../test/state/HashMap.test.ts | 2 +- .../test/state/MetricStorageRegistry.test.ts | 5 +- .../state/MultiWritableMetricStorage.test.ts | 2 +- .../opentelemetry-sdk-metrics/test/util.ts | 6 +- .../test/utils.test.ts | 2 +- .../tsconfig.esm.json | 5 - .../tsconfig.esnext.json | 5 - .../opentelemetry-sdk-metrics/tsconfig.json | 3 - .../opentelemetry-sdk-node/package.json | 5 +- .../opentelemetry-sdk-node/src/sdk.ts | 3 +- .../opentelemetry-sdk-node/test/sdk.test.ts | 2 +- .../opentelemetry-sdk-node/tsconfig.json | 3 - .../packages/otlp-transformer/package.json | 5 +- .../otlp-transformer/src/metrics/internal.ts | 2 +- .../otlp-transformer/test/metrics.test.ts | 2 +- .../packages/otlp-transformer/tsconfig.json | 3 - lerna.json | 1 - .../src/platform/browser/globalThis.ts | 3 +- tsconfig.base.json | 1 + tsconfig.json | 4 - 150 files changed, 698 insertions(+), 1687 deletions(-) delete mode 100644 api-metrics/.eslintrc.js delete mode 100644 api-metrics/LICENSE delete mode 100644 api-metrics/README.md delete mode 100644 api-metrics/karma.conf.js delete mode 100644 api-metrics/package.json delete mode 100644 api-metrics/src/index.ts delete mode 100644 api-metrics/src/internal/global-utils.ts delete mode 100644 api-metrics/src/internal/semver.ts delete mode 100644 api-metrics/src/platform/browser/globalThis.ts delete mode 100644 api-metrics/test/api/api.test.ts delete mode 100644 api-metrics/test/index-webpack.ts delete mode 100644 api-metrics/test/internal/global.test.ts delete mode 100644 api-metrics/test/internal/semver.test.ts delete mode 100644 api-metrics/test/types/Metric.test.ts delete mode 100644 api-metrics/tsconfig.all.json delete mode 100644 api-metrics/tsconfig.docs.json delete mode 100644 api-metrics/tsconfig.esm.json delete mode 100644 api-metrics/tsconfig.esnext.json delete mode 100644 api-metrics/tsconfig.json rename {api-metrics => api}/.eslintignore (100%) delete mode 100644 api/TODO.md rename {api-metrics => api}/src/api/metrics.ts (81%) rename api-metrics/src/platform/index.ts => api/src/context-api.ts (72%) create mode 100644 api/src/diag-api.ts delete mode 100644 api/src/diag/index.ts rename api-metrics/src/platform/browser/index.ts => api/src/metrics-api.ts (72%) rename {api-metrics/src/types => api/src/metrics}/Meter.ts (100%) rename {api-metrics/src/types => api/src/metrics}/MeterProvider.ts (100%) rename {api-metrics/src/types => api/src/metrics}/Metric.ts (95%) rename {api-metrics/src => api/src/metrics}/NoopMeter.ts (98%) rename {api-metrics/src => api/src/metrics}/NoopMeterProvider.ts (90%) rename {api-metrics/src/types => api/src/metrics}/ObservableResult.ts (100%) rename api-metrics/src/platform/node/index.ts => api/src/propagation-api.ts (70%) rename api-metrics/src/platform/node/globalThis.ts => api/src/trace-api.ts (72%) rename api/test/{ => common}/api/api.test.ts (85%) rename api/test/{ => common}/baggage/Baggage.test.ts (99%) rename api/test/{ => common}/context/NoopContextManager.test.ts (95%) rename api/test/{ => common}/diag/ComponentLogger.test.ts (96%) rename api/test/{ => common}/diag/consoleLogger.test.ts (99%) rename api/test/{ => common}/diag/logLevel.test.ts (96%) rename api/test/{ => common}/diag/logger.test.ts (94%) rename api/test/{ => common}/internal/global.test.ts (93%) rename api/test/{ => common}/internal/semver.test.ts (97%) rename {api-metrics/test => api/test/common}/internal/version.test.ts (90%) create mode 100644 api/test/common/metrics/Metric.test.ts rename {api-metrics/test => api/test/common}/noop-implementations/noop-meter.test.ts (97%) rename api/test/{ => common}/noop-implementations/noop-span.test.ts (94%) rename api/test/{ => common}/noop-implementations/noop-tracer-provider.test.ts (88%) rename api/test/{ => common}/noop-implementations/noop-tracer.test.ts (93%) rename api/test/{ => common}/proxy-implementations/proxy-tracer.test.ts (97%) rename api/test/{ => common}/trace/spancontext-utils.test.ts (96%) rename api/test/{ => common}/trace/tracestate-validators.test.ts (96%) rename api/test/{ => common}/trace/tracestate.test.ts (97%) delete mode 100644 api/test/internal/version.test.ts create mode 100644 api/test/tree-shaking/tree-shaking.test.ts diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 734bd6b29d..618e168e1e 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -47,10 +47,15 @@ jobs: - name: Build 🔧 run: | - npm run compile + npx lerna run compile - name: Unit tests - run: npm run test + run: | + # TODO(legendecas): webpack https://stackoverflow.com/questions/69692842/error-message-error0308010cdigital-envelope-routinesunsupported + if [ "${{ matrix.node_version }}" = "18" ]; then + export NODE_OPTIONS=--openssl-legacy-provider + fi + npm run test - name: Report Coverage run: npm run codecov if: ${{ matrix.node_version == '14' }} @@ -88,7 +93,8 @@ jobs: - name: Build 🔧 run: | - npm run compile + npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe" + npx lerna run compile - name: Unit tests run: npm run test diff --git a/CHANGELOG.md b/CHANGELOG.md index 79881b78dd..ce8e916111 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file. ### :boom: Breaking Change +* feat(api): merge api-metrics into api [#3374](https://github.com/open-telemetry/opentelemetry-js/pull/3374) @legendecas + ### :rocket: (Enhancement) * feat(sdk-trace): re-export sdk-trace-base in sdk-trace-node and web [#3319](https://github.com/open-telemetry/opentelemetry-js/pull/3319) @legendecas diff --git a/api-metrics/.eslintrc.js b/api-metrics/.eslintrc.js deleted file mode 100644 index 7d5c10c7f9..0000000000 --- a/api-metrics/.eslintrc.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - "env": { - "mocha": true, - "commonjs": true, - "shared-node-browser": true - }, - ...require('../eslint.config.js') -} diff --git a/api-metrics/LICENSE b/api-metrics/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/api-metrics/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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 - - 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. diff --git a/api-metrics/README.md b/api-metrics/README.md deleted file mode 100644 index d9e8745ec7..0000000000 --- a/api-metrics/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# OpenTelemetry API for JavaScript - -[![NPM Published Version][npm-img]][npm-url] -[![Apache License][license-image]][license-image] - -**Note: This is an experimental package under active development. New releases may include breaking changes.** - -This package provides everything needed to interact with the unstable OpenTelemetry Metrics API, including all TypeScript interfaces, enums, and no-op implementations. It is intended for use both on the server and in the browser. - -## Beta Software - Use at your own risk - -The metrics API is considered alpha software and there is no guarantee of stability or long-term support. When the API is stabilized, it will be made available and supported long-term in the `@opentelemetry/api` package and this package will be deprecated. - -## Quick Start - -To get started you need to install the SDK and instrumentations, create a MeterProvider, and register it with the API. - -### Install Dependencies - -```sh -$ # Install metrics dependencies -$ npm install \ - @opentelemetry/api-metrics \ - @opentelemetry/sdk-metrics \ - @opentelemetry/exporter-prometheus # add exporters as needed -``` - -> Note: this example is for node.js. See [examples/tracer-web](https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/tracer-web) for a browser example. - -### Initialize the SDK - -Before any other module in your application is loaded, you must initialize the global tracer and meter providers. If you fail to initialize a provider, no-op implementations will be provided to any library which acquires them from the API. - -To collect traces and metrics, you will have to tell the SDK where to export telemetry data to. This example uses Jaeger and Prometheus, but exporters exist for [other tracing backends][other-tracing-backends]. If you're not sure if there is an exporter for your tracing backend, contact your tracing provider. - -#### Metrics - -```javascript -const api = require("@opentelemetry/api-metrics"); -const { MeterProvider } = require("@opentelemetry/sdk-metrics"); -const { PrometheusExporter } = require("@opentelemetry/exporter-prometheus"); - -// The Prometheus exporter runs an HTTP server which the Prometheus backend -// scrapes to collect metrics. -const exporter = new PrometheusExporter({ startServer: true }); -// Creates MeterProvider and installs the exporter as a MetricReader -const meterProvider = new MeterProvider(); -meterProvider.addMetricReader(exporter); - -/** - * Registering the provider with the API allows it to be discovered - * and used by instrumentation libraries. - */ -api.metrics.setGlobalMeterProvider(meterProvider); -``` - -## Version Compatibility - -Because the npm installer and node module resolution algorithm could potentially allow two or more copies of any given package to exist within the same `node_modules` structure, the OpenTelemetry API takes advantage of a variable on the `global` object to store the global API. When an API method in the API package is called, it checks if this `global` API exists and proxies calls to it if and only if it is a compatible API version. This means if a package has a dependency on an OpenTelemetry API version which is not compatible with the API used by the end user, the package will receive a no-op implementation of the API. - -## Advanced Use - -### API Methods - -If you are writing an instrumentation library, or prefer to call the API methods directly rather than using the `register` method on the Tracer/Meter Provider, OpenTelemetry provides direct access to the underlying API methods through the `@opentelemetry/api-metrics` package. API entry points are defined as global singleton objects `trace`, `metrics`, `propagation`, and `context` which contain methods used to initialize SDK implementations and acquire resources from the API. - -- [Metrics API Documentation][metrics-api-docs] - -```javascript -const api = require("@opentelemetry/api-metrics"); - -/* Initialize MeterProvider */ -api.metrics.setGlobalMeterProvider(meterProvider); -/* returns meterProvider (no-op if a working provider has not been initialized) */ -api.metrics.getMeterProvider(); -/* returns a meter from the registered global meter provider (no-op if a working provider has not been initialized) */ -api.metrics.getMeter(name, version); -``` - -## Useful links - -- For more information on OpenTelemetry, visit: -- For more about OpenTelemetry JavaScript: -- For help or feedback on this project, join us in [GitHub Discussions][discussions-url] - -## License - -Apache 2.0 - See [LICENSE][license-url] for more information. - -[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions -[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE -[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat -[npm-url]: https://www.npmjs.com/package/@opentelemetry/api-metrics -[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi-metrics.svg - -[metrics-api-docs]: https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api_metrics.html - -[other-tracing-backends]: https://github.com/open-telemetry/opentelemetry-js#trace-exporters diff --git a/api-metrics/karma.conf.js b/api-metrics/karma.conf.js deleted file mode 100644 index 29b7b9bc5a..0000000000 --- a/api-metrics/karma.conf.js +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * 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 - * - * 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. - */ - -const karmaWebpackConfig = require('../karma.webpack'); -const karmaBaseConfig = require('../karma.base'); - -module.exports = (config) => { - config.set(Object.assign({}, karmaBaseConfig, { - webpack: karmaWebpackConfig - })) -}; diff --git a/api-metrics/package.json b/api-metrics/package.json deleted file mode 100644 index fc920cbb19..0000000000 --- a/api-metrics/package.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "name": "@opentelemetry/api-metrics", - "version": "1.0.0", - "description": "Public metrics API for OpenTelemetry", - "main": "build/src/index.js", - "module": "build/esm/index.js", - "esnext": "build/esnext/index.js", - "types": "build/src/index.d.ts", - "browser": { - "./src/platform/index.ts": "./src/platform/browser/index.ts", - "./build/esm/platform/index.js": "./build/esm/platform/browser/index.js", - "./build/esnext/platform/index.js": "./build/esnext/platform/browser/index.js", - "./build/src/platform/index.js": "./build/src/platform/browser/index.js" - }, - "repository": "open-telemetry/opentelemetry-js", - "scripts": { - "prepublishOnly": "npm run compile", - "compile": "tsc --build tsconfig.all.json", - "clean": "tsc --build --clean tsconfig.all.json", - "test": "nyc ts-mocha -p tsconfig.json test/**/*.test.ts", - "test:browser": "nyc karma start --single-run", - "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../", - "codecov:browser": "nyc report --reporter=json && codecov -f coverage/*.json -p ../", - "build": "npm run compile", - "lint": "eslint . --ext .ts", - "lint:fix": "eslint . --ext .ts --fix", - "version": "node ../scripts/version-update.js", - "watch": "tsc --build --watch tsconfig.all.json", - "precompile": "lerna run version --scope $(npm pkg get name) --include-dependencies", - "prewatch": "node ../scripts/version-update.js" - }, - "keywords": [ - "opentelemetry", - "nodejs", - "browser", - "profiling", - "metrics", - "stats", - "monitoring" - ], - "author": "OpenTelemetry Authors", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - }, - "files": [ - "build/esm/**/*.js", - "build/esm/**/*.js.map", - "build/esm/**/*.d.ts", - "build/esnext/**/*.js", - "build/esnext/**/*.js.map", - "build/esnext/**/*.d.ts", - "build/src/**/*.js", - "build/src/**/*.js.map", - "build/src/**/*.d.ts", - "doc", - "LICENSE", - "README.md" - ], - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@opentelemetry/api": "^1.0.0" - }, - "devDependencies": { - "@types/mocha": "10.0.0", - "@types/node": "18.6.5", - "@types/webpack-env": "1.16.3", - "codecov": "3.8.3", - "istanbul-instrumenter-loader": "3.0.1", - "karma": "6.3.16", - "karma-chrome-launcher": "3.1.0", - "karma-coverage-istanbul-reporter": "3.0.3", - "karma-mocha": "2.0.1", - "karma-spec-reporter": "0.0.32", - "karma-webpack": "4.0.2", - "mocha": "10.0.0", - "nyc": "15.1.0", - "ts-loader": "8.4.0", - "ts-mocha": "10.0.0", - "typescript": "4.4.4", - "webpack": "4.46.0" - }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-api-metrics", - "sideEffects": false -} diff --git a/api-metrics/src/index.ts b/api-metrics/src/index.ts deleted file mode 100644 index 5a59fe2d96..0000000000 --- a/api-metrics/src/index.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -export { - createNoopMeter, -} from './NoopMeter'; - -export { - MeterOptions, - Meter, -} from './types/Meter'; - -export { - MeterProvider, -} from './types/MeterProvider'; - -export { - ValueType, - Counter, - Histogram, - MetricOptions, - Observable, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - UpDownCounter, - BatchObservableCallback, - MetricAttributes, - MetricAttributeValue, - ObservableCallback, -} from './types/Metric'; - -export { - BatchObservableResult, - ObservableResult, -} from './types/ObservableResult'; - -import { MetricsAPI } from './api/metrics'; - -/** Entrypoint for metrics API */ -export const metrics = MetricsAPI.getInstance(); diff --git a/api-metrics/src/internal/global-utils.ts b/api-metrics/src/internal/global-utils.ts deleted file mode 100644 index f83c203398..0000000000 --- a/api-metrics/src/internal/global-utils.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 { _globalThis } from '../platform'; -import { MeterProvider } from '../types/MeterProvider'; -import { VERSION } from '../version'; -import { isCompatible } from './semver'; - -const major = VERSION.split('.')[0]; -const GLOBAL_OPENTELEMETRY_METRICS_API_KEY = Symbol.for( - `opentelemetry.js.api.metrics.${major}` -); - -const _global = _globalThis as OTelGlobal; - -export function registerGlobal( - type: Type, - instance: OTelGlobalAPI[Type], - allowOverride = false -): boolean { - const api = (_global[GLOBAL_OPENTELEMETRY_METRICS_API_KEY] = _global[ - GLOBAL_OPENTELEMETRY_METRICS_API_KEY - ] ?? { - version: VERSION, - }); - - if (!allowOverride && api[type]) { - // already registered an API of this type - const err = new Error( - `@opentelemetry/api: Attempted duplicate registration of API: ${type}` - ); - diag.error(err.stack || err.message); - return false; - } - - if (api.version !== VERSION) { - // All registered APIs must be of the same version exactly - const err = new Error( - '@opentelemetry/api: All API registration versions must match' - ); - diag.error(err.stack || err.message); - return false; - } - - api[type] = instance; - diag.debug( - `@opentelemetry/api: Registered a global for ${type} v${VERSION}.` - ); - - return true; -} - -export function getGlobal( - type: Type -): OTelGlobalAPI[Type] | undefined { - const globalVersion = _global[GLOBAL_OPENTELEMETRY_METRICS_API_KEY]?.version; - if (!globalVersion || !isCompatible(globalVersion)) { - return; - } - return _global[GLOBAL_OPENTELEMETRY_METRICS_API_KEY]?.[type]; -} - -export function unregisterGlobal(type: keyof OTelGlobalAPI) { - diag.debug( - `@opentelemetry/api-metrics: Unregistering a global for ${type} v${VERSION}.` - ); - const api = _global[GLOBAL_OPENTELEMETRY_METRICS_API_KEY]; - - if (api) { - delete api[type]; - } -} - -type OTelGlobal = { - [GLOBAL_OPENTELEMETRY_METRICS_API_KEY]?: OTelGlobalAPI; -}; - -type OTelGlobalAPI = { - version: string; - - metrics?: MeterProvider; -}; diff --git a/api-metrics/src/internal/semver.ts b/api-metrics/src/internal/semver.ts deleted file mode 100644 index 076f9b9b51..0000000000 --- a/api-metrics/src/internal/semver.ts +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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 { VERSION } from '../version'; - -const re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/; - -/** - * Create a function to test an API version to see if it is compatible with the provided ownVersion. - * - * The returned function has the following semantics: - * - Exact match is always compatible - * - Major versions must match exactly - * - 1.x package cannot use global 2.x package - * - 2.x package cannot use global 1.x package - * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API - * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects - * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 - * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor - * - Patch and build tag differences are not considered at this time - * - * @param ownVersion version which should be checked against - */ -export function _makeCompatibilityCheck( - ownVersion: string -): (globalVersion: string) => boolean { - const acceptedVersions = new Set([ownVersion]); - const rejectedVersions = new Set(); - - const myVersionMatch = ownVersion.match(re); - if (!myVersionMatch) { - // we cannot guarantee compatibility so we always return noop - return () => false; - } - - const ownVersionParsed = { - major: +myVersionMatch[1], - minor: +myVersionMatch[2], - patch: +myVersionMatch[3], - prerelease: myVersionMatch[4], - }; - - // if ownVersion has a prerelease tag, versions must match exactly - if (ownVersionParsed.prerelease != null) { - return function isExactmatch(globalVersion: string): boolean { - return globalVersion === ownVersion; - }; - } - - function _reject(v: string) { - rejectedVersions.add(v); - return false; - } - - function _accept(v: string) { - acceptedVersions.add(v); - return true; - } - - return function isCompatible(globalVersion: string): boolean { - if (acceptedVersions.has(globalVersion)) { - return true; - } - - if (rejectedVersions.has(globalVersion)) { - return false; - } - - const globalVersionMatch = globalVersion.match(re); - if (!globalVersionMatch) { - // cannot parse other version - // we cannot guarantee compatibility so we always noop - return _reject(globalVersion); - } - - const globalVersionParsed = { - major: +globalVersionMatch[1], - minor: +globalVersionMatch[2], - patch: +globalVersionMatch[3], - prerelease: globalVersionMatch[4], - }; - - // if globalVersion has a prerelease tag, versions must match exactly - if (globalVersionParsed.prerelease != null) { - return _reject(globalVersion); - } - - // major versions must match - if (ownVersionParsed.major !== globalVersionParsed.major) { - return _reject(globalVersion); - } - - if (ownVersionParsed.major === 0) { - if ( - ownVersionParsed.minor === globalVersionParsed.minor && - ownVersionParsed.patch <= globalVersionParsed.patch - ) { - return _accept(globalVersion); - } - - return _reject(globalVersion); - } - - if (ownVersionParsed.minor <= globalVersionParsed.minor) { - return _accept(globalVersion); - } - - return _reject(globalVersion); - }; -} - -/** - * Test an API version to see if it is compatible with this API. - * - * - Exact match is always compatible - * - Major versions must match exactly - * - 1.x package cannot use global 2.x package - * - 2.x package cannot use global 1.x package - * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API - * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects - * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3 - * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor - * - Patch and build tag differences are not considered at this time - * - * @param version version of the API requesting an instance of the global API - */ -export const isCompatible = _makeCompatibilityCheck(VERSION); diff --git a/api-metrics/src/platform/browser/globalThis.ts b/api-metrics/src/platform/browser/globalThis.ts deleted file mode 100644 index 1dece570f3..0000000000 --- a/api-metrics/src/platform/browser/globalThis.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - */ - -// Updates to this file should also be replicated to @opentelemetry/api and -// @opentelemetry/core too. - -/** - * - globalThis (New standard) - * - self (Will return the current window instance for supported browsers) - * - window (fallback for older browser implementations) - * - global (NodeJS implementation) - * - (When all else fails) - */ - -/** only globals that common to node and browsers are allowed */ -// eslint-disable-next-line node/no-unsupported-features/es-builtins, no-undef -export const _globalThis: typeof globalThis = - typeof globalThis === 'object' ? globalThis : - typeof self === 'object' ? self : - typeof window === 'object' ? window : - typeof global === 'object' ? global : - {} as typeof globalThis; diff --git a/api-metrics/test/api/api.test.ts b/api-metrics/test/api/api.test.ts deleted file mode 100644 index 66278d6bc7..0000000000 --- a/api-metrics/test/api/api.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 { metrics } from '../../src'; -import { NoopMeter } from '../../src/NoopMeter'; -import { NoopMeterProvider } from '../../src/NoopMeterProvider'; - - -describe('API', () => { - it('should expose a meter provider via getMeterProvider', () => { - const meter = metrics.getMeterProvider(); - assert.ok(meter); - assert.strictEqual(typeof meter, 'object'); - }); - - describe('GlobalMeterProvider', () => { - const dummyMeter = new NoopMeter(); - - beforeEach(() => { - metrics.disable(); - }); - - it('should use the global meter provider', () => { - metrics.setGlobalMeterProvider(new TestMeterProvider()); - const meter = metrics.getMeterProvider().getMeter('name'); - assert.deepStrictEqual(meter, dummyMeter); - }); - - class TestMeterProvider extends NoopMeterProvider { - override getMeter() { - return dummyMeter; - } - } - }); -}); diff --git a/api-metrics/test/index-webpack.ts b/api-metrics/test/index-webpack.ts deleted file mode 100644 index 061a48ccfa..0000000000 --- a/api-metrics/test/index-webpack.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -const testsContext = require.context('.', true, /test$/); -testsContext.keys().forEach(testsContext); - -const srcContext = require.context('.', true, /src$/); -srcContext.keys().forEach(srcContext); diff --git a/api-metrics/test/internal/global.test.ts b/api-metrics/test/internal/global.test.ts deleted file mode 100644 index e239728706..0000000000 --- a/api-metrics/test/internal/global.test.ts +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 { getGlobal } from '../../src/internal/global-utils'; -import { _globalThis } from '../../src/platform'; -import { NoopMeterProvider } from '../../src/NoopMeterProvider'; -import sinon = require('sinon'); -import { diag } from '@opentelemetry/api'; - -const api1 = require('../../src') as typeof import('../../src'); - -// clear cache and load a second instance of the api -for (const key of Object.keys(require.cache)) { - delete require.cache[key]; -} -const api2 = require('../../src') as typeof import('../../src'); - -// This will need to be changed manually on major version changes. -// It is intentionally not autogenerated to ensure the author of the change is aware of what they are doing. -const GLOBAL_METRICS_API_SYMBOL_KEY = 'opentelemetry.js.api.metrics.1'; - -const getMockLogger = () => ({ - verbose: sinon.spy(), - debug: sinon.spy(), - info: sinon.spy(), - warn: sinon.spy(), - error: sinon.spy(), -}); - -describe('Global Utils', () => { - // prove they are separate instances - assert.notEqual(api1, api2); - // that return separate noop instances to start - assert.notStrictEqual( - api1.metrics.getMeterProvider(), - api2.metrics.getMeterProvider(), - ); - - beforeEach(() => { - api1.metrics.disable(); - // @ts-expect-error we are modifying internals for testing purposes here - delete _globalThis[Symbol.for(GLOBAL_METRICS_API_SYMBOL_KEY)]; - }); - - it('should change the global meter provider', () => { - const original = api1.metrics.getMeterProvider(); - const newMeterProvider = new NoopMeterProvider(); - api1.metrics.setGlobalMeterProvider(newMeterProvider); - assert.notStrictEqual(api1.metrics.getMeterProvider(), original); - assert.strictEqual(api1.metrics.getMeterProvider(), newMeterProvider); - }); - - it('should load an instance from one which was set in the other', () => { - api1.metrics.setGlobalMeterProvider(new NoopMeterProvider()); - assert.strictEqual( - api1.metrics.getMeterProvider(), - api2.metrics.getMeterProvider() - ); - }); - - it('should disable both if one is disabled', () => { - const manager = new NoopMeterProvider(); - api1.metrics.setGlobalMeterProvider(manager); - - assert.strictEqual(manager, api1.metrics.getMeterProvider()); - api2.metrics.disable(); - assert.notStrictEqual(manager, api1.metrics.getMeterProvider()); - }); - - it('should return the module NoOp implementation if the version is a mismatch', () => { - const newMeterProvider = new NoopMeterProvider(); - api1.metrics.setGlobalMeterProvider(newMeterProvider); - - // ensure new meter provider is returned - assert.strictEqual(api1.metrics.getMeterProvider(), newMeterProvider); - - const globalInstance = getGlobal('metrics'); - assert.ok(globalInstance); - // @ts-expect-error we are modifying internals for testing purposes here - _globalThis[Symbol.for(GLOBAL_METRICS_API_SYMBOL_KEY)].version = '0.0.1'; - - // ensure new meter provider is not returned because version above is incompatible - assert.notStrictEqual( - api1.metrics.getMeterProvider(), - newMeterProvider - ); - }); - - it('should log an error if there is a duplicate registration', () => { - const logger = getMockLogger(); - diag.setLogger(logger); - - api1.metrics.setGlobalMeterProvider(new NoopMeterProvider()); - api1.metrics.setGlobalMeterProvider(new NoopMeterProvider()); - - sinon.assert.calledOnce(logger.error); - assert.strictEqual(logger.error.firstCall.args.length, 1); - assert.ok( - logger.error.firstCall.args[0].startsWith( - 'Error: @opentelemetry/api: Attempted duplicate registration of API: metrics' - ) - ); - }); -}); diff --git a/api-metrics/test/internal/semver.test.ts b/api-metrics/test/internal/semver.test.ts deleted file mode 100644 index e9ac3ec727..0000000000 --- a/api-metrics/test/internal/semver.test.ts +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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 { - isCompatible, - _makeCompatibilityCheck, -} from '../../src/internal/semver'; -import { VERSION } from '../../src/version'; - -describe('semver', () => { - it('should be compatible if versions are equal', () => { - assert.ok(isCompatible(VERSION)); - }); - - it('returns false if own version cannot be parsed', () => { - const check = _makeCompatibilityCheck('this is not semver'); - assert.ok(!check('1.0.0')); - }); - - it('incompatible if other version cannot be parsed', () => { - const check = _makeCompatibilityCheck('0.1.2'); - assert.ok(!check('this is not semver')); - }); - - describe('>= 1.0.0', () => { - const globalVersion = '5.5.5'; - const vers: [string, boolean][] = [ - // same major/minor run should be compatible - ['5.5.5', true], - ['5.5.6', true], - ['5.5.4', true], - - // prerelease version should not be compatible - ['5.5.5-rc.0', false], - - // if our version has a minor version increase, we may try to call methods which don't exist on the global - ['5.6.5', false], - ['5.6.6', false], - ['5.6.4', false], - - // if the global version is ahead of us by a minor revision, it has at least the methods we know about - ['5.4.5', true], - ['5.4.6', true], - ['5.4.4', true], - - // major version mismatch is always incompatible - ['6.5.5', false], - ['6.5.6', false], - ['6.5.4', false], - ['6.6.5', false], - ['6.6.6', false], - ['6.6.4', false], - ['6.4.5', false], - ['6.4.6', false], - ['6.4.4', false], - ['4.5.5', false], - ['4.5.6', false], - ['4.5.4', false], - ['4.6.5', false], - ['4.6.6', false], - ['4.6.4', false], - ['4.4.5', false], - ['4.4.6', false], - ['4.4.4', false], - ]; - - test(globalVersion, vers); - }); - - describe('< 1.0.0', () => { - const globalVersion = '0.5.5'; - const vers: [string, boolean][] = [ - // same minor/patch should be compatible - ['0.5.5', true], - - // prerelease version should not be compatible - ['0.5.5-rc.0', false], - - // if our version has a patch version increase, we may try to call methods which don't exist on the global - ['0.5.6', false], - - // if the global version is ahead of us by a patch revision, it has at least the methods we know about - ['0.5.4', true], - - // minor version mismatch is always incompatible - ['0.6.5', false], - ['0.6.6', false], - ['0.6.4', false], - ['0.4.5', false], - ['0.4.6', false], - ['0.4.4', false], - - // major version mismatch is always incompatible - ['1.5.5', false], - ['1.5.6', false], - ['1.5.4', false], - ['1.6.5', false], - ['1.6.6', false], - ['1.6.4', false], - ['1.4.5', false], - ['1.4.6', false], - ['1.4.4', false], - ]; - - test(globalVersion, vers); - }); - - describe('global version is prerelease', () => { - const globalVersion = '1.0.0-rc.3'; - const vers: [string, boolean][] = [ - // must match exactly - ['1.0.0', false], - ['1.0.0-rc.2', false], - ['1.0.0-rc.4', false], - - ['1.0.0-rc.3', true], - ]; - - test(globalVersion, vers); - }); -}); - -function test(globalVersion: string, vers: [string, boolean][]) { - describe(`global version is ${globalVersion}`, () => { - for (const [version, compatible] of vers) { - it(`API version ${version} ${ - compatible ? 'should' : 'should not' - } be able to access global`, () => { - const check = _makeCompatibilityCheck(version); - assert.strictEqual(check(globalVersion), compatible); - }); - } - }); -} diff --git a/api-metrics/test/types/Metric.test.ts b/api-metrics/test/types/Metric.test.ts deleted file mode 100644 index a499db168f..0000000000 --- a/api-metrics/test/types/Metric.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 { Counter, UpDownCounter, Histogram } from '../../src'; - -describe('Metric', () => { - describe('Counter', () =>{ - it('enable not to define any type', () => { - const counter: Counter = { - add(_value: number, _attribute: unknown) {} - }; - counter.add(1, { 'some-attribute': 'value' }); - }); - - it('enable to use with type', () => { - type Attributes = { - 'some-attribute': string - }; - const counter: Counter = { - add(_value: number, _attribute: Attributes) {} - }; - counter.add(1, { 'some-attribute': 'value' }); - }); - - it('disable wrong attributes by typing', () => { - type Attributes = { - 'some-attribute': string - }; - const counter: Counter = { - add(_value: number, _attribute: Attributes) {} - }; - // @ts-expect-error Expacting the type of Attributes - counter.add(1, { 'another-attribute': 'value' }); - }); - }); - - describe('UpDownCounter', () =>{ - it('enable not to define any type', () => { - const counter: UpDownCounter = { - add(_value: number, _attribute: unknown) {} - }; - counter.add(1, { 'some-attribute': 'value' }); - }); - - it('enable to use with type', () => { - type Attributes = { - 'some-attribute': string - }; - const counter: UpDownCounter = { - add(_value: number, _attribute: Attributes) {} - }; - counter.add(1, { 'some-attribute': 'value' }); - }); - - it('disable wrong attributes by typing', () => { - type Attributes = { - 'some-attribute': string - }; - const counter: UpDownCounter = { - add(_value: number, _attribute: Attributes) {} - }; - // @ts-expect-error Expacting the type of Attributes - counter.add(1, { 'another-attribute': 'value' }); - }); - }); - - describe('Histogram', () =>{ - it('enable not to define any type', () => { - const counter: Histogram = { - record(_value: number, _attribute: unknown) {} - }; - counter.record(1, { 'some-attribute': 'value' }); - }); - - it('enable to use with type', () => { - type Attributes = { - 'some-attribute': string - }; - const counter: Histogram = { - record(_value: number, _attribute: Attributes) {} - }; - counter.record(1, { 'some-attribute': 'value' }); - }); - - it('disable wrong attributes by typing', () => { - type Attributes = { - 'some-attribute': string - }; - const counter: Histogram = { - record(_value: number, _attribute: Attributes) {} - }; - // @ts-expect-error Expacting the type of Attributes - counter.record(1, { 'another-attribute': 'value' }); - }); - }); -}); diff --git a/api-metrics/tsconfig.all.json b/api-metrics/tsconfig.all.json deleted file mode 100644 index 4aa747e89f..0000000000 --- a/api-metrics/tsconfig.all.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../tsconfig.base.json", - "files": [], - "references": [ - { "path": "./tsconfig.json" }, - { "path": "./tsconfig.esm.json" }, - { "path": "./tsconfig.esnext.json" } - ] -} diff --git a/api-metrics/tsconfig.docs.json b/api-metrics/tsconfig.docs.json deleted file mode 100644 index 627fa3ff3e..0000000000 --- a/api-metrics/tsconfig.docs.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "rootDir": ".", - "outDir": "build" - }, - "include": [ - "src/**/*.ts" - ], - "typedocOptions": { - "name": "OpenTelemetry API for JavaScript", - "out": "docs/out", - "mode": "file", - "hideGenerator": true - } -} diff --git a/api-metrics/tsconfig.esm.json b/api-metrics/tsconfig.esm.json deleted file mode 100644 index 50611a86af..0000000000 --- a/api-metrics/tsconfig.esm.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../tsconfig.base.esm.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "build/esm", - "tsBuildInfoFile": "build/esm/tsconfig.esm.tsbuildinfo" - }, - "include": [ - "src/**/*.ts" - ] -} diff --git a/api-metrics/tsconfig.esnext.json b/api-metrics/tsconfig.esnext.json deleted file mode 100644 index 0e3427cbc1..0000000000 --- a/api-metrics/tsconfig.esnext.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../tsconfig.base.esnext.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "build/esnext", - "tsBuildInfoFile": "build/esnext/tsconfig.esnext.tsbuildinfo" - }, - "include": [ - "src/**/*.ts" - ] -} diff --git a/api-metrics/tsconfig.json b/api-metrics/tsconfig.json deleted file mode 100644 index e8b7e27e71..0000000000 --- a/api-metrics/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "../tsconfig.base.json", - "compilerOptions": { - "rootDir": ".", - "outDir": "build" - }, - "include": [ - "src/**/*.ts", - "test/**/*.ts" - ], - "references": [ - { - "path": "../api" - } - ] -} diff --git a/api-metrics/.eslintignore b/api/.eslintignore similarity index 100% rename from api-metrics/.eslintignore rename to api/.eslintignore diff --git a/api/TODO.md b/api/TODO.md deleted file mode 100644 index 30f67e54ec..0000000000 --- a/api/TODO.md +++ /dev/null @@ -1,11 +0,0 @@ -# TODO - -These tasks must be completed before the API package can be released from this repository. - -- [x] remove files specific to the API git repo -- [x] add to lerna monorepo - - [x] add tsconfig files - - [x] add web testing - - [x] build esm versions -- [ ] test node versions 8, 10, and 12 -- [x] add to auto published docs diff --git a/api/package.json b/api/package.json index 4fb085886d..799ea8ab95 100644 --- a/api/package.json +++ b/api/package.json @@ -24,7 +24,7 @@ "lint:fix": "eslint . --ext .ts --fix", "lint": "eslint . --ext .ts", "test:browser": "nyc karma start --single-run", - "test": "nyc ts-mocha -p tsconfig.json test/**/*.test.ts", + "test": "nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'", "test:webworker": "nyc karma start karma.worker.js --single-run", "cycle-check": "dpdm --exit-code circular:1 src/index.ts", "version": "node ../scripts/version-update.js", @@ -63,6 +63,7 @@ "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", + "@types/webpack": "4.41.26", "@types/webpack-env": "1.16.3", "codecov": "3.8.3", "dpdm": "3.10.0", @@ -74,13 +75,16 @@ "karma-mocha-webworker": "1.3.0", "karma-spec-reporter": "0.0.32", "karma-webpack": "4.0.2", + "memfs": "3.4.9", "mocha": "10.0.0", "nyc": "15.1.0", "sinon": "14.0.0", "ts-loader": "8.4.0", "ts-mocha": "10.0.0", "typescript": "4.4.4", + "unionfs": "4.4.0", "webpack": "4.46.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/api" + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/api", + "sideEffects": false } diff --git a/api-metrics/src/api/metrics.ts b/api/src/api/metrics.ts similarity index 81% rename from api-metrics/src/api/metrics.ts rename to api/src/api/metrics.ts index b3f9bac6b6..5353d84b91 100644 --- a/api-metrics/src/api/metrics.ts +++ b/api/src/api/metrics.ts @@ -14,10 +14,13 @@ * limitations under the License. */ -import { Meter, MeterOptions } from '../types/Meter'; -import { MeterProvider } from '../types/MeterProvider'; -import { NOOP_METER_PROVIDER } from '../NoopMeterProvider'; +import { Meter, MeterOptions } from '../metrics/Meter'; +import { MeterProvider } from '../metrics/MeterProvider'; +import { NOOP_METER_PROVIDER } from '../metrics/NoopMeterProvider'; import { getGlobal, registerGlobal, unregisterGlobal } from '../internal/global-utils'; +import { DiagAPI } from './diag'; + +const API_NAME = 'metrics'; /** * Singleton object which represents the entry point to the OpenTelemetry Metrics API @@ -42,14 +45,14 @@ export class MetricsAPI { * Returns true if the meter provider was successfully registered, else false. */ public setGlobalMeterProvider(provider: MeterProvider): boolean { - return registerGlobal('metrics', provider); + return registerGlobal(API_NAME, provider, DiagAPI.instance()); } /** * Returns the global meter provider. */ public getMeterProvider(): MeterProvider { - return getGlobal('metrics') || NOOP_METER_PROVIDER; + return getGlobal(API_NAME) || NOOP_METER_PROVIDER; } /** @@ -61,6 +64,6 @@ export class MetricsAPI { /** Remove the global meter provider */ public disable(): void { - unregisterGlobal('metrics'); + unregisterGlobal(API_NAME, DiagAPI.instance()); } } diff --git a/api-metrics/src/platform/index.ts b/api/src/context-api.ts similarity index 72% rename from api-metrics/src/platform/index.ts rename to api/src/context-api.ts index cdaf8858ce..db474def26 100644 --- a/api-metrics/src/platform/index.ts +++ b/api/src/context-api.ts @@ -14,4 +14,8 @@ * limitations under the License. */ -export * from './node'; +// Split module-level variable definition into separate files to allow +// tree-shaking on each api instance. +import { ContextAPI } from './api/context'; +/** Entrypoint for context API */ +export const context = ContextAPI.getInstance(); diff --git a/api/src/diag-api.ts b/api/src/diag-api.ts new file mode 100644 index 0000000000..ecad84caf4 --- /dev/null +++ b/api/src/diag-api.ts @@ -0,0 +1,26 @@ +/* + * 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. + */ + +// Split module-level variable definition into separate files to allow +// tree-shaking on each api instance. +import { DiagAPI } from './api/diag'; +/** + * Entrypoint for Diag API. + * Defines Diagnostic handler used for internal diagnostic logging operations. + * The default provides a Noop DiagLogger implementation which may be changed via the + * diag.setLogger(logger: DiagLogger) function. + */ +export const diag = DiagAPI.instance(); diff --git a/api/src/diag/index.ts b/api/src/diag/index.ts deleted file mode 100644 index 751b5eeda2..0000000000 --- a/api/src/diag/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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. - */ - -export * from './consoleLogger'; -export * from './types'; diff --git a/api/src/index.ts b/api/src/index.ts index 72825b0806..63325fa97e 100644 --- a/api/src/index.ts +++ b/api/src/index.ts @@ -14,75 +14,132 @@ * limitations under the License. */ -export * from './baggage/types'; +export { + BaggageEntry, + BaggageEntryMetadata, + Baggage, +} from './baggage/types'; export { baggageEntryMetadataFromString } from './baggage/utils'; -export * from './common/Exception'; -export * from './common/Time'; -export * from './common/Attributes'; -export * from './diag'; -export * from './propagation/TextMapPropagator'; -export * from './trace/attributes'; -export * from './trace/link'; -export * from './trace/ProxyTracer'; -export * from './trace/ProxyTracerProvider'; -export * from './trace/Sampler'; -export * from './trace/SamplingResult'; -export * from './trace/span_context'; -export * from './trace/span_kind'; -export * from './trace/span'; -export * from './trace/SpanOptions'; -export * from './trace/status'; -export * from './trace/trace_flags'; -export * from './trace/trace_state'; -export { createTraceState } from './trace/internal/utils'; -export * from './trace/tracer_provider'; -export * from './trace/tracer'; -export * from './trace/tracer_options'; +export { Exception } from './common/Exception'; +export { HrTime, TimeInput } from './common/Time'; +export { Attributes, AttributeValue } from './common/Attributes'; + +// Context APIs +export { + createContextKey, + ROOT_CONTEXT, +} from './context/context'; +export { + Context, + ContextManager, +} from './context/types'; +export type { ContextAPI } from './api/context'; + +// Diag APIs +export { DiagConsoleLogger } from './diag/consoleLogger'; +export { + DiagLogFunction, + DiagLogger, + DiagLogLevel, + ComponentLoggerOptions, +} from './diag/types'; +export type { DiagAPI } from './api/diag'; + +// Metrics APIs +export { + createNoopMeter, +} from './metrics/NoopMeter'; +export { + MeterOptions, + Meter, +} from './metrics/Meter'; +export { + MeterProvider, +} from './metrics/MeterProvider'; +export { + ValueType, + Counter, + Histogram, + MetricOptions, + Observable, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + UpDownCounter, + BatchObservableCallback, + MetricAttributes, + MetricAttributeValue, + ObservableCallback, +} from './metrics/Metric'; +export { + BatchObservableResult, + ObservableResult, +} from './metrics/ObservableResult'; +// Propagation APIs +export { + TextMapPropagator, + TextMapSetter, + TextMapGetter, + defaultTextMapGetter, + defaultTextMapSetter, +} from './propagation/TextMapPropagator'; +export type { PropagationAPI } from './api/propagation'; + +// Trace APIs +export { + SpanAttributes, + SpanAttributeValue, +} from './trace/attributes'; +export { Link } from './trace/link'; +export { ProxyTracer, TracerDelegator } from './trace/ProxyTracer'; +export { ProxyTracerProvider } from './trace/ProxyTracerProvider'; +export { Sampler } from './trace/Sampler'; +export { SamplingDecision, SamplingResult } from './trace/SamplingResult'; +export { SpanContext } from './trace/span_context'; +export { SpanKind } from './trace/span_kind'; +export { Span } from './trace/span'; +export { SpanOptions } from './trace/SpanOptions'; +export { SpanStatus, SpanStatusCode } from './trace/status'; +export { TraceFlags } from './trace/trace_flags'; +export { TraceState } from './trace/trace_state'; +export { createTraceState } from './trace/internal/utils'; +export { TracerProvider } from './trace/tracer_provider'; +export { Tracer } from './trace/tracer'; +export { TracerOptions } from './trace/tracer_options'; export { isSpanContextValid, isValidTraceId, isValidSpanId, } from './trace/spancontext-utils'; - export { INVALID_SPANID, INVALID_TRACEID, INVALID_SPAN_CONTEXT, } from './trace/invalid-span-constants'; - -export * from './context/context'; -export * from './context/types'; - -import { ContextAPI } from './api/context'; -export type { ContextAPI } from './api/context'; -/** Entrypoint for context API */ -export const context = ContextAPI.getInstance(); - -import { TraceAPI } from './api/trace'; export type { TraceAPI } from './api/trace'; -/** Entrypoint for trace API */ -export const trace = TraceAPI.getInstance(); -import { PropagationAPI } from './api/propagation'; -export type { PropagationAPI } from './api/propagation'; -/** Entrypoint for propagation API */ -export const propagation = PropagationAPI.getInstance(); - -import { DiagAPI } from './api/diag'; -export type { DiagAPI } from './api/diag'; - -/** - * Entrypoint for Diag API. - * Defines Diagnostic handler used for internal diagnostic logging operations. - * The default provides a Noop DiagLogger implementation which may be changed via the - * diag.setLogger(logger: DiagLogger) function. - */ -export const diag = DiagAPI.instance(); +// Split module-level variable definition into separate files to allow +// tree-shaking on each api instance. +import { context } from './context-api'; +import { diag } from './diag-api'; +import { metrics } from './metrics-api'; +import { propagation } from './propagation-api'; +import { trace } from './trace-api'; -export default { - trace, +// Named export. +export { context, + diag, + metrics, propagation, + trace, +}; +// Default export. +export default { + context, diag, + metrics, + propagation, + trace, }; diff --git a/api/src/internal/global-utils.ts b/api/src/internal/global-utils.ts index 5306aa503b..0753bc2775 100644 --- a/api/src/internal/global-utils.ts +++ b/api/src/internal/global-utils.ts @@ -14,8 +14,9 @@ * limitations under the License. */ +import { MeterProvider } from '../metrics/MeterProvider'; import { ContextManager } from '../context/types'; -import { DiagLogger } from '../diag'; +import { DiagLogger } from '../diag/types'; import { _globalThis } from '../platform'; import { TextMapPropagator } from '../propagation/TextMapPropagator'; import type { TracerProvider } from '../trace/tracer_provider'; @@ -98,5 +99,6 @@ type OTelGlobalAPI = { diag?: DiagLogger; trace?: TracerProvider; context?: ContextManager; + metrics?: MeterProvider; propagation?: TextMapPropagator; }; diff --git a/api-metrics/src/platform/browser/index.ts b/api/src/metrics-api.ts similarity index 72% rename from api-metrics/src/platform/browser/index.ts rename to api/src/metrics-api.ts index e9d6ebed71..16f399a22e 100644 --- a/api-metrics/src/platform/browser/index.ts +++ b/api/src/metrics-api.ts @@ -14,4 +14,8 @@ * limitations under the License. */ -export * from './globalThis'; +// Split module-level variable definition into separate files to allow +// tree-shaking on each api instance. +import { MetricsAPI } from './api/metrics'; +/** Entrypoint for metrics API */ +export const metrics = MetricsAPI.getInstance(); diff --git a/api-metrics/src/types/Meter.ts b/api/src/metrics/Meter.ts similarity index 100% rename from api-metrics/src/types/Meter.ts rename to api/src/metrics/Meter.ts diff --git a/api-metrics/src/types/MeterProvider.ts b/api/src/metrics/MeterProvider.ts similarity index 100% rename from api-metrics/src/types/MeterProvider.ts rename to api/src/metrics/MeterProvider.ts diff --git a/api-metrics/src/types/Metric.ts b/api/src/metrics/Metric.ts similarity index 95% rename from api-metrics/src/types/Metric.ts rename to api/src/metrics/Metric.ts index 6ca013766f..b20cfa4662 100644 --- a/api-metrics/src/types/Metric.ts +++ b/api/src/metrics/Metric.ts @@ -14,7 +14,8 @@ * limitations under the License. */ -import { Context, SpanAttributes, SpanAttributeValue } from '@opentelemetry/api'; +import { Attributes, AttributeValue } from '../common/Attributes'; +import { Context } from '../context/types'; import { BatchObservableResult, ObservableResult } from './ObservableResult'; /** @@ -88,7 +89,7 @@ export interface Histogram { }); }); }); + + describe('Global metrics', () => { + it('should expose a meter provider via getMeterProvider', () => { + const meter = metrics.getMeterProvider(); + assert.ok(meter); + assert.strictEqual(typeof meter, 'object'); + }); + + describe('GlobalMeterProvider', () => { + const dummyMeter = new NoopMeter(); + + beforeEach(() => { + metrics.disable(); + }); + + it('should use the global meter provider', () => { + metrics.setGlobalMeterProvider(new TestMeterProvider()); + const meter = metrics.getMeterProvider().getMeter('name'); + assert.deepStrictEqual(meter, dummyMeter); + }); + + class TestMeterProvider extends NoopMeterProvider { + override getMeter() { + return dummyMeter; + } + } + }); + }); }); diff --git a/api/test/baggage/Baggage.test.ts b/api/test/common/baggage/Baggage.test.ts similarity index 99% rename from api/test/baggage/Baggage.test.ts rename to api/test/common/baggage/Baggage.test.ts index 080b6a4193..81895306c0 100644 --- a/api/test/baggage/Baggage.test.ts +++ b/api/test/common/baggage/Baggage.test.ts @@ -19,7 +19,7 @@ import { ROOT_CONTEXT, propagation, baggageEntryMetadataFromString, -} from '../../src'; +} from '../../../src'; describe('Baggage', () => { describe('create', () => { diff --git a/api/test/context/NoopContextManager.test.ts b/api/test/common/context/NoopContextManager.test.ts similarity index 95% rename from api/test/context/NoopContextManager.test.ts rename to api/test/common/context/NoopContextManager.test.ts index 8a8a732bf7..8d257971b0 100644 --- a/api/test/context/NoopContextManager.test.ts +++ b/api/test/common/context/NoopContextManager.test.ts @@ -15,8 +15,8 @@ */ import * as assert from 'assert'; -import { createContextKey, ROOT_CONTEXT } from '../../src/context/context'; -import { NoopContextManager } from '../../src/context/NoopContextManager'; +import { createContextKey, ROOT_CONTEXT } from '../../../src/context/context'; +import { NoopContextManager } from '../../../src/context/NoopContextManager'; describe('NoopContextManager', () => { let contextManager: NoopContextManager; diff --git a/api/test/diag/ComponentLogger.test.ts b/api/test/common/diag/ComponentLogger.test.ts similarity index 96% rename from api/test/diag/ComponentLogger.test.ts rename to api/test/common/diag/ComponentLogger.test.ts index b9648c218a..2a01cf2e98 100644 --- a/api/test/diag/ComponentLogger.test.ts +++ b/api/test/common/diag/ComponentLogger.test.ts @@ -16,7 +16,7 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; -import { diag, DiagLogger, DiagLogLevel } from '../../src'; +import { diag, DiagLogger, DiagLogLevel } from '../../../src'; class SpyLogger implements DiagLogger { debug() {} diff --git a/api/test/diag/consoleLogger.test.ts b/api/test/common/diag/consoleLogger.test.ts similarity index 99% rename from api/test/diag/consoleLogger.test.ts rename to api/test/common/diag/consoleLogger.test.ts index fd57f11836..781acd93b0 100644 --- a/api/test/diag/consoleLogger.test.ts +++ b/api/test/common/diag/consoleLogger.test.ts @@ -17,7 +17,7 @@ /* eslint-disable no-console */ import * as assert from 'assert'; -import { DiagConsoleLogger } from '../../src/diag/consoleLogger'; +import { DiagConsoleLogger } from '../../../src/diag/consoleLogger'; export const diagLoggerFunctions = [ 'verbose', diff --git a/api/test/diag/logLevel.test.ts b/api/test/common/diag/logLevel.test.ts similarity index 96% rename from api/test/diag/logLevel.test.ts rename to api/test/common/diag/logLevel.test.ts index 1825db31a9..065e46d683 100644 --- a/api/test/diag/logLevel.test.ts +++ b/api/test/common/diag/logLevel.test.ts @@ -15,10 +15,10 @@ */ import * as assert from 'assert'; -import { diag } from '../../src'; -import { createLogLevelDiagLogger } from '../../src/diag/internal/logLevelLogger'; -import { createNoopDiagLogger } from '../../src/diag/internal/noopLogger'; -import { DiagLogger, DiagLogLevel } from '../../src/diag/types'; +import { diag } from '../../../src'; +import { createLogLevelDiagLogger } from '../../../src/diag/internal/logLevelLogger'; +import { createNoopDiagLogger } from '../../../src/diag/internal/noopLogger'; +import { DiagLogger, DiagLogLevel } from '../../../src/diag/types'; // Matches the previous Logger definition const incompleteLoggerFuncs = ['debug', 'info', 'warn', 'error'] as const; diff --git a/api/test/diag/logger.test.ts b/api/test/common/diag/logger.test.ts similarity index 94% rename from api/test/diag/logger.test.ts rename to api/test/common/diag/logger.test.ts index c0efdcb6f2..1b6f0d57ba 100644 --- a/api/test/diag/logger.test.ts +++ b/api/test/common/diag/logger.test.ts @@ -16,9 +16,9 @@ import * as assert from 'assert'; import sinon = require('sinon'); -import { diag, DiagLogLevel } from '../../src'; -import { createNoopDiagLogger } from '../../src/diag/internal/noopLogger'; -import { DiagLogger } from '../../src/diag/types'; +import { diag, DiagLogLevel } from '../../../src'; +import { createNoopDiagLogger } from '../../../src/diag/internal/noopLogger'; +import { DiagLogger } from '../../../src/diag/types'; export const diagLoggerFunctions = [ 'verbose', diff --git a/api/test/internal/global.test.ts b/api/test/common/internal/global.test.ts similarity index 93% rename from api/test/internal/global.test.ts rename to api/test/common/internal/global.test.ts index ba6218c7ed..291f707233 100644 --- a/api/test/internal/global.test.ts +++ b/api/test/common/internal/global.test.ts @@ -15,19 +15,19 @@ */ import * as assert from 'assert'; -import { getGlobal } from '../../src/internal/global-utils'; -import { _globalThis } from '../../src/platform'; -import { NoopContextManager } from '../../src/context/NoopContextManager'; -import { DiagLogLevel } from '../../src/diag/types'; +import { getGlobal } from '../../../src/internal/global-utils'; +import { _globalThis } from '../../../src/platform'; +import { NoopContextManager } from '../../../src/context/NoopContextManager'; +import { DiagLogLevel } from '../../../src/diag/types'; import sinon = require('sinon'); -const api1 = require('../../src') as typeof import('../../src'); +const api1 = require('../../../src') as typeof import('../../../src'); // clear cache and load a second instance of the api for (const key of Object.keys(require.cache)) { delete require.cache[key]; } -const api2 = require('../../src') as typeof import('../../src'); +const api2 = require('../../../src') as typeof import('../../../src'); // This will need to be changed manually on major version changes. // It is intentionally not autogenerated to ensure the author of the change is aware of what they are doing. diff --git a/api/test/internal/semver.test.ts b/api/test/common/internal/semver.test.ts similarity index 97% rename from api/test/internal/semver.test.ts rename to api/test/common/internal/semver.test.ts index e9ac3ec727..acd164b542 100644 --- a/api/test/internal/semver.test.ts +++ b/api/test/common/internal/semver.test.ts @@ -18,8 +18,8 @@ import * as assert from 'assert'; import { isCompatible, _makeCompatibilityCheck, -} from '../../src/internal/semver'; -import { VERSION } from '../../src/version'; +} from '../../../src/internal/semver'; +import { VERSION } from '../../../src/version'; describe('semver', () => { it('should be compatible if versions are equal', () => { diff --git a/api-metrics/test/internal/version.test.ts b/api/test/common/internal/version.test.ts similarity index 90% rename from api-metrics/test/internal/version.test.ts rename to api/test/common/internal/version.test.ts index 4d0e5f2542..cfffeb20fa 100644 --- a/api-metrics/test/internal/version.test.ts +++ b/api/test/common/internal/version.test.ts @@ -15,11 +15,11 @@ */ import * as assert from 'assert'; -import { VERSION } from '../../src/version'; +import { VERSION } from '../../../src/version'; describe('version', () => { it('should have generated VERSION.ts', () => { - const pjson = require('../../package.json'); + const pjson = require('../../../package.json'); assert.strictEqual(pjson.version, VERSION); }); diff --git a/api/test/common/metrics/Metric.test.ts b/api/test/common/metrics/Metric.test.ts new file mode 100644 index 0000000000..d7111d01f7 --- /dev/null +++ b/api/test/common/metrics/Metric.test.ts @@ -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 { Counter, UpDownCounter, Histogram } from '../../../src'; + +describe('Metric', () => { + describe('Counter', () =>{ + it('enable not to define any type', () => { + const counter: Counter = { + add(_value: number, _attribute: unknown) {} + }; + counter.add(1, { 'some-attribute': 'value' }); + }); + + it('enable to use with type', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: Counter = { + add(_value: number, _attribute: Attributes) {} + }; + counter.add(1, { 'some-attribute': 'value' }); + }); + + it('disable wrong attributes by typing', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: Counter = { + add(_value: number, _attribute: Attributes) {} + }; + // @ts-expect-error Expacting the type of Attributes + counter.add(1, { 'another-attribute': 'value' }); + }); + }); + + describe('UpDownCounter', () =>{ + it('enable not to define any type', () => { + const counter: UpDownCounter = { + add(_value: number, _attribute: unknown) {} + }; + counter.add(1, { 'some-attribute': 'value' }); + }); + + it('enable to use with type', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: UpDownCounter = { + add(_value: number, _attribute: Attributes) {} + }; + counter.add(1, { 'some-attribute': 'value' }); + }); + + it('disable wrong attributes by typing', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: UpDownCounter = { + add(_value: number, _attribute: Attributes) {} + }; + // @ts-expect-error Expacting the type of Attributes + counter.add(1, { 'another-attribute': 'value' }); + }); + }); + + describe('Histogram', () =>{ + it('enable not to define any type', () => { + const counter: Histogram = { + record(_value: number, _attribute: unknown) {} + }; + counter.record(1, { 'some-attribute': 'value' }); + }); + + it('enable to use with type', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: Histogram = { + record(_value: number, _attribute: Attributes) {} + }; + counter.record(1, { 'some-attribute': 'value' }); + }); + + it('disable wrong attributes by typing', () => { + type Attributes = { + 'some-attribute': string + }; + const counter: Histogram = { + record(_value: number, _attribute: Attributes) {} + }; + // @ts-expect-error Expacting the type of Attributes + counter.record(1, { 'another-attribute': 'value' }); + }); + }); +}); diff --git a/api-metrics/test/noop-implementations/noop-meter.test.ts b/api/test/common/noop-implementations/noop-meter.test.ts similarity index 97% rename from api-metrics/test/noop-implementations/noop-meter.test.ts rename to api/test/common/noop-implementations/noop-meter.test.ts index 07395a925b..951bdb80e7 100644 --- a/api-metrics/test/noop-implementations/noop-meter.test.ts +++ b/api/test/common/noop-implementations/noop-meter.test.ts @@ -24,8 +24,8 @@ import { NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC, NOOP_UP_DOWN_COUNTER_METRIC, createNoopMeter, -} from '../../src/NoopMeter'; -import { NoopMeterProvider } from '../../src/NoopMeterProvider'; +} from '../../../src/metrics/NoopMeter'; +import { NoopMeterProvider } from '../../../src/metrics/NoopMeterProvider'; const attributes = {}; const options = { diff --git a/api/test/noop-implementations/noop-span.test.ts b/api/test/common/noop-implementations/noop-span.test.ts similarity index 94% rename from api/test/noop-implementations/noop-span.test.ts rename to api/test/common/noop-implementations/noop-span.test.ts index de0007aeeb..5bc341f31a 100644 --- a/api/test/noop-implementations/noop-span.test.ts +++ b/api/test/common/noop-implementations/noop-span.test.ts @@ -20,8 +20,8 @@ import { INVALID_SPANID, INVALID_TRACEID, TraceFlags, -} from '../../src'; -import { NonRecordingSpan } from '../../src/trace/NonRecordingSpan'; +} from '../../../src'; +import { NonRecordingSpan } from '../../../src/trace/NonRecordingSpan'; describe('NonRecordingSpan', () => { it('do not crash', () => { diff --git a/api/test/noop-implementations/noop-tracer-provider.test.ts b/api/test/common/noop-implementations/noop-tracer-provider.test.ts similarity index 88% rename from api/test/noop-implementations/noop-tracer-provider.test.ts rename to api/test/common/noop-implementations/noop-tracer-provider.test.ts index 5b7e5ff7b1..d9eda44ee9 100644 --- a/api/test/noop-implementations/noop-tracer-provider.test.ts +++ b/api/test/common/noop-implementations/noop-tracer-provider.test.ts @@ -15,8 +15,8 @@ */ import * as assert from 'assert'; -import { NoopTracer } from '../../src/trace/NoopTracer'; -import { NoopTracerProvider } from '../../src/trace/NoopTracerProvider'; +import { NoopTracer } from '../../../src/trace/NoopTracer'; +import { NoopTracerProvider } from '../../../src/trace/NoopTracerProvider'; describe('NoopTracerProvider', () => { it('should not crash', () => { diff --git a/api/test/noop-implementations/noop-tracer.test.ts b/api/test/common/noop-implementations/noop-tracer.test.ts similarity index 93% rename from api/test/noop-implementations/noop-tracer.test.ts rename to api/test/common/noop-implementations/noop-tracer.test.ts index 037017208e..429f6d481d 100644 --- a/api/test/noop-implementations/noop-tracer.test.ts +++ b/api/test/common/noop-implementations/noop-tracer.test.ts @@ -22,9 +22,9 @@ import { SpanKind, trace, TraceFlags, -} from '../../src'; -import { NonRecordingSpan } from '../../src/trace/NonRecordingSpan'; -import { NoopTracer } from '../../src/trace/NoopTracer'; +} from '../../../src'; +import { NonRecordingSpan } from '../../../src/trace/NonRecordingSpan'; +import { NoopTracer } from '../../../src/trace/NoopTracer'; describe('NoopTracer', () => { it('should not crash', () => { diff --git a/api/test/proxy-implementations/proxy-tracer.test.ts b/api/test/common/proxy-implementations/proxy-tracer.test.ts similarity index 97% rename from api/test/proxy-implementations/proxy-tracer.test.ts rename to api/test/common/proxy-implementations/proxy-tracer.test.ts index bb9c55bfe1..9bf7e94409 100644 --- a/api/test/proxy-implementations/proxy-tracer.test.ts +++ b/api/test/common/proxy-implementations/proxy-tracer.test.ts @@ -26,9 +26,9 @@ import { SpanOptions, Tracer, TracerProvider, -} from '../../src'; -import { NonRecordingSpan } from '../../src/trace/NonRecordingSpan'; -import { NoopTracer } from '../../src/trace/NoopTracer'; +} from '../../../src'; +import { NonRecordingSpan } from '../../../src/trace/NonRecordingSpan'; +import { NoopTracer } from '../../../src/trace/NoopTracer'; describe('ProxyTracer', () => { let provider: ProxyTracerProvider; diff --git a/api/test/trace/spancontext-utils.test.ts b/api/test/common/trace/spancontext-utils.test.ts similarity index 96% rename from api/test/trace/spancontext-utils.test.ts rename to api/test/common/trace/spancontext-utils.test.ts index 09f5712b27..e2d87f807d 100644 --- a/api/test/trace/spancontext-utils.test.ts +++ b/api/test/common/trace/spancontext-utils.test.ts @@ -15,8 +15,8 @@ */ import * as assert from 'assert'; -import * as context from '../../src/trace/spancontext-utils'; -import { INVALID_SPANID, INVALID_TRACEID, TraceFlags } from '../../src'; +import * as context from '../../../src/trace/spancontext-utils'; +import { INVALID_SPANID, INVALID_TRACEID, TraceFlags } from '../../../src'; describe('spancontext-utils', () => { it('should return true for valid spancontext', () => { diff --git a/api/test/trace/tracestate-validators.test.ts b/api/test/common/trace/tracestate-validators.test.ts similarity index 96% rename from api/test/trace/tracestate-validators.test.ts rename to api/test/common/trace/tracestate-validators.test.ts index 0f355f1c12..15f49434eb 100644 --- a/api/test/trace/tracestate-validators.test.ts +++ b/api/test/common/trace/tracestate-validators.test.ts @@ -15,7 +15,7 @@ */ import * as assert from 'assert'; -import { validateKey, validateValue } from '../../src/trace/internal/tracestate-validators'; +import { validateKey, validateValue } from '../../../src/trace/internal/tracestate-validators'; describe('validators', () => { describe('validateKey', () => { diff --git a/api/test/trace/tracestate.test.ts b/api/test/common/trace/tracestate.test.ts similarity index 97% rename from api/test/trace/tracestate.test.ts rename to api/test/common/trace/tracestate.test.ts index 699c6cd9cb..6d20195b43 100644 --- a/api/test/trace/tracestate.test.ts +++ b/api/test/common/trace/tracestate.test.ts @@ -15,8 +15,8 @@ */ import * as assert from 'assert'; -import { createTraceState } from '../../src/trace/internal/utils'; -import { TraceStateImpl } from '../../src/trace/internal/tracestate-impl'; +import { createTraceState } from '../../../src/trace/internal/utils'; +import { TraceStateImpl } from '../../../src/trace/internal/tracestate-impl'; describe('TraceState', () => { describe('.serialize()', () => { diff --git a/api/test/index-webpack.ts b/api/test/index-webpack.ts index 856be100b2..2d2ef32478 100644 --- a/api/test/index-webpack.ts +++ b/api/test/index-webpack.ts @@ -14,11 +14,6 @@ * limitations under the License. */ { - const testsContext = require.context('.', true, /test$/); + const testsContext = require.context('./common', true); testsContext.keys().forEach(testsContext); } - -{ - const srcContext = require.context('.', true, /src$/); - srcContext.keys().forEach(srcContext); -} diff --git a/api/test/index-webpack.worker.ts b/api/test/index-webpack.worker.ts index d568d570b1..2d2ef32478 100644 --- a/api/test/index-webpack.worker.ts +++ b/api/test/index-webpack.worker.ts @@ -14,6 +14,6 @@ * limitations under the License. */ { - const testsContext = require.context('./', true, /test$/); + const testsContext = require.context('./common', true); testsContext.keys().forEach(testsContext); } diff --git a/api/test/internal/version.test.ts b/api/test/internal/version.test.ts deleted file mode 100644 index 4d0e5f2542..0000000000 --- a/api/test/internal/version.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 { VERSION } from '../../src/version'; - -describe('version', () => { - it('should have generated VERSION.ts', () => { - const pjson = require('../../package.json'); - assert.strictEqual(pjson.version, VERSION); - }); - - it('prerelease tag versions are banned', () => { - // see https://github.com/open-telemetry/opentelemetry-js-api/issues/74 - assert.ok(VERSION.match(/^\d+\.\d+\.\d+$/)); - }); -}); diff --git a/api/test/tree-shaking/tree-shaking.test.ts b/api/test/tree-shaking/tree-shaking.test.ts new file mode 100644 index 0000000000..37ab5def3a --- /dev/null +++ b/api/test/tree-shaking/tree-shaking.test.ts @@ -0,0 +1,119 @@ +/* + * 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 * as webpack from 'webpack'; +import * as path from 'path'; +import { Union } from 'unionfs'; +import { fs as mfs } from 'memfs'; +import * as realFs from 'fs'; + +/** + * Verify that tree-shaking can be properly applied on the @opentelemetry/api package. + * Unused optional apis should be able to be removed from the final bundle. + */ +describe('tree-shaking', () => { + const allowedAPIs = ['ContextAPI', 'DiagAPI']; + const testAPIs = [ + { + name: 'MetricsAPI', + export: 'metrics', + }, + { + name: 'PropagationAPI', + export: 'propagation', + }, + { + name: 'TraceAPI', + export: 'trace' + }, + ]; + const APIMatcher = /(?:class|function) (\w+API)/g; + + const sourceCodePath = path.join(__dirname, 'test.js'); + const outputPath = path.join(__dirname, 'output'); + const outputFilename = path.join(outputPath, 'bundle.js'); + + afterEach(() => { + try { + mfs.unlinkSync(outputFilename); + } catch { + /** ignore */ + } + }); + + for (const testAPI of testAPIs) { + it(`verify ${testAPI.name}`, async () => { + const sourceCode = ` + import { ${testAPI.export} } from '../../'; + console.log(${testAPI.export}); + `; + mfs.mkdirpSync(path.dirname(sourceCodePath)); + mfs.writeFileSync(sourceCodePath, sourceCode, { encoding: 'utf8' }); + + const compiler = webpack({ + entry: sourceCodePath, + output: { + filename: 'bundle.js', + path: outputPath, + }, + mode: 'production', + optimization: { + // disable minimization so that we can inspect the output easily. + minimize: false, + } + }); + + const fs = new Union(); + fs.use(mfs as any) + .use(realFs); + + //direct webpack to use unionfs for file input + compiler.inputFileSystem = fs; + //direct webpack to output to memoryfs rather than to disk + compiler.outputFileSystem = { + ...mfs, + join: path.join, + } as any; + + const stats = await new Promise((resolve, reject) => { + compiler.run((err, stats) => { + if (err) { + return reject(err); + } + resolve(stats); + }); + }); + assert.deepStrictEqual(stats.compilation.errors, []); + assert.deepStrictEqual(stats.compilation.warnings, []); + + const outputFile = mfs.readFileSync(outputFilename, 'utf8') as string; + const matches = new Set(); + let match; + do { + match = APIMatcher.exec(outputFile); + if (match) { + matches.add(match[1]); + } + } while (match); + + // Remove allowed apis from checking list. + allowedAPIs.forEach(it => matches.delete(it)); + + assert.deepStrictEqual(Array.from(matches), [testAPI.name]); + }); + } +}); diff --git a/examples/opentelemetry-web/examples/metrics/index.js b/examples/opentelemetry-web/examples/metrics/index.js index e036f1e8d2..c3f86cfbe5 100644 --- a/examples/opentelemetry-web/examples/metrics/index.js +++ b/examples/opentelemetry-web/examples/metrics/index.js @@ -1,5 +1,4 @@ -const { DiagConsoleLogger, DiagLogLevel, diag } = require('@opentelemetry/api'); -const { metrics } = require('@opentelemetry/api-metrics'); +const { DiagConsoleLogger, DiagLogLevel, diag, metrics } = require('@opentelemetry/api'); const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http'); const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); diff --git a/examples/opentelemetry-web/package.json b/examples/opentelemetry-web/package.json index f99b49e3f7..966968275d 100644 --- a/examples/opentelemetry-web/package.json +++ b/examples/opentelemetry-web/package.json @@ -42,8 +42,7 @@ "webpack-merge": "^5.8.0" }, "dependencies": { - "@opentelemetry/api": "^1.0.2", - "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/api": "^1.2.0", "@opentelemetry/context-zone": "1.7.0", "@opentelemetry/core": "1.7.0", "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", diff --git a/examples/otlp-exporter-node/package.json b/examples/otlp-exporter-node/package.json index 085d15917d..d122327991 100644 --- a/examples/otlp-exporter-node/package.json +++ b/examples/otlp-exporter-node/package.json @@ -28,8 +28,7 @@ "url": "https://github.com/open-telemetry/opentelemetry-js/issues" }, "dependencies": { - "@opentelemetry/api": "^1.1.0", - "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/api": "^1.2.0", "@opentelemetry/core": "1.7.0", "@opentelemetry/exporter-metrics-otlp-grpc": "0.33.0", "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", diff --git a/experimental/examples/prometheus/package.json b/experimental/examples/prometheus/package.json index 837fcf9b61..96a9f5572d 100644 --- a/experimental/examples/prometheus/package.json +++ b/experimental/examples/prometheus/package.json @@ -9,7 +9,7 @@ "author": "OpenTelemetry Authors", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/api": "^1.0.2", + "@opentelemetry/api": "^1.2.0", "@opentelemetry/exporter-prometheus": "0.33.0", "@opentelemetry/sdk-metrics": "0.33.0" } diff --git a/experimental/packages/api-logs/README.md b/experimental/packages/api-logs/README.md index b0704800de..57d40a3211 100644 --- a/experimental/packages/api-logs/README.md +++ b/experimental/packages/api-logs/README.md @@ -58,6 +58,6 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions [license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE [license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat -[npm-url]: https://www.npmjs.com/package/@opentelemetry/api-metrics -[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi-metrics.svg +[npm-url]: https://www.npmjs.com/package/@opentelemetry/api-logs +[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi-logs.svg [logs-api-docs]: https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api_logs.html diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json index d7dc5a21a8..e44641b004 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json @@ -49,8 +49,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@grpc/proto-loader": "^0.7.3", - "@opentelemetry/api": "^1.0.0", - "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/api": "^1.2.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -65,7 +64,7 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.2.0" }, "dependencies": { "@grpc/grpc-js": "^1.7.1", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts index 58922addc3..e7f2baa351 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Counter, Histogram, ObservableGauge, ObservableResult, ValueType } from '@opentelemetry/api-metrics'; +import { Counter, Histogram, ObservableGauge, ObservableResult, ValueType } from '@opentelemetry/api'; import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; import * as grpc from '@grpc/grpc-js'; diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json index c2a6041ceb..d866e532c2 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json @@ -12,9 +12,6 @@ { "path": "../../../api" }, - { - "path": "../../../api-metrics" - }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json index 0740d5913e..4b21d78f8f 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json @@ -64,7 +64,7 @@ }, "devDependencies": { "@babel/core": "7.16.0", - "@opentelemetry/api": "^1.0.0", + "@opentelemetry/api": "^1.2.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -91,10 +91,9 @@ "webpack-merge": "5.8.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.2.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.33.0", "@opentelemetry/core": "1.7.0", "@opentelemetry/otlp-exporter-base": "0.33.0", "@opentelemetry/otlp-transformer": "0.33.0", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts index 166dbc4a81..c0cb9dc2ab 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/browser/CollectorMetricExporter.test.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { diag, DiagLogger, DiagLogLevel } from '@opentelemetry/api'; -import { Counter, Histogram, } from '@opentelemetry/api-metrics'; +import { diag, DiagLogger, DiagLogLevel, Counter, Histogram } from '@opentelemetry/api'; import { ExportResultCode, hrTimeToNanoseconds } from '@opentelemetry/core'; import { AggregationTemporality, ResourceMetrics, } from '@opentelemetry/sdk-metrics'; import * as assert from 'assert'; diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts index 0b15459815..5989d870f6 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts @@ -22,7 +22,7 @@ import { ObservableCounter, ObservableGauge, ObservableUpDownCounter, -} from '@opentelemetry/api-metrics'; +} from '@opentelemetry/api'; import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; import { InstrumentationScope, VERSION } from '@opentelemetry/core'; diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json index 7a2d809dff..af647ba8e3 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json @@ -12,9 +12,6 @@ { "path": "../../../api" }, - { - "path": "../../../api-metrics" - }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json index bad7943e6e..bd21a3c040 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json @@ -48,8 +48,7 @@ }, "devDependencies": { "@babel/core": "7.16.0", - "@opentelemetry/api": "^1.0.0", - "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/api": "^1.2.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -64,7 +63,7 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.2.0" }, "dependencies": { "@opentelemetry/core": "1.7.0", diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts index 2f62a8ba2c..ce3a70ff24 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts @@ -20,7 +20,7 @@ import { Histogram, ValueType, ObservableGauge, -} from '@opentelemetry/api-metrics'; +} from '@opentelemetry/api'; import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; import { diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json index 133b1e8bb8..521fc31cfe 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json @@ -12,9 +12,6 @@ { "path": "../../../api" }, - { - "path": "../../../api-metrics" - }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-exporter-prometheus/package.json b/experimental/packages/opentelemetry-exporter-prometheus/package.json index bb841bacd4..9461ac2bca 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/package.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/package.json @@ -43,7 +43,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": "^1.0.0", + "@opentelemetry/api": "^1.2.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -56,10 +56,9 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.2.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.33.0", "@opentelemetry/core": "1.7.0", "@opentelemetry/sdk-metrics": "0.33.0", "@opentelemetry/resources": "1.7.0" diff --git a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts index 410cbfbf34..0879f16e87 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/src/PrometheusSerializer.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { diag } from '@opentelemetry/api'; +import { + diag, + MetricAttributes, + MetricAttributeValue, +} from '@opentelemetry/api'; import { ResourceMetrics, InstrumentType, @@ -24,10 +28,6 @@ import { DataPoint, Histogram, } from '@opentelemetry/sdk-metrics'; -import type { - MetricAttributes, - MetricAttributeValue -} from '@opentelemetry/api-metrics'; import { hrTimeToMilliseconds } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts index 6b60952670..3104348300 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts @@ -15,9 +15,10 @@ */ import { + Counter, Meter, ObservableResult -} from '@opentelemetry/api-metrics'; +} from '@opentelemetry/api'; import { MeterProvider } from '@opentelemetry/sdk-metrics'; import * as assert from 'assert'; import * as sinon from 'sinon'; @@ -28,7 +29,6 @@ import { mockHrTime } from './util'; import { SinonStubbedInstance } from 'sinon'; -import { Counter } from '@opentelemetry/api-metrics'; const serializedEmptyResourceLines = [ '# HELP target_info Target metadata', diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts index 852946f355..2694c96f83 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts @@ -18,7 +18,7 @@ import * as assert from 'assert'; import { MetricAttributes, UpDownCounter -} from '@opentelemetry/api-metrics'; +} from '@opentelemetry/api'; import { Aggregation, AggregationTemporality, diff --git a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json index 9ac6b6fd90..719097c712 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json @@ -12,9 +12,6 @@ { "path": "../../../api" }, - { - "path": "../../../api-metrics" - }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/package.json b/experimental/packages/opentelemetry-instrumentation-grpc/package.json index 8d9f69ef1c..09f8ab2aff 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/package.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/package.json @@ -47,7 +47,7 @@ "devDependencies": { "@grpc/grpc-js": "^1.7.1", "@grpc/proto-loader": "^0.7.3", - "@opentelemetry/api": "^1.0.0", + "@opentelemetry/api": "^1.2.0", "@opentelemetry/context-async-hooks": "1.7.0", "@opentelemetry/core": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0", @@ -68,10 +68,9 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.2.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.33.0", "@opentelemetry/instrumentation": "0.33.0", "@opentelemetry/semantic-conventions": "1.7.0" }, diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/src/instrumentation.ts b/experimental/packages/opentelemetry-instrumentation-grpc/src/instrumentation.ts index 5ac237038a..d6f782684b 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/src/instrumentation.ts +++ b/experimental/packages/opentelemetry-instrumentation-grpc/src/instrumentation.ts @@ -19,7 +19,6 @@ import { VERSION } from './version'; import { GrpcNativeInstrumentation } from './grpc'; import { GrpcJsInstrumentation } from './grpc-js'; import * as api from '@opentelemetry/api'; -import { MeterProvider } from '@opentelemetry/api-metrics'; /** The metadata key under which span context is stored as a binary value. */ export const GRPC_TRACE_KEY = 'grpc-trace-bin'; @@ -81,7 +80,7 @@ export class GrpcInstrumentation { * Sets MeterProvider to this plugin * @param meterProvider */ - public setMeterProvider(meterProvider: MeterProvider) { + public setMeterProvider(meterProvider: api.MeterProvider) { this._grpcJsInstrumentation.setMeterProvider(meterProvider); this._grpcNativeInstrumentation.setMeterProvider(meterProvider); } diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json index 25a8b5fb03..0170a84c3c 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json @@ -12,9 +12,6 @@ { "path": "../../../api" }, - { - "path": "../../../api-metrics" - }, { "path": "../../../packages/opentelemetry-context-async-hooks" }, diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index ef2a792705..67983b76d6 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -45,7 +45,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": "^1.0.0", + "@opentelemetry/api": "^1.2.0", "@opentelemetry/context-async-hooks": "1.7.0", "@opentelemetry/sdk-trace-base": "1.7.0", "@opentelemetry/sdk-trace-node": "1.7.0", @@ -69,10 +69,9 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.2.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.33.0", "@opentelemetry/core": "1.7.0", "@opentelemetry/instrumentation": "0.33.0", "@opentelemetry/sdk-metrics": "0.33.0", diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts index a0e07a1e9f..4129759589 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts @@ -25,8 +25,11 @@ import { SpanStatus, SpanStatusCode, trace, + Histogram, + MeterProvider, + MetricAttributes, + ValueType, } from '@opentelemetry/api'; -import { Histogram, MeterProvider, MetricAttributes, ValueType } from '@opentelemetry/api-metrics'; import { hrTime, hrTimeDuration, hrTimeToMilliseconds, suppressTracing } from '@opentelemetry/core'; import type * as http from 'http'; import type * as https from 'https'; diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts index e9e9b45468..4094586493 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts @@ -14,6 +14,7 @@ * limitations under the License. */ import { + MetricAttributes, SpanAttributes, SpanStatusCode, Span, @@ -35,7 +36,6 @@ import { getRPCMetadata, RPCType } from '@opentelemetry/core'; import * as url from 'url'; import { AttributeNames } from './enums/AttributeNames'; import { Err, IgnoreMatcher, ParsedRequestOptions } from './types'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; /** * Get an absolute url diff --git a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json index c6158c12c1..00267e9c1a 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json @@ -12,9 +12,6 @@ { "path": "../../../api" }, - { - "path": "../../../api-metrics" - }, { "path": "../../../packages/opentelemetry-context-async-hooks" }, diff --git a/experimental/packages/opentelemetry-instrumentation/package.json b/experimental/packages/opentelemetry-instrumentation/package.json index abc09deb23..96437b278b 100644 --- a/experimental/packages/opentelemetry-instrumentation/package.json +++ b/experimental/packages/opentelemetry-instrumentation/package.json @@ -68,17 +68,16 @@ "url": "https://github.com/open-telemetry/opentelemetry-js/issues" }, "dependencies": { - "@opentelemetry/api-metrics": "0.33.0", "require-in-the-middle": "^5.0.3", "semver": "^7.3.2", "shimmer": "^1.2.1" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": "^1.2.0" }, "devDependencies": { "@babel/core": "7.16.0", - "@opentelemetry/api": "^1.0.0", + "@opentelemetry/api": "^1.2.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/semver": "7.3.9", diff --git a/experimental/packages/opentelemetry-instrumentation/src/autoLoader.ts b/experimental/packages/opentelemetry-instrumentation/src/autoLoader.ts index 862ba111e0..c6a052c6c9 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/autoLoader.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/autoLoader.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { trace } from '@opentelemetry/api'; -import { metrics } from '@opentelemetry/api-metrics'; +import { trace, metrics } from '@opentelemetry/api'; import { disableInstrumentations, enableInstrumentations, diff --git a/experimental/packages/opentelemetry-instrumentation/src/autoLoaderUtils.ts b/experimental/packages/opentelemetry-instrumentation/src/autoLoaderUtils.ts index 962c6de128..a6d63de472 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/autoLoaderUtils.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/autoLoaderUtils.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { TracerProvider } from '@opentelemetry/api'; -import { MeterProvider } from '@opentelemetry/api-metrics'; +import { TracerProvider, MeterProvider } from '@opentelemetry/api'; import { Instrumentation } from './types'; import { AutoLoaderResult, InstrumentationOption } from './types_internal'; diff --git a/experimental/packages/opentelemetry-instrumentation/src/instrumentation.ts b/experimental/packages/opentelemetry-instrumentation/src/instrumentation.ts index fb9f53fc70..5024b5d536 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/instrumentation.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/instrumentation.ts @@ -17,11 +17,13 @@ import { diag, DiagLogger, + metrics, + Meter, + MeterProvider, trace, Tracer, TracerProvider, } from '@opentelemetry/api'; -import { Meter, MeterProvider, metrics } from '@opentelemetry/api-metrics'; import * as shimmer from 'shimmer'; import { InstrumentationModuleDefinition } from './platform/node'; import * as types from './types'; diff --git a/experimental/packages/opentelemetry-instrumentation/src/types.ts b/experimental/packages/opentelemetry-instrumentation/src/types.ts index 9edd6368ec..837f096792 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/types.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/types.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { TracerProvider } from '@opentelemetry/api'; -import { MeterProvider } from '@opentelemetry/api-metrics'; +import { TracerProvider, MeterProvider } from '@opentelemetry/api'; /** Interface Instrumentation to apply patch. */ export interface Instrumentation { diff --git a/experimental/packages/opentelemetry-instrumentation/src/types_internal.ts b/experimental/packages/opentelemetry-instrumentation/src/types_internal.ts index 6383b6cd17..016be0ad36 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/types_internal.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/types_internal.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { TracerProvider } from '@opentelemetry/api'; -import { MeterProvider } from '@opentelemetry/api-metrics'; +import { TracerProvider, MeterProvider } from '@opentelemetry/api'; import { InstrumentationBase } from './platform'; import { Instrumentation } from './types'; diff --git a/experimental/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts b/experimental/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts index c7bf2f6967..c7bebf204c 100644 --- a/experimental/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts +++ b/experimental/packages/opentelemetry-instrumentation/test/common/autoLoader.test.ts @@ -14,15 +14,16 @@ * limitations under the License. */ -import { Tracer, TracerProvider } from '@opentelemetry/api'; -import * as assert from 'assert'; -import * as sinon from 'sinon'; -import { InstrumentationBase, registerInstrumentations } from '../../src'; import { + Tracer, + TracerProvider, Meter, MeterOptions, MeterProvider, -} from '@opentelemetry/api-metrics'; +} from '@opentelemetry/api'; +import * as assert from 'assert'; +import * as sinon from 'sinon'; +import { InstrumentationBase, registerInstrumentations } from '../../src'; class DummyTracerProvider implements TracerProvider { getTracer(name: string, version?: string): Tracer { diff --git a/experimental/packages/opentelemetry-instrumentation/tsconfig.esnext.json b/experimental/packages/opentelemetry-instrumentation/tsconfig.esnext.json index dc405c942c..cb78dd6ff3 100644 --- a/experimental/packages/opentelemetry-instrumentation/tsconfig.esnext.json +++ b/experimental/packages/opentelemetry-instrumentation/tsconfig.esnext.json @@ -7,10 +7,5 @@ }, "include": [ "src/**/*.ts" - ], - "references": [ - { - "path": "../../../api-metrics/tsconfig.esnext.json" - } ] } diff --git a/experimental/packages/opentelemetry-instrumentation/tsconfig.json b/experimental/packages/opentelemetry-instrumentation/tsconfig.json index ce90824272..e22548584a 100644 --- a/experimental/packages/opentelemetry-instrumentation/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation/tsconfig.json @@ -11,9 +11,6 @@ "references": [ { "path": "../../../api" - }, - { - "path": "../../../api-metrics" } ] } diff --git a/experimental/packages/opentelemetry-sdk-metrics/README.md b/experimental/packages/opentelemetry-sdk-metrics/README.md index 044c385913..ab5f2dd0a0 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/README.md +++ b/experimental/packages/opentelemetry-sdk-metrics/README.md @@ -14,7 +14,7 @@ It does **not** provide automated instrumentation of known libraries or host env ## Installation ```bash -npm install --save @opentelemetry/api-metrics +npm install --save @opentelemetry/api npm install --save @opentelemetry/sdk-metrics ``` @@ -23,7 +23,7 @@ npm install --save @opentelemetry/sdk-metrics The basic setup of the SDK can be seen as followings: ```js -const opentelemetry = require('@opentelemetry/api-metrics'); +const opentelemetry = require('@opentelemetry/api'); const { MeterProvider } = require('@opentelemetry/sdk-metrics'); // To create an instrument, you first need to initialize the Meter provider. diff --git a/experimental/packages/opentelemetry-sdk-metrics/package.json b/experimental/packages/opentelemetry-sdk-metrics/package.json index f53dc3cacf..dcd526d57f 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/package.json +++ b/experimental/packages/opentelemetry-sdk-metrics/package.json @@ -54,7 +54,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": "^1.0.0", + "@opentelemetry/api": ">=1.2.0 <1.3.0", "@types/lodash.merge": "4.6.6", "@types/mocha": "10.0.0", "@types/node": "18.6.5", @@ -74,10 +74,9 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.0.0" + "@opentelemetry/api": ">=1.2.0 <1.3.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.33.0", "@opentelemetry/core": "1.7.0", "@opentelemetry/resources": "1.7.0", "lodash.merge": "4.6.2" diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/InstrumentDescriptor.ts b/experimental/packages/opentelemetry-sdk-metrics/src/InstrumentDescriptor.ts index e511cd8dd3..4008bc3de2 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/InstrumentDescriptor.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/InstrumentDescriptor.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { MetricOptions, ValueType } from '@opentelemetry/api-metrics'; +import { MetricOptions, ValueType } from '@opentelemetry/api'; import { View } from './view/View'; /** diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/Instruments.ts b/experimental/packages/opentelemetry-sdk-metrics/src/Instruments.ts index 5706059691..8b70c06f70 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/Instruments.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/Instruments.ts @@ -14,9 +14,21 @@ * limitations under the License. */ -import * as api from '@opentelemetry/api'; -import * as metrics from '@opentelemetry/api-metrics'; -import { ObservableCallback } from '@opentelemetry/api-metrics'; +import { + context as contextApi, + diag, + Context, + MetricAttributes, + ValueType, + UpDownCounter, + Counter, + Histogram, + Observable, + ObservableCallback, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, +} from '@opentelemetry/api'; import { hrTime } from '@opentelemetry/core'; import { InstrumentDescriptor } from './InstrumentDescriptor'; import { ObservableRegistry } from './state/ObservableRegistry'; @@ -25,9 +37,9 @@ import { AsyncWritableMetricStorage, WritableMetricStorage } from './state/Writa export class SyncInstrument { constructor(private _writableMetricStorage: WritableMetricStorage, protected _descriptor: InstrumentDescriptor) {} - protected _record(value: number, attributes: metrics.MetricAttributes = {}, context: api.Context = api.context.active()) { - if (this._descriptor.valueType === metrics.ValueType.INT && !Number.isInteger(value)) { - api.diag.warn( + protected _record(value: number, attributes: MetricAttributes = {}, context: Context = contextApi.active()) { + if (this._descriptor.valueType === ValueType.INT && !Number.isInteger(value)) { + diag.warn( `INT value type cannot accept a floating-point value for ${this._descriptor.name}, ignoring the fractional digits.` ); value = Math.trunc(value); @@ -37,27 +49,27 @@ export class SyncInstrument { } /** - * The class implements {@link metrics.UpDownCounter} interface. + * The class implements {@link UpDownCounter} interface. */ -export class UpDownCounterInstrument extends SyncInstrument implements metrics.UpDownCounter { +export class UpDownCounterInstrument extends SyncInstrument implements UpDownCounter { /** * Increment value of counter by the input. Inputs may be negative. */ - add(value: number, attributes?: metrics.MetricAttributes, ctx?: api.Context): void { + add(value: number, attributes?: MetricAttributes, ctx?: Context): void { this._record(value, attributes, ctx); } } /** - * The class implements {@link metrics.Counter} interface. + * The class implements {@link Counter} interface. */ -export class CounterInstrument extends SyncInstrument implements metrics.Counter { +export class CounterInstrument extends SyncInstrument implements Counter { /** * Increment value of counter by the input. Inputs may not be negative. */ - add(value: number, attributes?: metrics.MetricAttributes, ctx?: api.Context): void { + add(value: number, attributes?: MetricAttributes, ctx?: Context): void { if (value < 0) { - api.diag.warn(`negative value provided to counter ${this._descriptor.name}: ${value}`); + diag.warn(`negative value provided to counter ${this._descriptor.name}: ${value}`); return; } @@ -66,22 +78,22 @@ export class CounterInstrument extends SyncInstrument implements metrics.Counter } /** - * The class implements {@link metrics.Histogram} interface. + * The class implements {@link Histogram} interface. */ -export class HistogramInstrument extends SyncInstrument implements metrics.Histogram { +export class HistogramInstrument extends SyncInstrument implements Histogram { /** * Records a measurement. Value of the measurement must not be negative. */ - record(value: number, attributes?: metrics.MetricAttributes, ctx?: api.Context): void { + record(value: number, attributes?: MetricAttributes, ctx?: Context): void { if (value < 0) { - api.diag.warn(`negative value provided to histogram ${this._descriptor.name}: ${value}`); + diag.warn(`negative value provided to histogram ${this._descriptor.name}: ${value}`); return; } this._record(value, attributes, ctx); } } -export class ObservableInstrument implements metrics.Observable { +export class ObservableInstrument implements Observable { /** @internal */ _metricStorages: AsyncWritableMetricStorage[]; /** @internal */ @@ -93,23 +105,23 @@ export class ObservableInstrument implements metrics.Observable { } /** - * @see {metrics.Observable.addCallback} + * @see {Observable.addCallback} */ addCallback(callback: ObservableCallback) { this._observableRegistry.addCallback(callback, this); } /** - * @see {metrics.Observable.removeCallback} + * @see {Observable.removeCallback} */ removeCallback(callback: ObservableCallback) { this._observableRegistry.removeCallback(callback, this); } } -export class ObservableCounterInstrument extends ObservableInstrument implements metrics.ObservableCounter {} -export class ObservableGaugeInstrument extends ObservableInstrument implements metrics.ObservableGauge {} -export class ObservableUpDownCounterInstrument extends ObservableInstrument implements metrics.ObservableUpDownCounter {} +export class ObservableCounterInstrument extends ObservableInstrument implements ObservableCounter {} +export class ObservableGaugeInstrument extends ObservableInstrument implements ObservableGauge {} +export class ObservableUpDownCounterInstrument extends ObservableInstrument implements ObservableUpDownCounter {} export function isObservableInstrument(it: unknown): it is ObservableInstrument { return it instanceof ObservableInstrument; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/Meter.ts b/experimental/packages/opentelemetry-sdk-metrics/src/Meter.ts index d8a7f00a21..bd58dcbac1 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/Meter.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/Meter.ts @@ -14,7 +14,18 @@ * limitations under the License. */ -import * as metrics from '@opentelemetry/api-metrics'; +import { + Meter as IMeter, + MetricOptions, + Histogram, + Counter, + UpDownCounter, + ObservableGauge, + ObservableCounter, + ObservableUpDownCounter, + BatchObservableCallback, + Observable, +} from '@opentelemetry/api'; import { createInstrumentDescriptor, InstrumentType } from './InstrumentDescriptor'; import { CounterInstrument, @@ -27,85 +38,85 @@ import { import { MeterSharedState } from './state/MeterSharedState'; /** - * This class implements the {@link metrics.Meter} interface. + * This class implements the {@link IMeter} interface. */ -export class Meter implements metrics.Meter { +export class Meter implements IMeter { constructor(private _meterSharedState: MeterSharedState) {} /** - * Create a {@link metrics.Histogram} instrument. + * Create a {@link Histogram} instrument. */ - createHistogram(name: string, options?: metrics.MetricOptions): metrics.Histogram { + createHistogram(name: string, options?: MetricOptions): Histogram { const descriptor = createInstrumentDescriptor(name, InstrumentType.HISTOGRAM, options); const storage = this._meterSharedState.registerMetricStorage(descriptor); return new HistogramInstrument(storage, descriptor); } /** - * Create a {@link metrics.Counter} instrument. + * Create a {@link Counter} instrument. */ - createCounter(name: string, options?: metrics.MetricOptions): metrics.Counter { + createCounter(name: string, options?: MetricOptions): Counter { const descriptor = createInstrumentDescriptor(name, InstrumentType.COUNTER, options); const storage = this._meterSharedState.registerMetricStorage(descriptor); return new CounterInstrument(storage, descriptor); } /** - * Create a {@link metrics.UpDownCounter} instrument. + * Create a {@link UpDownCounter} instrument. */ - createUpDownCounter(name: string, options?: metrics.MetricOptions): metrics.UpDownCounter { + createUpDownCounter(name: string, options?: MetricOptions): UpDownCounter { const descriptor = createInstrumentDescriptor(name, InstrumentType.UP_DOWN_COUNTER, options); const storage = this._meterSharedState.registerMetricStorage(descriptor); return new UpDownCounterInstrument(storage, descriptor); } /** - * Create a {@link metrics.ObservableGauge} instrument. + * Create a {@link ObservableGauge} instrument. */ createObservableGauge( name: string, - options?: metrics.MetricOptions, - ): metrics.ObservableGauge { + options?: MetricOptions, + ): ObservableGauge { const descriptor = createInstrumentDescriptor(name, InstrumentType.OBSERVABLE_GAUGE, options); const storages = this._meterSharedState.registerAsyncMetricStorage(descriptor); return new ObservableGaugeInstrument(descriptor, storages, this._meterSharedState.observableRegistry); } /** - * Create a {@link metrics.ObservableCounter} instrument. + * Create a {@link ObservableCounter} instrument. */ createObservableCounter( name: string, - options?: metrics.MetricOptions, - ): metrics.ObservableCounter { + options?: MetricOptions, + ): ObservableCounter { const descriptor = createInstrumentDescriptor(name, InstrumentType.OBSERVABLE_COUNTER, options); const storages = this._meterSharedState.registerAsyncMetricStorage(descriptor); return new ObservableCounterInstrument(descriptor, storages, this._meterSharedState.observableRegistry); } /** - * Create a {@link metrics.ObservableUpDownCounter} instrument. + * Create a {@link ObservableUpDownCounter} instrument. */ createObservableUpDownCounter( name: string, - options?: metrics.MetricOptions, - ): metrics.ObservableUpDownCounter { + options?: MetricOptions, + ): ObservableUpDownCounter { const descriptor = createInstrumentDescriptor(name, InstrumentType.OBSERVABLE_UP_DOWN_COUNTER, options); const storages = this._meterSharedState.registerAsyncMetricStorage(descriptor); return new ObservableUpDownCounterInstrument(descriptor, storages, this._meterSharedState.observableRegistry); } /** - * @see {@link metrics.Meter.addBatchObservableCallback} + * @see {@link Meter.addBatchObservableCallback} */ - addBatchObservableCallback(callback: metrics.BatchObservableCallback, observables: metrics.Observable[]) { + addBatchObservableCallback(callback: BatchObservableCallback, observables: Observable[]) { this._meterSharedState.observableRegistry.addBatchCallback(callback, observables); } /** - * @see {@link metrics.Meter.removeBatchObservableCallback} + * @see {@link Meter.removeBatchObservableCallback} */ - removeBatchObservableCallback(callback: metrics.BatchObservableCallback, observables: metrics.Observable[]) { + removeBatchObservableCallback(callback: BatchObservableCallback, observables: Observable[]) { this._meterSharedState.observableRegistry.removeBatchCallback(callback, observables); } } diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts b/experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts index f8008d1c4b..01c3f54a1b 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts @@ -14,8 +14,13 @@ * limitations under the License. */ -import * as api from '@opentelemetry/api'; -import * as metrics from '@opentelemetry/api-metrics'; +import { + diag, + MeterProvider as IMeterProvider, + Meter as IMeter, + MeterOptions, + createNoopMeter, +} from '@opentelemetry/api'; import { Resource } from '@opentelemetry/resources'; import { MetricReader } from './export/MetricReader'; import { MeterProviderSharedState } from './state/MeterProviderSharedState'; @@ -33,9 +38,9 @@ export interface MeterProviderOptions { } /** - * This class implements the {@link metrics.MeterProvider} interface. + * This class implements the {@link MeterProvider} interface. */ -export class MeterProvider implements metrics.MeterProvider { +export class MeterProvider implements IMeterProvider { private _sharedState: MeterProviderSharedState; private _shutdown = false; @@ -51,11 +56,11 @@ export class MeterProvider implements metrics.MeterProvider { /** * Get a meter with the configuration of the MeterProvider. */ - getMeter(name: string, version = '', options: metrics.MeterOptions = {}): metrics.Meter { + getMeter(name: string, version = '', options: MeterOptions = {}): IMeter { // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#meter-creation if (this._shutdown) { - api.diag.warn('A shutdown MeterProvider cannot provide a Meter'); - return metrics.createNoopMeter(); + diag.warn('A shutdown MeterProvider cannot provide a Meter'); + return createNoopMeter(); } return this._sharedState @@ -83,7 +88,7 @@ export class MeterProvider implements metrics.MeterProvider { */ async shutdown(options?: ShutdownOptions): Promise { if (this._shutdown) { - api.diag.warn('shutdown may only be called once per MeterProvider'); + diag.warn('shutdown may only be called once per MeterProvider'); return; } @@ -102,7 +107,7 @@ export class MeterProvider implements metrics.MeterProvider { async forceFlush(options?: ForceFlushOptions): Promise { // do not flush after shutdown if (this._shutdown) { - api.diag.warn('invalid attempt to force flush after MeterProvider shutdown'); + diag.warn('invalid attempt to force flush after MeterProvider shutdown'); return; } diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/ObservableResult.ts b/experimental/packages/opentelemetry-sdk-metrics/src/ObservableResult.ts index 19ba32846c..e3a46f1c4d 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/ObservableResult.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/ObservableResult.ts @@ -14,16 +14,22 @@ * limitations under the License. */ -import * as api from '@opentelemetry/api'; -import * as metrics from '@opentelemetry/api-metrics'; +import { + diag, + ObservableResult, + MetricAttributes, + ValueType, + BatchObservableResult, + Observable, +} from '@opentelemetry/api'; import { AttributeHashMap } from './state/HashMap'; import { isObservableInstrument, ObservableInstrument } from './Instruments'; import { InstrumentDescriptor } from '.'; /** - * The class implements {@link metrics.ObservableResult} interface. + * The class implements {@link ObservableResult} interface. */ -export class ObservableResultImpl implements metrics.ObservableResult { +export class ObservableResultImpl implements ObservableResult { /** * @internal */ @@ -34,9 +40,9 @@ export class ObservableResultImpl implements metrics.ObservableResult { /** * Observe a measurement of the value associated with the given attributes. */ - observe(value: number, attributes: metrics.MetricAttributes = {}): void { - if (this._descriptor.valueType === metrics.ValueType.INT && !Number.isInteger(value)) { - api.diag.warn( + observe(value: number, attributes: MetricAttributes = {}): void { + if (this._descriptor.valueType === ValueType.INT && !Number.isInteger(value)) { + diag.warn( `INT value type cannot accept a floating-point value for ${this._descriptor.name}, ignoring the fractional digits.` ); value = Math.trunc(value); @@ -46,9 +52,9 @@ export class ObservableResultImpl implements metrics.ObservableResult { } /** - * The class implements {@link metrics.BatchObservableCallback} interface. + * The class implements {@link BatchObservableCallback} interface. */ -export class BatchObservableResultImpl implements metrics.BatchObservableResult { +export class BatchObservableResultImpl implements BatchObservableResult { /** * @internal */ @@ -57,7 +63,7 @@ export class BatchObservableResultImpl implements metrics.BatchObservableResult /** * Observe a measurement of the value associated with the given attributes. */ - observe(metric: metrics.Observable, value: number, attributes: metrics.MetricAttributes = {}): void { + observe(metric: Observable, value: number, attributes: MetricAttributes = {}): void { if (!isObservableInstrument(metric)) { return; } @@ -66,8 +72,8 @@ export class BatchObservableResultImpl implements metrics.BatchObservableResult map = new AttributeHashMap(); this._buffer.set(metric, map); } - if (metric._descriptor.valueType === metrics.ValueType.INT && !Number.isInteger(value)) { - api.diag.warn( + if (metric._descriptor.valueType === ValueType.INT && !Number.isInteger(value)) { + diag.warn( `INT value type cannot accept a floating-point value for ${metric._descriptor.name}, ignoring the fractional digits.` ); value = Math.trunc(value); diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts b/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts index 20c8f7ec4d..cc6a2a4976 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { HrTime } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { HrTime, MetricAttributes } from '@opentelemetry/api'; import { AggregationTemporality } from '../export/AggregationTemporality'; import { MetricData } from '../export/MetricData'; import { InstrumentDescriptor } from '../InstrumentDescriptor'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlignedHistogramBucketExemplarReservoir.ts b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlignedHistogramBucketExemplarReservoir.ts index 96060d16ae..0148ead72b 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlignedHistogramBucketExemplarReservoir.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlignedHistogramBucketExemplarReservoir.ts @@ -15,8 +15,7 @@ */ -import { Context, HrTime } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { Context, HrTime, MetricAttributes } from '@opentelemetry/api'; import { FixedSizeExemplarReservoirBase } from './ExemplarReservoir'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlwaysSampleExemplarFilter.ts b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlwaysSampleExemplarFilter.ts index d2c52cdc0e..01c4a5dbfb 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlwaysSampleExemplarFilter.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlwaysSampleExemplarFilter.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { MetricAttributes } from '@opentelemetry/api-metrics'; -import { Context, HrTime } from '@opentelemetry/api'; +import { Context, HrTime, MetricAttributes } from '@opentelemetry/api'; import { ExemplarFilter } from './ExemplarFilter'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/Exemplar.ts b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/Exemplar.ts index 28628ff04f..d98246dc49 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/Exemplar.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/Exemplar.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { HrTime } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { HrTime, MetricAttributes } from '@opentelemetry/api'; /** * A representation of an exemplar, which is a sample input measurement. diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts index ae005b4988..78b8ca0f39 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { MetricAttributes } from '@opentelemetry/api-metrics'; -import { Context, HrTime } from '@opentelemetry/api'; +import { Context, HrTime, MetricAttributes } from '@opentelemetry/api'; /** * This interface represents a ExemplarFilter. Exemplar filters are diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarReservoir.ts b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarReservoir.ts index 190976502e..fb2e0b8adb 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarReservoir.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarReservoir.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { MetricAttributes } from '@opentelemetry/api-metrics'; -import { Context, HrTime, isSpanContextValid, trace } from '@opentelemetry/api'; +import { Context, HrTime, isSpanContextValid, trace, MetricAttributes } from '@opentelemetry/api'; import { Exemplar } from './Exemplar'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/NeverSampleExemplarFilter.ts b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/NeverSampleExemplarFilter.ts index 374f35e52f..c51adda410 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/NeverSampleExemplarFilter.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/NeverSampleExemplarFilter.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { MetricAttributes } from '@opentelemetry/api-metrics'; -import { Context, HrTime } from '@opentelemetry/api'; +import { Context, HrTime, MetricAttributes } from '@opentelemetry/api'; import { ExemplarFilter } from './ExemplarFilter'; export class NeverSampleExemplarFilter implements ExemplarFilter { diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/SimpleFixedSizeExemplarReservoir.ts b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/SimpleFixedSizeExemplarReservoir.ts index 31b0369d87..892f0605dc 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/SimpleFixedSizeExemplarReservoir.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/SimpleFixedSizeExemplarReservoir.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { Context, HrTime } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { Context, HrTime, MetricAttributes } from '@opentelemetry/api'; import { FixedSizeExemplarReservoirBase } from './ExemplarReservoir'; /** diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/WithTraceExemplarFilter.ts b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/WithTraceExemplarFilter.ts index 1ca0439c0d..6251a36a05 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/WithTraceExemplarFilter.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/WithTraceExemplarFilter.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { MetricAttributes } from '@opentelemetry/api-metrics'; -import { Context, HrTime, isSpanContextValid, trace, TraceFlags } from '@opentelemetry/api'; +import { Context, HrTime, isSpanContextValid, trace, TraceFlags, MetricAttributes } from '@opentelemetry/api'; import { ExemplarFilter } from './ExemplarFilter'; export class WithTraceExemplarFilter implements ExemplarFilter { diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts index f31c748e0b..b15da1d9b9 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { HrTime } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { HrTime, MetricAttributes } from '@opentelemetry/api'; import { InstrumentationScope } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; import { InstrumentDescriptor } from '../InstrumentDescriptor'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/DeltaMetricProcessor.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/DeltaMetricProcessor.ts index 22c25edab0..999db3c282 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/DeltaMetricProcessor.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/DeltaMetricProcessor.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { Context, HrTime } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { Context, HrTime, MetricAttributes } from '@opentelemetry/api'; import { Maybe } from '../utils'; import { Accumulation, Aggregator } from '../aggregator/types'; import { AttributeHashMap } from './HashMap'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/HashMap.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/HashMap.ts index 0f8efd3794..681d4dedee 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/HashMap.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/HashMap.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { MetricAttributes } from '@opentelemetry/api'; import { hashAttributes } from '../utils'; export interface Hash { diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MultiWritableMetricStorage.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/MultiWritableMetricStorage.ts index 323ef83947..64694793ed 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/MultiWritableMetricStorage.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/MultiWritableMetricStorage.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { Context, HrTime } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { Context, HrTime, MetricAttributes } from '@opentelemetry/api'; import { WritableMetricStorage } from './WritableMetricStorage'; /** diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/ObservableRegistry.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/ObservableRegistry.ts index c74b9f9ab9..bd3e3fc6a7 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/ObservableRegistry.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/ObservableRegistry.ts @@ -14,9 +14,7 @@ * limitations under the License. */ -import * as api from '@opentelemetry/api'; -import { HrTime } from '@opentelemetry/api'; -import { BatchObservableCallback, Observable, ObservableCallback } from '@opentelemetry/api-metrics'; +import { diag, HrTime, BatchObservableCallback, Observable, ObservableCallback } from '@opentelemetry/api'; import { isObservableInstrument, ObservableInstrument } from '../Instruments'; import { BatchObservableResultImpl, ObservableResultImpl } from '../ObservableResult'; import { callWithTimeout, PromiseAllSettled, isPromiseAllSettledRejectionResult, setEquals } from '../utils'; @@ -67,7 +65,7 @@ export class ObservableRegistry { // Create a set of unique instruments. const observableInstruments = new Set(instruments.filter(isObservableInstrument)); if (observableInstruments.size === 0) { - api.diag.error('BatchObservableCallback is not associated with valid instruments', instruments); + diag.error('BatchObservableCallback is not associated with valid instruments', instruments); return; } const idx = this._findBatchCallback(callback, observableInstruments); diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/SyncMetricStorage.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/SyncMetricStorage.ts index 26d5fec1ab..7bfd5967b2 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/SyncMetricStorage.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/SyncMetricStorage.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { Context, HrTime } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { Context, HrTime, MetricAttributes } from '@opentelemetry/api'; import { WritableMetricStorage } from './WritableMetricStorage'; import { Accumulation, Aggregator } from '../aggregator/types'; import { InstrumentDescriptor } from '../InstrumentDescriptor'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/WritableMetricStorage.ts b/experimental/packages/opentelemetry-sdk-metrics/src/state/WritableMetricStorage.ts index 8bfdbcfde1..72945cd01d 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/state/WritableMetricStorage.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/state/WritableMetricStorage.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { Context, HrTime } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { Context, HrTime, MetricAttributes } from '@opentelemetry/api'; import { AttributeHashMap } from './HashMap'; /** diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/utils.ts b/experimental/packages/opentelemetry-sdk-metrics/src/utils.ts index 33e198b3ba..532e05d227 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/utils.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/utils.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { MetricAttributes } from '@opentelemetry/api'; import { InstrumentationScope } from '@opentelemetry/core'; export type Maybe = T | undefined; diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/AttributesProcessor.ts b/experimental/packages/opentelemetry-sdk-metrics/src/view/AttributesProcessor.ts index 9900daf82f..96858c6428 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/src/view/AttributesProcessor.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/src/view/AttributesProcessor.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { Context } from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { Context, MetricAttributes } from '@opentelemetry/api'; /** * The {@link AttributesProcessor} is responsible for customizing which diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts index 772e268fa4..1faa5b64a1 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts @@ -36,7 +36,7 @@ import { defaultResource, defaultInstrumentationScope } from './util'; -import { ObservableResult, ValueType } from '@opentelemetry/api-metrics'; +import { ObservableResult, ValueType } from '@opentelemetry/api'; describe('Instruments', () => { describe('Counter', () => { diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/Meter.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/Meter.test.ts index ada1234d58..c51c0baa52 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/Meter.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/Meter.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Observable } from '@opentelemetry/api-metrics'; +import { Observable } from '@opentelemetry/api'; import * as assert from 'assert'; import { CounterInstrument, diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts index aaa97768b8..c425eafec7 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ValueType } from '@opentelemetry/api-metrics'; +import { ValueType } from '@opentelemetry/api'; import * as assert from 'assert'; import { InstrumentType } from '../src'; import { ObservableInstrument } from '../src/Instruments'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Histogram.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Histogram.test.ts index f5d5ea7e33..3dadaf8b1c 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Histogram.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Histogram.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { HrTime } from '@opentelemetry/api'; +import { HrTime, ValueType } from '@opentelemetry/api'; import * as assert from 'assert'; import { AggregationTemporality, @@ -30,7 +30,6 @@ import { commonValues, defaultInstrumentDescriptor } from '../util'; -import { ValueType } from '@opentelemetry/api-metrics'; describe('HistogramAggregator', () => { describe('createAccumulation', () => { diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/ConsoleMetricExporter.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/ConsoleMetricExporter.test.ts index 39edda36f1..6097aeb555 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/export/ConsoleMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/ConsoleMetricExporter.test.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import * as metrics from '@opentelemetry/api-metrics'; +import * as metrics from '@opentelemetry/api'; import { ExportResult } from '@opentelemetry/core'; import { ConsoleMetricExporter } from '../../src/export/ConsoleMetricExporter'; import { PeriodicExportingMetricReader } from '../../src/export/PeriodicExportingMetricReader'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/InMemoryMetricExporter.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/export/InMemoryMetricExporter.test.ts index 7afb3299a4..cab538fd2d 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/export/InMemoryMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/export/InMemoryMetricExporter.test.ts @@ -15,7 +15,7 @@ */ import { ExportResultCode } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; -import * as metrics from '@opentelemetry/api-metrics'; +import * as metrics from '@opentelemetry/api'; import assert = require('assert'); import { AggregationTemporality } from '../../src/export/AggregationTemporality'; import { InMemoryMetricExporter } from '../../src/export/InMemoryMetricExporter'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/HashMap.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/state/HashMap.test.ts index d41c24e9f4..8ae772989b 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/state/HashMap.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/state/HashMap.test.ts @@ -15,7 +15,7 @@ */ import * as assert from 'assert'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { MetricAttributes } from '@opentelemetry/api'; import { HashMap } from '../../src/state/HashMap'; import { hashAttributes } from '../../src/utils'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts index fa8424b992..53ffa5a75a 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts @@ -15,13 +15,12 @@ */ import { MetricStorageRegistry } from '../../src/state/MetricStorageRegistry'; -import { ValueType } from '@opentelemetry/api-metrics'; +import { diag, ValueType } from '@opentelemetry/api'; import { MetricStorage } from '../../src/state/MetricStorage'; import { HrTime } from '@opentelemetry/api'; import { MetricCollectorHandle } from '../../src/state/MetricCollector'; import { MetricData, InstrumentDescriptor, InstrumentType } from '../../src'; import { Maybe } from '../../src/utils'; -import * as api from '@opentelemetry/api'; import * as assert from 'assert'; import * as sinon from 'sinon'; import { @@ -44,7 +43,7 @@ describe('MetricStorageRegistry', () => { let spyLoggerWarn: sinon.SinonStub<[message: string, ...args: unknown[]], void>; beforeEach(() => { - spyLoggerWarn = sinon.stub(api.diag, 'warn'); + spyLoggerWarn = sinon.stub(diag, 'warn'); }); afterEach(() => { diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MultiWritableMetricStorage.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/state/MultiWritableMetricStorage.test.ts index e91c952e69..1ccae07723 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/state/MultiWritableMetricStorage.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/state/MultiWritableMetricStorage.test.ts @@ -15,7 +15,7 @@ */ import * as api from '@opentelemetry/api'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { MetricAttributes } from '@opentelemetry/api'; import { hrTime } from '@opentelemetry/core'; import * as assert from 'assert'; import { MultiMetricStorage } from '../../src/state/MultiWritableMetricStorage'; diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/util.ts b/experimental/packages/opentelemetry-sdk-metrics/test/util.ts index 87c6184e37..80f9ab1c49 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/util.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/util.ts @@ -14,13 +14,13 @@ * limitations under the License. */ -import * as api from '@opentelemetry/api'; import { + Context, BatchObservableCallback, MetricAttributes, ObservableCallback, ValueType, -} from '@opentelemetry/api-metrics'; +} from '@opentelemetry/api'; import { InstrumentationScope } from '@opentelemetry/core'; import { Resource } from '@opentelemetry/resources'; import * as assert from 'assert'; @@ -40,7 +40,7 @@ export type Measurement = { value: number; // TODO: use common attributes attributes: MetricAttributes - context?: api.Context; + context?: Context; }; export const defaultResource = new Resource({ diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/utils.test.ts b/experimental/packages/opentelemetry-sdk-metrics/test/utils.test.ts index 07731a5376..2bf818088a 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/test/utils.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics/test/utils.test.ts @@ -18,7 +18,7 @@ import * as sinon from 'sinon'; import * as assert from 'assert'; import { callWithTimeout, hashAttributes, TimeoutError } from '../src/utils'; import { assertRejects } from './test-utils'; -import { MetricAttributes } from '@opentelemetry/api-metrics'; +import { MetricAttributes } from '@opentelemetry/api'; describe('utils', () => { afterEach(() => { diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json index fb267e4d26..379f547a46 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json +++ b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json @@ -7,10 +7,5 @@ }, "include": [ "src/**/*.ts" - ], - "references": [ - { - "path": "../../../api-metrics/tsconfig.esnext.json" - } ] } diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json index dc405c942c..cb78dd6ff3 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json +++ b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json @@ -7,10 +7,5 @@ }, "include": [ "src/**/*.ts" - ], - "references": [ - { - "path": "../../../api-metrics/tsconfig.esnext.json" - } ] } diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json index bcce5660d3..f93e34131f 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json +++ b/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json @@ -12,9 +12,6 @@ { "path": "../../../api" }, - { - "path": "../../../api-metrics" - }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index 8a60ba30b7..30d559fc65 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -49,7 +49,6 @@ "@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", "@opentelemetry/resources": "1.7.0", @@ -59,10 +58,10 @@ "@opentelemetry/semantic-conventions": "1.7.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.2.0 <1.3.0" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.2.0 <1.3.0", "@opentelemetry/context-async-hooks": "1.7.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts index bb20ed9440..38f85b87f2 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { ContextManager, TextMapPropagator } from '@opentelemetry/api'; -import { metrics } from '@opentelemetry/api-metrics'; +import { ContextManager, TextMapPropagator, metrics } from '@opentelemetry/api'; import { InstrumentationOption, registerInstrumentations diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index bb78a3f7d3..6d853e4902 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -21,8 +21,8 @@ import { trace, diag, DiagLogLevel, + metrics, } from '@opentelemetry/api'; -import { metrics } from '@opentelemetry/api-metrics'; import { AsyncHooksContextManager, AsyncLocalStorageContextManager, diff --git a/experimental/packages/opentelemetry-sdk-node/tsconfig.json b/experimental/packages/opentelemetry-sdk-node/tsconfig.json index 1ecf7ce067..20eb8eace7 100644 --- a/experimental/packages/opentelemetry-sdk-node/tsconfig.json +++ b/experimental/packages/opentelemetry-sdk-node/tsconfig.json @@ -12,9 +12,6 @@ { "path": "../../../api" }, - { - "path": "../../../api-metrics" - }, { "path": "../../../packages/opentelemetry-context-async-hooks" }, diff --git a/experimental/packages/otlp-transformer/package.json b/experimental/packages/otlp-transformer/package.json index 471c94cda9..8a5adedb64 100644 --- a/experimental/packages/otlp-transformer/package.json +++ b/experimental/packages/otlp-transformer/package.json @@ -52,10 +52,10 @@ "README.md" ], "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.2.0 <1.3.0" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.2.0 <1.3.0", "@types/mocha": "10.0.0", "@types/webpack-env": "1.16.3", "codecov": "3.8.3", @@ -76,7 +76,6 @@ "webpack": "4.46.0" }, "dependencies": { - "@opentelemetry/api-metrics": "0.33.0", "@opentelemetry/core": "1.7.0", "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-metrics": "0.33.0", diff --git a/experimental/packages/otlp-transformer/src/metrics/internal.ts b/experimental/packages/otlp-transformer/src/metrics/internal.ts index bc17b84976..7aa9c82acd 100644 --- a/experimental/packages/otlp-transformer/src/metrics/internal.ts +++ b/experimental/packages/otlp-transformer/src/metrics/internal.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ValueType } from '@opentelemetry/api-metrics'; +import { ValueType } from '@opentelemetry/api'; import { hrTimeToNanoseconds } from '@opentelemetry/core'; import { AggregationTemporality, diff --git a/experimental/packages/otlp-transformer/test/metrics.test.ts b/experimental/packages/otlp-transformer/test/metrics.test.ts index afb65d264a..df88389c5e 100644 --- a/experimental/packages/otlp-transformer/test/metrics.test.ts +++ b/experimental/packages/otlp-transformer/test/metrics.test.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ValueType } from '@opentelemetry/api-metrics'; +import { ValueType } from '@opentelemetry/api'; import { Resource } from '@opentelemetry/resources'; import { AggregationTemporality, diff --git a/experimental/packages/otlp-transformer/tsconfig.json b/experimental/packages/otlp-transformer/tsconfig.json index 64be5006a0..11ace43aeb 100644 --- a/experimental/packages/otlp-transformer/tsconfig.json +++ b/experimental/packages/otlp-transformer/tsconfig.json @@ -12,9 +12,6 @@ { "path": "../../../api" }, - { - "path": "../../../api-metrics" - }, { "path": "../../../packages/opentelemetry-core" }, diff --git a/lerna.json b/lerna.json index 26c6e6b7bb..d97ab02a62 100644 --- a/lerna.json +++ b/lerna.json @@ -3,7 +3,6 @@ "npmClient": "npm", "packages": [ "api", - "api-metrics", "packages/*", "experimental/packages/*", "experimental/examples/*", diff --git a/packages/opentelemetry-core/src/platform/browser/globalThis.ts b/packages/opentelemetry-core/src/platform/browser/globalThis.ts index aa3c2fec6e..c438f2895f 100644 --- a/packages/opentelemetry-core/src/platform/browser/globalThis.ts +++ b/packages/opentelemetry-core/src/platform/browser/globalThis.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -// Updates to this file should also be replicated to @opentelemetry/api and -// @opentelemetry/api-metrics too. +// Updates to this file should also be replicated to @opentelemetry/api too. /** * - globalThis (New standard) diff --git a/tsconfig.base.json b/tsconfig.base.json index ca44078430..cbafb67678 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -16,6 +16,7 @@ "noImplicitReturns": true, "noUnusedLocals": true, "pretty": true, + "skipLibCheck": true, "sourceMap": true, "strict": true, "strictNullChecks": true, diff --git a/tsconfig.json b/tsconfig.json index d6642f0f02..371ba80055 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,6 @@ "experimental/packages/exporter-trace-otlp-grpc", "experimental/packages/exporter-trace-otlp-http", "experimental/packages/exporter-trace-otlp-proto", - "experimental/packages/opentelemetry-api-metrics", "experimental/packages/opentelemetry-exporter-metrics-otlp-grpc", "experimental/packages/opentelemetry-exporter-metrics-otlp-http", "experimental/packages/opentelemetry-exporter-metrics-otlp-proto", @@ -53,9 +52,6 @@ { "path": "api" }, - { - "path": "api-metrics" - }, { "path": "packages/opentelemetry-context-async-hooks" }, From d154066354863e8c682b4aa488d79c7e914bf91c Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Fri, 4 Nov 2022 08:27:04 +0100 Subject: [PATCH 59/77] deps(instrumentation-http): move sdk-metrics to dev dependencies (#3380) --- experimental/CHANGELOG.md | 1 + .../packages/opentelemetry-instrumentation-http/package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index a2f7b6b6bd..426ca3d990 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -34,6 +34,7 @@ All notable changes to experimental packages in this project will be documented * ci(instrumentation-http): remove got devDependency [#3347](https://github.com/open-telemetry/opentelemetry-js/issues/3347) @dyladan +* deps(instrumentation-http): move sdk-metrics to dev dependencies [#3380](https://github.com/open-telemetry/opentelemetry-js/issues/3380) @pichlermarc ## 0.33.0 diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index 67983b76d6..dc20ae09c4 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -47,6 +47,7 @@ "devDependencies": { "@opentelemetry/api": "^1.2.0", "@opentelemetry/context-async-hooks": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0", "@opentelemetry/sdk-trace-base": "1.7.0", "@opentelemetry/sdk-trace-node": "1.7.0", "@types/mocha": "10.0.0", @@ -74,7 +75,6 @@ "dependencies": { "@opentelemetry/core": "1.7.0", "@opentelemetry/instrumentation": "0.33.0", - "@opentelemetry/sdk-metrics": "0.33.0", "@opentelemetry/semantic-conventions": "1.7.0", "semver": "^7.3.5" }, From 85c62ef617bdb42283ca3a466f52f111d017aa32 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Tue, 8 Nov 2022 16:15:49 +0800 Subject: [PATCH 60/77] docs(api): fix counter negative value wording (#3396) --- CHANGELOG.md | 2 ++ api/src/metrics/Metric.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce8e916111..5f382b980c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ All notable changes to this project will be documented in this file. ### :books: (Refine Doc) +* docs(api): fix counter negative value wording [#3396](https://github.com/open-telemetry/opentelemetry-js/pull/3396) @legendecas + ### :house: (Internal) * ci: run browser tests without circle [#3328](https://github.com/open-telemetry/opentelemetry-js/pull/3328) @dyladan diff --git a/api/src/metrics/Metric.ts b/api/src/metrics/Metric.ts index b20cfa4662..d0b6909bd7 100644 --- a/api/src/metrics/Metric.ts +++ b/api/src/metrics/Metric.ts @@ -64,7 +64,7 @@ export enum ValueType { */ export interface Counter { /** - * Increment value of counter by the input. Inputs may not be negative. + * Increment value of counter by the input. Inputs must not be negative. */ add(value: number, attributes?: AttributesTypes, context?: Context): void; } From c6ff50ee18eeb5d6ea357f6b00a56037a82a23cb Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Wed, 9 Nov 2022 02:42:36 +0800 Subject: [PATCH 61/77] docs: document how to implement a propagator (#3351) Co-authored-by: Marc Pichler Co-authored-by: Daniel Dyla Co-authored-by: Valentin Marchaud --- doc/propagation.md | 91 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/doc/propagation.md b/doc/propagation.md index 1cb3928bde..c3d246c0fc 100644 --- a/doc/propagation.md +++ b/doc/propagation.md @@ -1,5 +1,92 @@ # Propagation -TODO +Span context fields like trace id, span id, trace flags, and baggages need to be send to the downstream services +in order to properly associate downstream created spans with the current span. -_Propagation API reference: _ +This is commonly achieved with HTTP headers, RPC metadata, with well-known formats like: + +- [W3C Trace Context][]: Supported with [W3CTraceContextPropagator][]. +- [B3][]: Supported with [B3Propagator][]. +- Jaeger: Supported with [JaegerPropagator][]. + +If none of the above formats meet your needs, you can implement your own propagator. + +## Implement your own propagator + +To implement a propagator, you need to define a class implementing the `TextMapPropagator` interface. + +```ts +import { + Context, + isSpanContextValid, + isValidSpanId, + isValidTraceId, + TextMapGetter, + TextMapPropagator, + TextMapSetter, + TraceFlags, + trace, +} from '@opentelemetry/api'; +import { isTracingSuppressed } from '@opentelemetry/core'; + +// Example header, the content format can be `:` +const MyHeader = 'my-header'; + +export class MyPropagator implements TextMapPropagator { + // Inject the header to the outgoing request. + inject(context: Context, carrier: unknown, setter: TextMapSetter): void { + const spanContext = trace.getSpanContext(context); + // Skip if the current span context is not valid or suppressed. + if ( + !spanContext || + !isSpanContextValid(spanContext) || + isTracingSuppressed(context) + ) { + return; + } + + const value = `${spanContext.traceId}:${spanContext.spanId}`; + setter.set(carrier, MyHeader, value); + // You can set more header fields as you need. + } + + // Extract the header from the incoming request. + extract(context: Context, carrier: unknown, getter: TextMapGetter): Context { + const headers = getter.get(carrier, MyHeader); + const header = Array.isArray(headers) ? headers[0] : headers; + if (typeof header !== 'string') return context; + + const [traceId, spanId] = header.split(':'); + + // Skip if the traceId or spanId is invalid. + if (!isValidTraceId(traceId) || !isValidSpanId(spanId)) return context; + + return trace.setSpanContext(context, { + traceId, + spanId, + isRemote: true, + traceFlags: TraceFlags.SAMPLED, + }); + } + + fields(): string[] { + return [MyHeader]; + } +} +``` + +With the propagator defined, you can set it as the global propagator, so that all instrumentations +can make use of it. + +```ts +const api = require('@opentelemetry/api'); +const { MyPropagator } = require('./my-propagator'); + +api.propagation.setGlobalPropagator(new MyPropagator()); +``` + +[B3]: https://github.com/openzipkin/b3-propagation +[B3Propagator]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-b3 +[JaegerPropagator]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-jaeger +[W3C Trace Context]: https://www.w3.org/TR/trace-context/ +[W3CTraceContextPropagator]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-core#w3ctracecontextpropagator-propagator From baf0feea263bfa8d7dfe6d7b9a9b3a967771daca Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Tue, 8 Nov 2022 20:51:58 +0100 Subject: [PATCH 62/77] feat(api): Optionally suppress warning about logger being overwritten (#3366) Co-authored-by: Daniel Dyla --- api/CHANGELOG.md | 6 ++++++ api/src/api/diag.ts | 31 ++++++++++++++++--------------- api/src/diag/types.ts | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/api/CHANGELOG.md b/api/CHANGELOG.md index 139f4a33fa..ff82beb8e6 100644 --- a/api/CHANGELOG.md +++ b/api/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## Unreleased + +### Features + +* Optionally suppress warning about logger being overwritten ([#3366](https://www.github.com/open-telemetry/opentelemetry-js-api/pull/3366)) + ## [1.2.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.1.0...v1.2.0) (2022-08-09) ### Features diff --git a/api/src/api/diag.ts b/api/src/api/diag.ts index 3fd1027a62..516657d8c8 100644 --- a/api/src/api/diag.ts +++ b/api/src/api/diag.ts @@ -20,6 +20,7 @@ import { ComponentLoggerOptions, DiagLogFunction, DiagLogger, + DiagLoggerApi, DiagLogLevel, } from '../diag/types'; import { @@ -34,7 +35,7 @@ const API_NAME = 'diag'; * Singleton object which represents the entry point to the OpenTelemetry internal * diagnostic API */ -export class DiagAPI implements DiagLogger { +export class DiagAPI implements DiagLogger, DiagLoggerApi { private static _instance?: DiagAPI; /** Get the singleton instance of the DiagAPI API */ @@ -65,9 +66,9 @@ export class DiagAPI implements DiagLogger { // DiagAPI specific functions - self.setLogger = ( - logger: DiagLogger, - logLevel: DiagLogLevel = DiagLogLevel.INFO + const setLogger: DiagLoggerApi['setLogger'] = ( + logger, + optionsOrLogLevel = { logLevel: DiagLogLevel.INFO }, ) => { if (logger === self) { // There isn't much we can do here. @@ -80,10 +81,16 @@ export class DiagAPI implements DiagLogger { return false; } + if (typeof optionsOrLogLevel === 'number') { + optionsOrLogLevel = { + logLevel: optionsOrLogLevel, + }; + } + const oldLogger = getGlobal('diag'); - const newLogger = createLogLevelDiagLogger(logLevel, logger); + const newLogger = createLogLevelDiagLogger(optionsOrLogLevel.logLevel ?? DiagLogLevel.INFO, logger); // There already is an logger registered. We'll let it know before overwriting it. - if (oldLogger) { + if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) { const stack = new Error().stack ?? ''; oldLogger.warn(`Current logger will be overwritten from ${stack}`); newLogger.warn( @@ -94,6 +101,8 @@ export class DiagAPI implements DiagLogger { return registerGlobal('diag', newLogger, self, true); }; + self.setLogger = setLogger; + self.disable = () => { unregisterGlobal(API_NAME, self); }; @@ -109,15 +118,7 @@ export class DiagAPI implements DiagLogger { self.error = _logProxy('error'); } - /** - * Set the global DiagLogger and DiagLogLevel. - * If a global diag logger is already set, this will override it. - * - * @param logger - [Optional] The DiagLogger instance to set as the default logger. - * @param logLevel - [Optional] The DiagLogLevel used to filter logs sent to the logger. If not provided it will default to INFO. - * @returns true if the logger was successfully registered, else false - */ - public setLogger!: (logger: DiagLogger, logLevel?: DiagLogLevel) => boolean; + public setLogger!: DiagLoggerApi['setLogger']; /** * */ diff --git a/api/src/diag/types.ts b/api/src/diag/types.ts index 54bf398d01..e2ec879f03 100644 --- a/api/src/diag/types.ts +++ b/api/src/diag/types.ts @@ -96,3 +96,37 @@ export enum DiagLogLevel { export interface ComponentLoggerOptions { namespace: string; } + +export interface LoggerOptions { + /** + * The {@link DiagLogLevel} used to filter logs sent to the logger. + * + * @defaultValue DiagLogLevel.INFO + */ + logLevel?: DiagLogLevel; + + /** + * Setting this value to `true` will suppress the warning message normally emitted when registering a logger when another logger is already registered. + */ + suppressOverrideMessage?: boolean; +} + +export interface DiagLoggerApi { + /** + * Set the global DiagLogger and DiagLogLevel. + * If a global diag logger is already set, this will override it. + * + * @param logger - The {@link DiagLogger} instance to set as the default logger. + * @param options - A {@link LoggerOptions} object. If not provided, default values will be set. + * @returns `true` if the logger was successfully registered, else `false` + */ + setLogger(logger: DiagLogger, options?: LoggerOptions): boolean; + + /** + * + * @param logger - The {@link DiagLogger} instance to set as the default logger. + * @param logLevel - The {@link DiagLogLevel} used to filter logs sent to the logger. If not provided it will default to {@link DiagLogLevel.INFO}. + * @returns `true` if the logger was successfully registered, else `false` + */ + setLogger(logger: DiagLogger, logLevel?: DiagLogLevel): boolean; +} From 27c4f762948c9b8d693d5ce1c2df5aaa5b0e92ee Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 9 Nov 2022 13:32:23 -0500 Subject: [PATCH 63/77] chore: release API 1.3.0 (#3399) --- api/CHANGELOG.md | 5 ++--- api/package.json | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/api/CHANGELOG.md b/api/CHANGELOG.md index ff82beb8e6..12b33c4e2c 100644 --- a/api/CHANGELOG.md +++ b/api/CHANGELOG.md @@ -2,10 +2,9 @@ All notable changes to this project will be documented in this file. -## Unreleased - -### Features +## [1.3.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.2.0...v1.3.0) +* feat(api): merge api-metrics into api [#3374](https://github.com/open-telemetry/opentelemetry-js/pull/3374) @legendecas * Optionally suppress warning about logger being overwritten ([#3366](https://www.github.com/open-telemetry/opentelemetry-js-api/pull/3366)) ## [1.2.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.1.0...v1.2.0) (2022-08-09) diff --git a/api/package.json b/api/package.json index 799ea8ab95..50e3782e80 100644 --- a/api/package.json +++ b/api/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/api", - "version": "1.2.0", + "version": "1.3.0", "description": "Public API for OpenTelemetry", "main": "build/src/index.js", "module": "build/esm/index.js", From 7972edf6659fb6e0d5928a5cf7a35f26683e168f Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 9 Nov 2022 14:21:50 -0500 Subject: [PATCH 64/77] chore: release SDK 1.8.0 / Experimental 0.34.0 with metrics GA (#3340) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- CHANGELOG.md | 23 +++++++++++++ examples/https/package.json | 18 +++++------ examples/opentelemetry-web/package.json | 30 ++++++++--------- examples/otlp-exporter-node/package.json | 26 +++++++-------- experimental/CHANGELOG.md | 14 ++++++-- .../node14/package.json | 6 ++-- .../node16/package.json | 6 ++-- experimental/examples/prometheus/package.json | 9 +++--- experimental/packages/api-logs/package.json | 2 +- .../exporter-trace-otlp-grpc/package.json | 14 ++++---- .../exporter-trace-otlp-http/package.json | 12 +++---- .../exporter-trace-otlp-proto/package.json | 14 ++++---- .../package.json | 6 ++-- .../package.json | 18 +++++------ .../tsconfig.json | 4 +-- .../package.json | 16 +++++----- .../tsconfig.json | 2 +- .../package.json | 20 ++++++------ .../tsconfig.json | 4 +-- .../package.json | 12 +++---- .../tsconfig.json | 2 +- .../package.json | 16 +++++----- .../package.json | 18 +++++------ .../package.json | 20 ++++++------ .../tsconfig.json | 4 +-- .../package.json | 16 +++++----- .../package.json | 6 ++-- .../opentelemetry-sdk-node/package.json | 32 +++++++++---------- .../opentelemetry-sdk-node/tsconfig.json | 6 ++-- .../packages/otlp-exporter-base/package.json | 4 +-- .../otlp-grpc-exporter-base/package.json | 12 +++---- .../otlp-proto-exporter-base/package.json | 6 ++-- .../packages/otlp-transformer/package.json | 14 ++++---- .../packages/otlp-transformer/tsconfig.json | 2 +- .../package.json | 8 ++--- .../package.json | 6 ++-- .../package.json | 6 ++-- .../opentelemetry-context-zone/package.json | 4 +-- packages/opentelemetry-core/package.json | 8 ++--- .../package.json | 10 +++--- .../package.json | 10 +++--- .../opentelemetry-propagator-b3/package.json | 8 ++--- .../package.json | 8 ++--- packages/opentelemetry-resources/package.json | 10 +++--- .../opentelemetry-sdk-trace-base/package.json | 12 +++---- .../opentelemetry-sdk-trace-node/package.json | 20 ++++++------ .../opentelemetry-sdk-trace-web/package.json | 18 +++++------ .../package.json | 2 +- .../package.json | 16 +++++----- .../sdk-metrics}/.eslintignore | 0 .../sdk-metrics}/.eslintrc.js | 2 +- .../sdk-metrics}/.npmignore | 0 .../sdk-metrics}/LICENSE | 0 .../sdk-metrics}/README.md | 0 .../sdk-metrics}/karma.conf.js | 4 +-- .../sdk-metrics}/package.json | 18 +++++------ .../sdk-metrics}/src/InstrumentDescriptor.ts | 0 .../sdk-metrics}/src/Instruments.ts | 0 .../sdk-metrics}/src/Meter.ts | 0 .../sdk-metrics}/src/MeterProvider.ts | 0 .../sdk-metrics}/src/ObservableResult.ts | 0 .../sdk-metrics}/src/aggregator/Drop.ts | 0 .../sdk-metrics}/src/aggregator/Histogram.ts | 0 .../sdk-metrics}/src/aggregator/LastValue.ts | 0 .../sdk-metrics}/src/aggregator/Sum.ts | 0 .../sdk-metrics}/src/aggregator/index.ts | 0 .../sdk-metrics}/src/aggregator/types.ts | 0 ...AlignedHistogramBucketExemplarReservoir.ts | 0 .../exemplar/AlwaysSampleExemplarFilter.ts | 0 .../sdk-metrics}/src/exemplar/Exemplar.ts | 0 .../src/exemplar/ExemplarFilter.ts | 0 .../src/exemplar/ExemplarReservoir.ts | 0 .../src/exemplar/NeverSampleExemplarFilter.ts | 0 .../SimpleFixedSizeExemplarReservoir.ts | 0 .../src/exemplar/WithTraceExemplarFilter.ts | 0 .../sdk-metrics}/src/exemplar/index.ts | 0 .../src/export/AggregationSelector.ts | 0 .../src/export/AggregationTemporality.ts | 0 .../src/export/ConsoleMetricExporter.ts | 0 .../src/export/InMemoryMetricExporter.ts | 0 .../sdk-metrics}/src/export/MetricData.ts | 0 .../sdk-metrics}/src/export/MetricExporter.ts | 0 .../sdk-metrics}/src/export/MetricProducer.ts | 0 .../sdk-metrics}/src/export/MetricReader.ts | 0 .../export/PeriodicExportingMetricReader.ts | 0 .../sdk-metrics}/src/index.ts | 0 .../src/state/AsyncMetricStorage.ts | 0 .../src/state/DeltaMetricProcessor.ts | 0 .../sdk-metrics}/src/state/HashMap.ts | 0 .../src/state/MeterProviderSharedState.ts | 0 .../src/state/MeterSharedState.ts | 0 .../sdk-metrics}/src/state/MetricCollector.ts | 0 .../sdk-metrics}/src/state/MetricStorage.ts | 0 .../src/state/MetricStorageRegistry.ts | 0 .../src/state/MultiWritableMetricStorage.ts | 0 .../src/state/ObservableRegistry.ts | 0 .../src/state/SyncMetricStorage.ts | 0 .../src/state/TemporalMetricProcessor.ts | 0 .../src/state/WritableMetricStorage.ts | 0 .../sdk-metrics}/src/types.ts | 0 .../sdk-metrics}/src/utils.ts | 0 .../sdk-metrics}/src/view/Aggregation.ts | 0 .../src/view/AttributesProcessor.ts | 0 .../src/view/InstrumentSelector.ts | 0 .../sdk-metrics}/src/view/MeterSelector.ts | 0 .../sdk-metrics}/src/view/Predicate.ts | 0 .../src/view/RegistrationConflicts.ts | 0 .../sdk-metrics}/src/view/View.ts | 0 .../sdk-metrics}/src/view/ViewRegistry.ts | 0 .../sdk-metrics}/test/ExemplarFilter.test.ts | 0 .../test/ExemplarReservoir.test.ts | 0 .../test/InstrumentDescriptor.test.ts | 0 .../sdk-metrics}/test/Instruments.test.ts | 0 .../sdk-metrics}/test/Meter.test.ts | 0 .../sdk-metrics}/test/MeterProvider.test.ts | 0 .../test/ObservableResult.test.ts | 0 .../sdk-metrics}/test/aggregator/Drop.test.ts | 0 .../test/aggregator/Histogram.test.ts | 0 .../test/aggregator/LastValue.test.ts | 0 .../sdk-metrics}/test/aggregator/Sum.test.ts | 0 .../test/export/ConsoleMetricExporter.test.ts | 0 .../export/InMemoryMetricExporter.test.ts | 0 .../test/export/MetricReader.test.ts | 0 .../PeriodicExportingMetricReader.test.ts | 0 .../test/export/TestMetricExporter.ts | 0 .../test/export/TestMetricProducer.ts | 0 .../test/export/TestMetricReader.ts | 0 .../sdk-metrics}/test/export/utils.ts | 0 .../sdk-metrics}/test/index-webpack.ts | 0 .../test/state/AsyncMetricStorage.test.ts | 0 .../test/state/DeltaMetricProcessor.test.ts | 0 .../sdk-metrics}/test/state/HashMap.test.ts | 0 .../test/state/MeterSharedState.test.ts | 0 .../test/state/MetricCollector.test.ts | 0 .../test/state/MetricStorageRegistry.test.ts | 0 .../state/MultiWritableMetricStorage.test.ts | 0 .../test/state/ObservableRegistry.test.ts | 0 .../test/state/SyncMetricStorage.test.ts | 0 .../state/TemporalMetricProcessor.test.ts | 0 .../sdk-metrics}/test/test-utils.ts | 0 .../sdk-metrics}/test/util.ts | 0 .../sdk-metrics}/test/utils.test.ts | 0 .../test/view/Aggregation.test.ts | 0 .../test/view/AttributesProcessor.test.ts | 0 .../sdk-metrics}/test/view/Predicate.test.ts | 0 .../sdk-metrics}/test/view/View.test.ts | 0 .../test/view/ViewRegistry.test.ts | 0 .../sdk-metrics}/tsconfig.all.json | 2 +- .../sdk-metrics}/tsconfig.esm.json | 2 +- .../sdk-metrics}/tsconfig.esnext.json | 2 +- .../sdk-metrics}/tsconfig.json | 8 ++--- packages/template/package.json | 2 +- selenium-tests/package.json | 22 ++++++------- tsconfig.json | 6 ++-- 155 files changed, 332 insertions(+), 298 deletions(-) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/.eslintignore (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/.eslintrc.js (65%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/.npmignore (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/LICENSE (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/README.md (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/karma.conf.js (86%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/package.json (85%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/InstrumentDescriptor.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/Instruments.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/Meter.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/MeterProvider.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/ObservableResult.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/aggregator/Drop.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/aggregator/Histogram.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/aggregator/LastValue.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/aggregator/Sum.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/aggregator/index.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/aggregator/types.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/exemplar/AlignedHistogramBucketExemplarReservoir.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/exemplar/AlwaysSampleExemplarFilter.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/exemplar/Exemplar.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/exemplar/ExemplarFilter.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/exemplar/ExemplarReservoir.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/exemplar/NeverSampleExemplarFilter.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/exemplar/SimpleFixedSizeExemplarReservoir.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/exemplar/WithTraceExemplarFilter.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/exemplar/index.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/export/AggregationSelector.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/export/AggregationTemporality.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/export/ConsoleMetricExporter.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/export/InMemoryMetricExporter.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/export/MetricData.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/export/MetricExporter.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/export/MetricProducer.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/export/MetricReader.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/export/PeriodicExportingMetricReader.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/index.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/AsyncMetricStorage.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/DeltaMetricProcessor.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/HashMap.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/MeterProviderSharedState.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/MeterSharedState.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/MetricCollector.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/MetricStorage.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/MetricStorageRegistry.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/MultiWritableMetricStorage.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/ObservableRegistry.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/SyncMetricStorage.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/TemporalMetricProcessor.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/state/WritableMetricStorage.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/types.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/utils.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/view/Aggregation.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/view/AttributesProcessor.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/view/InstrumentSelector.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/view/MeterSelector.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/view/Predicate.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/view/RegistrationConflicts.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/view/View.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/src/view/ViewRegistry.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/ExemplarFilter.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/ExemplarReservoir.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/InstrumentDescriptor.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/Instruments.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/Meter.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/MeterProvider.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/ObservableResult.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/aggregator/Drop.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/aggregator/Histogram.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/aggregator/LastValue.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/aggregator/Sum.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/export/ConsoleMetricExporter.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/export/InMemoryMetricExporter.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/export/MetricReader.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/export/PeriodicExportingMetricReader.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/export/TestMetricExporter.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/export/TestMetricProducer.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/export/TestMetricReader.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/export/utils.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/index-webpack.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/AsyncMetricStorage.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/DeltaMetricProcessor.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/HashMap.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/MeterSharedState.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/MetricCollector.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/MetricStorageRegistry.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/MultiWritableMetricStorage.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/ObservableRegistry.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/SyncMetricStorage.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/state/TemporalMetricProcessor.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/test-utils.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/util.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/utils.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/view/Aggregation.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/view/AttributesProcessor.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/view/Predicate.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/view/View.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/test/view/ViewRegistry.test.ts (100%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/tsconfig.all.json (78%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/tsconfig.esm.json (78%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/tsconfig.esnext.json (78%) rename {experimental/packages/opentelemetry-sdk-metrics => packages/sdk-metrics}/tsconfig.json (51%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index f50009ef60..5cadb10953 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -84,7 +84,7 @@ body: "start": "node -r tracing.js app.js" }, "dependencies": { - "@opentelemetry/api": "^1.2.0", + "@opentelemetry/api": "^1.3.0", "@opentelemetry/sdk-trace-base": "~1.3.1", ... } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f382b980c..6df58ae19c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,28 @@ All notable changes to this project will be documented in this file. +For API changes, see the [API CHANGELOG](api/CHANGELOG.md). +For experimental package changes, see the [experimental CHANGELOG](experimental/CHANGELOG.md). + ## Unreleased ### :boom: Breaking Change +### :rocket: (Enhancement) + +### :bug: (Bug Fix) + +### :books: (Refine Doc) + +### :house: (Internal) + +## 1.8.0 + +* `@opentelemetry/sdk-metrics` has been promoted to stable +* `@opentelemetry/api-metrics` has been merged into `@opentelemetry/api` and deprecated + +### :boom: Breaking Change + * feat(api): merge api-metrics into api [#3374](https://github.com/open-telemetry/opentelemetry-js/pull/3374) @legendecas ### :rocket: (Enhancement) @@ -37,6 +55,11 @@ All notable changes to this project will be documented in this file. Metrics API is now stable and generally available. There are no changes between 1.0.0 and the previous 0.33.0 version. +### :boom: Breaking Change + +* Add semver check to metrics API [#3357](https://github.com/open-telemetry/opentelemetry-js/pull/3357) @dyladan + * Previously API versions were only considered compatible if the API was exactly the same + ## 1.7.0 ### :bug: (Bug Fix) diff --git a/examples/https/package.json b/examples/https/package.json index e9dcc45177..e693df3b09 100644 --- a/examples/https/package.json +++ b/examples/https/package.json @@ -1,7 +1,7 @@ { "name": "https-example", "private": true, - "version": "0.33.0", + "version": "0.34.0", "description": "Example of HTTPs integration with OpenTelemetry", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -33,14 +33,14 @@ }, "dependencies": { "@opentelemetry/api": "^1.0.0", - "@opentelemetry/exporter-jaeger": "1.7.0", - "@opentelemetry/exporter-zipkin": "1.7.0", - "@opentelemetry/instrumentation": "0.33.0", - "@opentelemetry/instrumentation-http": "0.33.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/sdk-trace-node": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/exporter-jaeger": "1.8.0", + "@opentelemetry/exporter-zipkin": "1.8.0", + "@opentelemetry/instrumentation": "0.34.0", + "@opentelemetry/instrumentation-http": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/sdk-trace-node": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/https", "devDependencies": { diff --git a/examples/opentelemetry-web/package.json b/examples/opentelemetry-web/package.json index 966968275d..827b2279c3 100644 --- a/examples/opentelemetry-web/package.json +++ b/examples/opentelemetry-web/package.json @@ -1,7 +1,7 @@ { "name": "web-opentelemetry-example", "private": true, - "version": "0.33.0", + "version": "0.34.0", "description": "Example of using @opentelemetry/sdk-trace-web and @opentelemetry/sdk-metrics in browser", "main": "index.js", "scripts": { @@ -42,20 +42,20 @@ "webpack-merge": "^5.8.0" }, "dependencies": { - "@opentelemetry/api": "^1.2.0", - "@opentelemetry/context-zone": "1.7.0", - "@opentelemetry/core": "1.7.0", - "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", - "@opentelemetry/exporter-trace-otlp-http": "0.33.0", - "@opentelemetry/exporter-zipkin": "1.7.0", - "@opentelemetry/instrumentation": "0.33.0", - "@opentelemetry/instrumentation-fetch": "0.33.0", - "@opentelemetry/instrumentation-xml-http-request": "0.33.0", - "@opentelemetry/propagator-b3": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/sdk-trace-web": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/api": "^1.3.0", + "@opentelemetry/context-zone": "1.8.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.34.0", + "@opentelemetry/exporter-trace-otlp-http": "0.34.0", + "@opentelemetry/exporter-zipkin": "1.8.0", + "@opentelemetry/instrumentation": "0.34.0", + "@opentelemetry/instrumentation-fetch": "0.34.0", + "@opentelemetry/instrumentation-xml-http-request": "0.34.0", + "@opentelemetry/propagator-b3": "1.8.0", + "@opentelemetry/sdk-metrics": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/sdk-trace-web": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/tracer-web" } diff --git a/examples/otlp-exporter-node/package.json b/examples/otlp-exporter-node/package.json index d122327991..3468b247f0 100644 --- a/examples/otlp-exporter-node/package.json +++ b/examples/otlp-exporter-node/package.json @@ -1,7 +1,7 @@ { "name": "example-otlp-exporter-node", "private": true, - "version": "0.33.0", + "version": "0.34.0", "description": "Example of using @opentelemetry/collector-exporter in Node.js", "main": "index.js", "scripts": { @@ -28,18 +28,18 @@ "url": "https://github.com/open-telemetry/opentelemetry-js/issues" }, "dependencies": { - "@opentelemetry/api": "^1.2.0", - "@opentelemetry/core": "1.7.0", - "@opentelemetry/exporter-metrics-otlp-grpc": "0.33.0", - "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", - "@opentelemetry/exporter-metrics-otlp-proto": "0.33.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/resources": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/api": "^1.3.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.34.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.34.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.34.0", + "@opentelemetry/exporter-trace-otlp-grpc": "0.34.0", + "@opentelemetry/exporter-trace-otlp-http": "0.34.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-metrics": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/otlp-exporter-node" } diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 426ca3d990..62ccda9e0a 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -6,8 +6,18 @@ All notable changes to experimental packages in this project will be documented ### :boom: Breaking Change -* Add semver check to metrics API [#3357](https://github.com/open-telemetry/opentelemetry-js/pull/3357) @dyladan - * Previously API versions were only considered compatible if the API was exactly the same +### :rocket: (Enhancement) + +### :bug: (Bug Fix) + +### :books: (Refine Doc) + +### :house: (Internal) + +## 0.34.0 + +* `@opentelemetry/sdk-metrics` moved to [packages/sdk-metrics](../packages/sdk-metrics) +* `@opentelemetry/api-metrics` deprecated and merged into [api](../api) ### :rocket: (Enhancement) diff --git a/experimental/backwards-compatability/node14/package.json b/experimental/backwards-compatability/node14/package.json index 30cc1e1f5d..a8ff394187 100644 --- a/experimental/backwards-compatability/node14/package.json +++ b/experimental/backwards-compatability/node14/package.json @@ -1,6 +1,6 @@ { "name": "backcompat-node14", - "version": "0.33.0", + "version": "0.34.0", "private": true, "description": "Backwards compatability app for node 14 types and the OpenTelemetry Node.js SDK", "main": "index.js", @@ -9,8 +9,8 @@ "peer-api-check": "node ../../../scripts/peer-api-check.js" }, "dependencies": { - "@opentelemetry/sdk-node": "0.33.0", - "@opentelemetry/sdk-trace-base": "1.7.0" + "@opentelemetry/sdk-node": "0.34.0", + "@opentelemetry/sdk-trace-base": "1.8.0" }, "devDependencies": { "@types/node": "14.18.25", diff --git a/experimental/backwards-compatability/node16/package.json b/experimental/backwards-compatability/node16/package.json index f130915560..03d284dbdb 100644 --- a/experimental/backwards-compatability/node16/package.json +++ b/experimental/backwards-compatability/node16/package.json @@ -1,6 +1,6 @@ { "name": "backcompat-node16", - "version": "0.33.0", + "version": "0.34.0", "private": true, "description": "Backwards compatability app for node 16 types and the OpenTelemetry Node.js SDK", "main": "index.js", @@ -9,8 +9,8 @@ "peer-api-check": "node ../../../scripts/peer-api-check.js" }, "dependencies": { - "@opentelemetry/sdk-node": "0.33.0", - "@opentelemetry/sdk-trace-base": "1.7.0" + "@opentelemetry/sdk-node": "0.34.0", + "@opentelemetry/sdk-trace-base": "1.8.0" }, "devDependencies": { "@types/node": "16.11.52", diff --git a/experimental/examples/prometheus/package.json b/experimental/examples/prometheus/package.json index 96a9f5572d..55cefc9d76 100644 --- a/experimental/examples/prometheus/package.json +++ b/experimental/examples/prometheus/package.json @@ -1,6 +1,7 @@ { "name": "prometheus-example", - "version": "0.33.0", + "version": "0.34.0", + "private": true, "description": "Example of using @opentelemetry/sdk-metrics and @opentelemetry/exporter-prometheus", "main": "index.js", "scripts": { @@ -9,8 +10,8 @@ "author": "OpenTelemetry Authors", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/api": "^1.2.0", - "@opentelemetry/exporter-prometheus": "0.33.0", - "@opentelemetry/sdk-metrics": "0.33.0" + "@opentelemetry/api": "^1.3.0", + "@opentelemetry/exporter-prometheus": "0.34.0", + "@opentelemetry/sdk-metrics": "1.8.0" } } diff --git a/experimental/packages/api-logs/package.json b/experimental/packages/api-logs/package.json index fe0a0cb73e..952a107fcb 100644 --- a/experimental/packages/api-logs/package.json +++ b/experimental/packages/api-logs/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/api-logs", - "version": "0.33.0", + "version": "0.34.0", "description": "Public logs API for OpenTelemetry", "main": "build/src/index.js", "module": "build/esm/index.js", diff --git a/experimental/packages/exporter-trace-otlp-grpc/package.json b/experimental/packages/exporter-trace-otlp-grpc/package.json index 05ba15892c..4b7b41c973 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/package.json +++ b/experimental/packages/exporter-trace-otlp-grpc/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-trace-otlp-grpc", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry Collector Exporter allows user to send collected traces to the OpenTelemetry Collector", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -50,7 +50,7 @@ "@babel/core": "7.16.0", "@grpc/proto-loader": "^0.7.3", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/otlp-exporter-base": "0.33.0", + "@opentelemetry/otlp-exporter-base": "0.34.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -69,11 +69,11 @@ }, "dependencies": { "@grpc/grpc-js": "^1.7.1", - "@opentelemetry/core": "1.7.0", - "@opentelemetry/otlp-grpc-exporter-base": "0.33.0", - "@opentelemetry/otlp-transformer": "0.33.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.34.0", + "@opentelemetry/otlp-transformer": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-grpc", "sideEffects": false diff --git a/experimental/packages/exporter-trace-otlp-http/package.json b/experimental/packages/exporter-trace-otlp-http/package.json index 3883b148fb..bd17747f7f 100644 --- a/experimental/packages/exporter-trace-otlp-http/package.json +++ b/experimental/packages/exporter-trace-otlp-http/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-trace-otlp-http", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry Collector Trace Exporter allows user to send collected traces to the OpenTelemetry Collector", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -94,11 +94,11 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/otlp-exporter-base": "0.33.0", - "@opentelemetry/otlp-transformer": "0.33.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/otlp-exporter-base": "0.34.0", + "@opentelemetry/otlp-transformer": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-http", "sideEffects": false diff --git a/experimental/packages/exporter-trace-otlp-proto/package.json b/experimental/packages/exporter-trace-otlp-proto/package.json index b9a6927640..1a44e0ea66 100644 --- a/experimental/packages/exporter-trace-otlp-proto/package.json +++ b/experimental/packages/exporter-trace-otlp-proto/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-trace-otlp-proto", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry Collector Exporter allows user to send collected traces to the OpenTelemetry Collector using protobuf over HTTP", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -66,12 +66,12 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/otlp-exporter-base": "0.33.0", - "@opentelemetry/otlp-proto-exporter-base": "0.33.0", - "@opentelemetry/otlp-transformer": "0.33.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/otlp-exporter-base": "0.34.0", + "@opentelemetry/otlp-proto-exporter-base": "0.34.0", + "@opentelemetry/otlp-transformer": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-proto", "sideEffects": false diff --git a/experimental/packages/opentelemetry-browser-detector/package.json b/experimental/packages/opentelemetry-browser-detector/package.json index 6fef4a3c9e..9af38cea26 100644 --- a/experimental/packages/opentelemetry-browser-detector/package.json +++ b/experimental/packages/opentelemetry-browser-detector/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/opentelemetry-browser-detector", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry Resource Detector for Browser", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -70,8 +70,8 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/browser-detector" } diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json index e44641b004..c56fa61892 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-metrics-otlp-grpc", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry Collector Metrics Exporter allows user to send collected metrics to the OpenTelemetry Collector", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -49,7 +49,7 @@ "devDependencies": { "@babel/core": "7.16.0", "@grpc/proto-loader": "^0.7.3", - "@opentelemetry/api": "^1.2.0", + "@opentelemetry/api": "^1.3.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -64,16 +64,16 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.2.0" + "@opentelemetry/api": "^1.3.0" }, "dependencies": { "@grpc/grpc-js": "^1.7.1", - "@opentelemetry/core": "1.7.0", - "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", - "@opentelemetry/otlp-grpc-exporter-base": "0.33.0", - "@opentelemetry/otlp-transformer": "0.33.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.34.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.34.0", + "@opentelemetry/otlp-transformer": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-metrics": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc", "sideEffects": false diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json index d866e532c2..2ba3d74b8b 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/tsconfig.json @@ -19,10 +19,10 @@ "path": "../../../packages/opentelemetry-resources" }, { - "path": "../opentelemetry-exporter-metrics-otlp-http" + "path": "../../../packages/sdk-metrics" }, { - "path": "../opentelemetry-sdk-metrics" + "path": "../opentelemetry-exporter-metrics-otlp-http" }, { "path": "../otlp-grpc-exporter-base" diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json index 4b21d78f8f..e17aa4f5e9 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-metrics-otlp-http", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry Collector Metrics Exporter allows user to send collected metrics to the OpenTelemetry Collector", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -64,7 +64,7 @@ }, "devDependencies": { "@babel/core": "7.16.0", - "@opentelemetry/api": "^1.2.0", + "@opentelemetry/api": "^1.3.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -91,14 +91,14 @@ "webpack-merge": "5.8.0" }, "peerDependencies": { - "@opentelemetry/api": "^1.2.0" + "@opentelemetry/api": "^1.3.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/otlp-exporter-base": "0.33.0", - "@opentelemetry/otlp-transformer": "0.33.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/otlp-exporter-base": "0.34.0", + "@opentelemetry/otlp-transformer": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-metrics": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-http", "sideEffects": false diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json index af647ba8e3..7ae0cb4939 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-http/tsconfig.json @@ -19,7 +19,7 @@ "path": "../../../packages/opentelemetry-resources" }, { - "path": "../opentelemetry-sdk-metrics" + "path": "../../../packages/sdk-metrics" }, { "path": "../otlp-exporter-base" diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json index bd21a3c040..4305efa91f 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-metrics-otlp-proto", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry Collector Metrics Exporter allows user to send collected metrics to the OpenTelemetry Collector using protobuf over HTTP", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -48,7 +48,7 @@ }, "devDependencies": { "@babel/core": "7.16.0", - "@opentelemetry/api": "^1.2.0", + "@opentelemetry/api": "^1.3.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -63,16 +63,16 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.2.0" + "@opentelemetry/api": "^1.3.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", - "@opentelemetry/otlp-exporter-base": "0.33.0", - "@opentelemetry/otlp-proto-exporter-base": "0.33.0", - "@opentelemetry/otlp-transformer": "0.33.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.34.0", + "@opentelemetry/otlp-exporter-base": "0.34.0", + "@opentelemetry/otlp-proto-exporter-base": "0.34.0", + "@opentelemetry/otlp-transformer": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-metrics": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-proto", "sideEffects": false diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json index 521fc31cfe..1539111d42 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/tsconfig.json @@ -19,10 +19,10 @@ "path": "../../../packages/opentelemetry-resources" }, { - "path": "../opentelemetry-exporter-metrics-otlp-http" + "path": "../../../packages/sdk-metrics" }, { - "path": "../opentelemetry-sdk-metrics" + "path": "../opentelemetry-exporter-metrics-otlp-http" }, { "path": "../otlp-exporter-base" diff --git a/experimental/packages/opentelemetry-exporter-prometheus/package.json b/experimental/packages/opentelemetry-exporter-prometheus/package.json index 9461ac2bca..8d6c32a868 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/package.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-prometheus", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry Exporter Prometheus provides a metrics endpoint for Prometheus", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -43,7 +43,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": "^1.2.0", + "@opentelemetry/api": "^1.3.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -56,12 +56,12 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.2.0" + "@opentelemetry/api": "^1.3.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0", - "@opentelemetry/resources": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/sdk-metrics": "1.8.0", + "@opentelemetry/resources": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-prometheus", "sideEffects": false diff --git a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json index 719097c712..f0e9f90992 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json @@ -19,7 +19,7 @@ "path": "../../../packages/opentelemetry-resources" }, { - "path": "../opentelemetry-sdk-metrics" + "path": "../../../packages/sdk-metrics" } ] } diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/package.json b/experimental/packages/opentelemetry-instrumentation-fetch/package.json index 3e7e3336fc..cebc08ada0 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/package.json +++ b/experimental/packages/opentelemetry-instrumentation-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-fetch", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry fetch automatic instrumentation package.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -56,9 +56,9 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/context-zone": "1.7.0", - "@opentelemetry/propagator-b3": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/context-zone": "1.8.0", + "@opentelemetry/propagator-b3": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -87,10 +87,10 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/instrumentation": "0.33.0", - "@opentelemetry/sdk-trace-web": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/instrumentation": "0.34.0", + "@opentelemetry/sdk-trace-web": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-fetch", "sideEffects": false diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/package.json b/experimental/packages/opentelemetry-instrumentation-grpc/package.json index 09f8ab2aff..ec8781464d 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/package.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-grpc", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry grpc automatic instrumentation package.", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -47,11 +47,11 @@ "devDependencies": { "@grpc/grpc-js": "^1.7.1", "@grpc/proto-loader": "^0.7.3", - "@opentelemetry/api": "^1.2.0", - "@opentelemetry/context-async-hooks": "1.7.0", - "@opentelemetry/core": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/sdk-trace-node": "1.7.0", + "@opentelemetry/api": "^1.3.0", + "@opentelemetry/context-async-hooks": "1.8.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/sdk-trace-node": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/semver": "7.3.9", @@ -68,11 +68,11 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.2.0" + "@opentelemetry/api": "^1.3.0" }, "dependencies": { - "@opentelemetry/instrumentation": "0.33.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/instrumentation": "0.34.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-grpc", "sideEffects": false diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index dc20ae09c4..b62aafe8c4 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-http", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry http/https automatic instrumentation package.", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -45,11 +45,11 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": "^1.2.0", - "@opentelemetry/context-async-hooks": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/sdk-trace-node": "1.7.0", + "@opentelemetry/api": "^1.3.0", + "@opentelemetry/context-async-hooks": "1.8.0", + "@opentelemetry/sdk-metrics": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/sdk-trace-node": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/request-promise-native": "1.0.18", @@ -70,12 +70,12 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": "^1.2.0" + "@opentelemetry/api": "^1.3.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/instrumentation": "0.33.0", - "@opentelemetry/semantic-conventions": "1.7.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/instrumentation": "0.34.0", + "@opentelemetry/semantic-conventions": "1.8.0", "semver": "^7.3.5" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http", diff --git a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json index 00267e9c1a..ca127b85dc 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json @@ -28,10 +28,10 @@ "path": "../../../packages/opentelemetry-semantic-conventions" }, { - "path": "../opentelemetry-instrumentation" + "path": "../../../packages/sdk-metrics" }, { - "path": "../opentelemetry-sdk-metrics" + "path": "../opentelemetry-instrumentation" } ] } diff --git a/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json b/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json index 40b340b5cd..1f1b480ecc 100644 --- a/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json +++ b/experimental/packages/opentelemetry-instrumentation-xml-http-request/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-xml-http-request", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry XMLHttpRequest automatic instrumentation package.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -56,9 +56,9 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/context-zone": "1.7.0", - "@opentelemetry/propagator-b3": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/context-zone": "1.8.0", + "@opentelemetry/propagator-b3": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -87,10 +87,10 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/instrumentation": "0.33.0", - "@opentelemetry/sdk-trace-web": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/instrumentation": "0.34.0", + "@opentelemetry/sdk-trace-web": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-xml-http-request", "sideEffects": false diff --git a/experimental/packages/opentelemetry-instrumentation/package.json b/experimental/packages/opentelemetry-instrumentation/package.json index 96437b278b..29b186d510 100644 --- a/experimental/packages/opentelemetry-instrumentation/package.json +++ b/experimental/packages/opentelemetry-instrumentation/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation", - "version": "0.33.0", + "version": "0.34.0", "description": "Base class for node which OpenTelemetry instrumentation modules extend", "author": "OpenTelemetry Authors", "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation", @@ -73,11 +73,11 @@ "shimmer": "^1.2.1" }, "peerDependencies": { - "@opentelemetry/api": "^1.2.0" + "@opentelemetry/api": "^1.3.0" }, "devDependencies": { "@babel/core": "7.16.0", - "@opentelemetry/api": "^1.2.0", + "@opentelemetry/api": "^1.3.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/semver": "7.3.9", diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index 30d559fc65..e37dc098c7 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-node", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry SDK for Node.js", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -44,25 +44,25 @@ "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/core": "1.7.0", - "@opentelemetry/instrumentation": "0.33.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/sdk-trace-node": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/exporter-jaeger": "1.8.0", + "@opentelemetry/exporter-trace-otlp-grpc": "0.34.0", + "@opentelemetry/exporter-trace-otlp-http": "0.34.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.34.0", + "@opentelemetry/exporter-zipkin": "1.8.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/instrumentation": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-metrics": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/sdk-trace-node": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.2.0 <1.3.0" + "@opentelemetry/api": ">=1.3.0 <1.4.0" }, "devDependencies": { - "@opentelemetry/api": ">=1.2.0 <1.3.0", - "@opentelemetry/context-async-hooks": "1.7.0", + "@opentelemetry/api": ">=1.3.0 <1.4.0", + "@opentelemetry/context-async-hooks": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/semver": "7.3.9", diff --git a/experimental/packages/opentelemetry-sdk-node/tsconfig.json b/experimental/packages/opentelemetry-sdk-node/tsconfig.json index 20eb8eace7..3b5a3efd79 100644 --- a/experimental/packages/opentelemetry-sdk-node/tsconfig.json +++ b/experimental/packages/opentelemetry-sdk-node/tsconfig.json @@ -36,6 +36,9 @@ { "path": "../../../packages/opentelemetry-semantic-conventions" }, + { + "path": "../../../packages/sdk-metrics" + }, { "path": "../exporter-trace-otlp-grpc" }, @@ -47,9 +50,6 @@ }, { "path": "../opentelemetry-instrumentation" - }, - { - "path": "../opentelemetry-sdk-metrics" } ] } diff --git a/experimental/packages/otlp-exporter-base/package.json b/experimental/packages/otlp-exporter-base/package.json index 0d6eadfb0b..712a269d62 100644 --- a/experimental/packages/otlp-exporter-base/package.json +++ b/experimental/packages/otlp-exporter-base/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/otlp-exporter-base", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry OTLP Exporter base (for internal use only)", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -61,7 +61,7 @@ "access": "public" }, "dependencies": { - "@opentelemetry/core": "1.7.0" + "@opentelemetry/core": "1.8.0" }, "devDependencies": { "@opentelemetry/api": "^1.0.0", diff --git a/experimental/packages/otlp-grpc-exporter-base/package.json b/experimental/packages/otlp-grpc-exporter-base/package.json index b164cec8dd..e90632e22c 100644 --- a/experimental/packages/otlp-grpc-exporter-base/package.json +++ b/experimental/packages/otlp-grpc-exporter-base/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/otlp-grpc-exporter-base", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry OTLP-gRPC Exporter base (for internal use only)", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -51,9 +51,9 @@ "devDependencies": { "@babel/core": "7.16.0", "@opentelemetry/api": "^1.0.0", - "@opentelemetry/otlp-transformer": "0.33.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/otlp-transformer": "0.34.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -73,8 +73,8 @@ "dependencies": { "@grpc/grpc-js": "^1.7.1", "@grpc/proto-loader": "^0.7.3", - "@opentelemetry/core": "1.7.0", - "@opentelemetry/otlp-exporter-base": "0.33.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/otlp-exporter-base": "0.34.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-grpc-exporter-base", "sideEffects": false diff --git a/experimental/packages/otlp-proto-exporter-base/package.json b/experimental/packages/otlp-proto-exporter-base/package.json index aaec196080..71653bd0d6 100644 --- a/experimental/packages/otlp-proto-exporter-base/package.json +++ b/experimental/packages/otlp-proto-exporter-base/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/otlp-proto-exporter-base", - "version": "0.33.0", + "version": "0.34.0", "description": "OpenTelemetry OTLP-HTTP-protobuf Exporter base (for internal use only)", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -63,8 +63,8 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/otlp-exporter-base": "0.33.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/otlp-exporter-base": "0.34.0", "protobufjs": "7.1.1" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-proto-exporter-base", diff --git a/experimental/packages/otlp-transformer/package.json b/experimental/packages/otlp-transformer/package.json index 8a5adedb64..4d0f59f88e 100644 --- a/experimental/packages/otlp-transformer/package.json +++ b/experimental/packages/otlp-transformer/package.json @@ -4,7 +4,7 @@ "publishConfig": { "access": "public" }, - "version": "0.33.0", + "version": "0.34.0", "description": "Transform OpenTelemetry SDK data into OTLP", "module": "build/esm/index.js", "esnext": "build/esnext/index.js", @@ -52,10 +52,10 @@ "README.md" ], "peerDependencies": { - "@opentelemetry/api": ">=1.2.0 <1.3.0" + "@opentelemetry/api": ">=1.3.0 <1.4.0" }, "devDependencies": { - "@opentelemetry/api": ">=1.2.0 <1.3.0", + "@opentelemetry/api": ">=1.3.0 <1.4.0", "@types/mocha": "10.0.0", "@types/webpack-env": "1.16.3", "codecov": "3.8.3", @@ -76,10 +76,10 @@ "webpack": "4.46.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-metrics": "0.33.0", - "@opentelemetry/sdk-trace-base": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-metrics": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/otlp-transformer", "sideEffects": false diff --git a/experimental/packages/otlp-transformer/tsconfig.json b/experimental/packages/otlp-transformer/tsconfig.json index 11ace43aeb..cbcb2b9bc6 100644 --- a/experimental/packages/otlp-transformer/tsconfig.json +++ b/experimental/packages/otlp-transformer/tsconfig.json @@ -22,7 +22,7 @@ "path": "../../../packages/opentelemetry-sdk-trace-base" }, { - "path": "../opentelemetry-sdk-metrics" + "path": "../../../packages/sdk-metrics" } ] } diff --git a/integration-tests/propagation-validation-server/package.json b/integration-tests/propagation-validation-server/package.json index ef4919d2d4..78383d4673 100644 --- a/integration-tests/propagation-validation-server/package.json +++ b/integration-tests/propagation-validation-server/package.json @@ -1,6 +1,6 @@ { "name": "propagation-validation-server", - "version": "1.7.0", + "version": "1.8.0", "description": "server for w3c tests", "main": "validation_server.js", "private": true, @@ -12,9 +12,9 @@ }, "dependencies": { "@opentelemetry/api": "^1.0.0", - "@opentelemetry/context-async-hooks": "1.7.0", - "@opentelemetry/core": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/context-async-hooks": "1.8.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", "axios": "0.24.0", "body-parser": "1.19.0", "express": "4.17.1" diff --git a/packages/opentelemetry-context-async-hooks/package.json b/packages/opentelemetry-context-async-hooks/package.json index 07c85471a0..cf1dc3636e 100644 --- a/packages/opentelemetry-context-async-hooks/package.json +++ b/packages/opentelemetry-context-async-hooks/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/context-async-hooks", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry AsyncHooks-based Context Manager", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -44,7 +44,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "codecov": "3.8.3", @@ -55,7 +55,7 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.0.0 <1.4.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-context-async-hooks", "sideEffects": false diff --git a/packages/opentelemetry-context-zone-peer-dep/package.json b/packages/opentelemetry-context-zone-peer-dep/package.json index 550f3adc63..153d158d37 100644 --- a/packages/opentelemetry-context-zone-peer-dep/package.json +++ b/packages/opentelemetry-context-zone-peer-dep/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/context-zone-peer-dep", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry Context Zone with peer dependency for zone.js", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -54,7 +54,7 @@ }, "devDependencies": { "@babel/core": "7.16.0", - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -81,7 +81,7 @@ "zone.js": "0.11.4" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", "zone.js": "^0.10.2 || ^0.11.0" }, "sideEffects": false, diff --git a/packages/opentelemetry-context-zone/package.json b/packages/opentelemetry-context-zone/package.json index acfe75bec9..14f36b16fb 100644 --- a/packages/opentelemetry-context-zone/package.json +++ b/packages/opentelemetry-context-zone/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/context-zone", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry Context Zone", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -74,7 +74,7 @@ "webpack-merge": "5.8.0" }, "dependencies": { - "@opentelemetry/context-zone-peer-dep": "1.7.0", + "@opentelemetry/context-zone-peer-dep": "1.8.0", "zone.js": "^0.11.0" }, "sideEffects": true, diff --git a/packages/opentelemetry-core/package.json b/packages/opentelemetry-core/package.json index 8334561f5b..7803c09beb 100644 --- a/packages/opentelemetry-core/package.json +++ b/packages/opentelemetry-core/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/core", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry Core provides constants and utilities shared by all OpenTelemetry SDK packages.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -64,7 +64,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -88,10 +88,10 @@ "webpack": "4.46.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.0.0 <1.4.0" }, "dependencies": { - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-core", "sideEffects": false diff --git a/packages/opentelemetry-exporter-jaeger/package.json b/packages/opentelemetry-exporter-jaeger/package.json index 0578ba2643..38371fcf76 100644 --- a/packages/opentelemetry-exporter-jaeger/package.json +++ b/packages/opentelemetry-exporter-jaeger/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-jaeger", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry Exporter Jaeger allows user to send collected traces to Jaeger", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -45,7 +45,7 @@ }, "devDependencies": { "@opentelemetry/api": "^1.0.0", - "@opentelemetry/resources": "1.7.0", + "@opentelemetry/resources": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -62,9 +62,9 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0", "jaeger-client": "^3.15.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-exporter-jaeger", diff --git a/packages/opentelemetry-exporter-zipkin/package.json b/packages/opentelemetry-exporter-zipkin/package.json index fbed197c0d..7d56b47a1b 100644 --- a/packages/opentelemetry-exporter-zipkin/package.json +++ b/packages/opentelemetry-exporter-zipkin/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/exporter-zipkin", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry Zipkin Exporter allows the user to send collected traces to Zipkin.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -91,10 +91,10 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-exporter-zipkin", "sideEffects": false diff --git a/packages/opentelemetry-propagator-b3/package.json b/packages/opentelemetry-propagator-b3/package.json index a54d56e95e..dd2ab2756e 100644 --- a/packages/opentelemetry-propagator-b3/package.json +++ b/packages/opentelemetry-propagator-b3/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/propagator-b3", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry B3 propagator provides context propagation for systems that are using the B3 header format", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -51,13 +51,13 @@ "access": "public" }, "dependencies": { - "@opentelemetry/core": "1.7.0" + "@opentelemetry/core": "1.8.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.0.0 <1.4.0" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "codecov": "3.8.3", diff --git a/packages/opentelemetry-propagator-jaeger/package.json b/packages/opentelemetry-propagator-jaeger/package.json index 98aba129a6..e44d3c77f7 100644 --- a/packages/opentelemetry-propagator-jaeger/package.json +++ b/packages/opentelemetry-propagator-jaeger/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/propagator-jaeger", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry Jaeger propagator provides HTTP header propagation for systems that are using Jaeger HTTP header format.", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -54,7 +54,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -77,10 +77,10 @@ "webpack": "4.46.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.0.0 <1.4.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0" + "@opentelemetry/core": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-jaeger", "sideEffects": false diff --git a/packages/opentelemetry-resources/package.json b/packages/opentelemetry-resources/package.json index 84cb29a7af..a65084826c 100644 --- a/packages/opentelemetry-resources/package.json +++ b/packages/opentelemetry-resources/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/resources", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry SDK resources", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -61,7 +61,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -86,11 +86,11 @@ "webpack-merge": "5.8.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.0.0 <1.4.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-resources", "sideEffects": false diff --git a/packages/opentelemetry-sdk-trace-base/package.json b/packages/opentelemetry-sdk-trace-base/package.json index a062b9c4d7..4d8d98cf3d 100644 --- a/packages/opentelemetry-sdk-trace-base/package.json +++ b/packages/opentelemetry-sdk-trace-base/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-trace-base", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry Tracing", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -64,7 +64,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", @@ -88,12 +88,12 @@ "webpack": "4.46.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.0.0 <1.4.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-base", "sideEffects": false diff --git a/packages/opentelemetry-sdk-trace-node/package.json b/packages/opentelemetry-sdk-trace-node/package.json index cbf5bd9e37..4889fab422 100644 --- a/packages/opentelemetry-sdk-trace-node/package.json +++ b/packages/opentelemetry-sdk-trace-node/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-trace-node", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry Node SDK provides automatic telemetry (tracing, metrics, etc) for Node.js applications", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -45,9 +45,9 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@opentelemetry/resources": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", + "@opentelemetry/resources": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/semver": "7.3.9", @@ -61,14 +61,14 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.0.0 <1.4.0" }, "dependencies": { - "@opentelemetry/context-async-hooks": "1.7.0", - "@opentelemetry/core": "1.7.0", - "@opentelemetry/propagator-b3": "1.7.0", - "@opentelemetry/propagator-jaeger": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/context-async-hooks": "1.8.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/propagator-b3": "1.8.0", + "@opentelemetry/propagator-jaeger": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", "semver": "^7.3.5" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node", diff --git a/packages/opentelemetry-sdk-trace-web/package.json b/packages/opentelemetry-sdk-trace-web/package.json index 65afa52b30..70f3c21256 100644 --- a/packages/opentelemetry-sdk-trace-web/package.json +++ b/packages/opentelemetry-sdk-trace-web/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-trace-web", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry Web Tracer", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -56,10 +56,10 @@ }, "devDependencies": { "@babel/core": "7.16.0", - "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@opentelemetry/context-zone": "1.7.0", - "@opentelemetry/propagator-b3": "1.7.0", - "@opentelemetry/resources": "1.7.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", + "@opentelemetry/context-zone": "1.8.0", + "@opentelemetry/propagator-b3": "1.8.0", + "@opentelemetry/resources": "1.8.0", "@types/jquery": "3.5.8", "@types/mocha": "10.0.0", "@types/node": "18.6.5", @@ -88,12 +88,12 @@ "webpack-merge": "5.8.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.0.0 <1.4.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0" + "@opentelemetry/core": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web", "sideEffects": false diff --git a/packages/opentelemetry-semantic-conventions/package.json b/packages/opentelemetry-semantic-conventions/package.json index c7cbcc040b..a801f2b02e 100644 --- a/packages/opentelemetry-semantic-conventions/package.json +++ b/packages/opentelemetry-semantic-conventions/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/semantic-conventions", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTelemetry semantic conventions", "main": "build/src/index.js", "module": "build/esm/index.js", diff --git a/packages/opentelemetry-shim-opentracing/package.json b/packages/opentelemetry-shim-opentracing/package.json index f73fb08774..f60f9e9e35 100644 --- a/packages/opentelemetry-shim-opentracing/package.json +++ b/packages/opentelemetry-shim-opentracing/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/shim-opentracing", - "version": "1.7.0", + "version": "1.8.0", "description": "OpenTracing to OpenTelemetry shim", "main": "build/src/index.js", "types": "build/src/index.d.ts", @@ -42,10 +42,10 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0", - "@opentelemetry/propagator-b3": "1.7.0", - "@opentelemetry/propagator-jaeger": "1.7.0", - "@opentelemetry/sdk-trace-base": "1.7.0", + "@opentelemetry/api": ">=1.0.0 <1.4.0", + "@opentelemetry/propagator-b3": "1.8.0", + "@opentelemetry/propagator-jaeger": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "codecov": "3.8.3", @@ -56,11 +56,11 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.3.0" + "@opentelemetry/api": ">=1.0.0 <1.4.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/semantic-conventions": "1.7.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/semantic-conventions": "1.8.0", "opentracing": "^0.14.4" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-shim-opentracing", diff --git a/experimental/packages/opentelemetry-sdk-metrics/.eslintignore b/packages/sdk-metrics/.eslintignore similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/.eslintignore rename to packages/sdk-metrics/.eslintignore diff --git a/experimental/packages/opentelemetry-sdk-metrics/.eslintrc.js b/packages/sdk-metrics/.eslintrc.js similarity index 65% rename from experimental/packages/opentelemetry-sdk-metrics/.eslintrc.js rename to packages/sdk-metrics/.eslintrc.js index f756f4488b..f726f3becb 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/.eslintrc.js +++ b/packages/sdk-metrics/.eslintrc.js @@ -3,5 +3,5 @@ module.exports = { "mocha": true, "node": true }, - ...require('../../../eslint.config.js') + ...require('../../eslint.config.js') } diff --git a/experimental/packages/opentelemetry-sdk-metrics/.npmignore b/packages/sdk-metrics/.npmignore similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/.npmignore rename to packages/sdk-metrics/.npmignore diff --git a/experimental/packages/opentelemetry-sdk-metrics/LICENSE b/packages/sdk-metrics/LICENSE similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/LICENSE rename to packages/sdk-metrics/LICENSE diff --git a/experimental/packages/opentelemetry-sdk-metrics/README.md b/packages/sdk-metrics/README.md similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/README.md rename to packages/sdk-metrics/README.md diff --git a/experimental/packages/opentelemetry-sdk-metrics/karma.conf.js b/packages/sdk-metrics/karma.conf.js similarity index 86% rename from experimental/packages/opentelemetry-sdk-metrics/karma.conf.js rename to packages/sdk-metrics/karma.conf.js index 6174839d65..3019564a15 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/karma.conf.js +++ b/packages/sdk-metrics/karma.conf.js @@ -14,8 +14,8 @@ * limitations under the License. */ -const karmaWebpackConfig = require('../../../karma.webpack'); -const karmaBaseConfig = require('../../../karma.base'); +const karmaWebpackConfig = require('../../karma.webpack'); +const karmaBaseConfig = require('../../karma.base'); module.exports = (config) => { config.set(Object.assign({}, karmaBaseConfig, { diff --git a/experimental/packages/opentelemetry-sdk-metrics/package.json b/packages/sdk-metrics/package.json similarity index 85% rename from experimental/packages/opentelemetry-sdk-metrics/package.json rename to packages/sdk-metrics/package.json index dcd526d57f..f1c9e29474 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/package.json +++ b/packages/sdk-metrics/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-metrics", - "version": "0.33.0", + "version": "1.8.0", "description": "Work in progress OpenTelemetry metrics SDK", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -15,14 +15,14 @@ "test:browser": "nyc karma start --single-run", "tdd": "npm run test -- --watch-extensions ts --watch", "tdd:browser": "karma start", - "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../../", + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", - "version": "node ../../../scripts/version-update.js", + "version": "node ../../scripts/version-update.js", "watch": "tsc --build --watch tsconfig.all.json", "precompile": "lerna run version --scope $(npm pkg get name) --include-dependencies", - "prewatch": "node ../../../scripts/version-update.js", - "peer-api-check": "node ../../../scripts/peer-api-check.js" + "prewatch": "node ../../scripts/version-update.js", + "peer-api-check": "node ../../scripts/peer-api-check.js" }, "keywords": [ "opentelemetry", @@ -54,7 +54,7 @@ "access": "public" }, "devDependencies": { - "@opentelemetry/api": ">=1.2.0 <1.3.0", + "@opentelemetry/api": ">=1.3.0 <1.4.0", "@types/lodash.merge": "4.6.6", "@types/mocha": "10.0.0", "@types/node": "18.6.5", @@ -74,11 +74,11 @@ "typescript": "4.4.4" }, "peerDependencies": { - "@opentelemetry/api": ">=1.2.0 <1.3.0" + "@opentelemetry/api": ">=1.3.0 <1.4.0" }, "dependencies": { - "@opentelemetry/core": "1.7.0", - "@opentelemetry/resources": "1.7.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/resources": "1.8.0", "lodash.merge": "4.6.2" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-metrics", diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/InstrumentDescriptor.ts b/packages/sdk-metrics/src/InstrumentDescriptor.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/InstrumentDescriptor.ts rename to packages/sdk-metrics/src/InstrumentDescriptor.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/Instruments.ts b/packages/sdk-metrics/src/Instruments.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/Instruments.ts rename to packages/sdk-metrics/src/Instruments.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/Meter.ts b/packages/sdk-metrics/src/Meter.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/Meter.ts rename to packages/sdk-metrics/src/Meter.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts b/packages/sdk-metrics/src/MeterProvider.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/MeterProvider.ts rename to packages/sdk-metrics/src/MeterProvider.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/ObservableResult.ts b/packages/sdk-metrics/src/ObservableResult.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/ObservableResult.ts rename to packages/sdk-metrics/src/ObservableResult.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/Drop.ts b/packages/sdk-metrics/src/aggregator/Drop.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/aggregator/Drop.ts rename to packages/sdk-metrics/src/aggregator/Drop.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/Histogram.ts b/packages/sdk-metrics/src/aggregator/Histogram.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/aggregator/Histogram.ts rename to packages/sdk-metrics/src/aggregator/Histogram.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/LastValue.ts b/packages/sdk-metrics/src/aggregator/LastValue.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/aggregator/LastValue.ts rename to packages/sdk-metrics/src/aggregator/LastValue.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/Sum.ts b/packages/sdk-metrics/src/aggregator/Sum.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/aggregator/Sum.ts rename to packages/sdk-metrics/src/aggregator/Sum.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/index.ts b/packages/sdk-metrics/src/aggregator/index.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/aggregator/index.ts rename to packages/sdk-metrics/src/aggregator/index.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts b/packages/sdk-metrics/src/aggregator/types.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/aggregator/types.ts rename to packages/sdk-metrics/src/aggregator/types.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlignedHistogramBucketExemplarReservoir.ts b/packages/sdk-metrics/src/exemplar/AlignedHistogramBucketExemplarReservoir.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlignedHistogramBucketExemplarReservoir.ts rename to packages/sdk-metrics/src/exemplar/AlignedHistogramBucketExemplarReservoir.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlwaysSampleExemplarFilter.ts b/packages/sdk-metrics/src/exemplar/AlwaysSampleExemplarFilter.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/exemplar/AlwaysSampleExemplarFilter.ts rename to packages/sdk-metrics/src/exemplar/AlwaysSampleExemplarFilter.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/Exemplar.ts b/packages/sdk-metrics/src/exemplar/Exemplar.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/exemplar/Exemplar.ts rename to packages/sdk-metrics/src/exemplar/Exemplar.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts b/packages/sdk-metrics/src/exemplar/ExemplarFilter.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarFilter.ts rename to packages/sdk-metrics/src/exemplar/ExemplarFilter.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarReservoir.ts b/packages/sdk-metrics/src/exemplar/ExemplarReservoir.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/exemplar/ExemplarReservoir.ts rename to packages/sdk-metrics/src/exemplar/ExemplarReservoir.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/NeverSampleExemplarFilter.ts b/packages/sdk-metrics/src/exemplar/NeverSampleExemplarFilter.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/exemplar/NeverSampleExemplarFilter.ts rename to packages/sdk-metrics/src/exemplar/NeverSampleExemplarFilter.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/SimpleFixedSizeExemplarReservoir.ts b/packages/sdk-metrics/src/exemplar/SimpleFixedSizeExemplarReservoir.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/exemplar/SimpleFixedSizeExemplarReservoir.ts rename to packages/sdk-metrics/src/exemplar/SimpleFixedSizeExemplarReservoir.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/WithTraceExemplarFilter.ts b/packages/sdk-metrics/src/exemplar/WithTraceExemplarFilter.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/exemplar/WithTraceExemplarFilter.ts rename to packages/sdk-metrics/src/exemplar/WithTraceExemplarFilter.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/exemplar/index.ts b/packages/sdk-metrics/src/exemplar/index.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/exemplar/index.ts rename to packages/sdk-metrics/src/exemplar/index.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts b/packages/sdk-metrics/src/export/AggregationSelector.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationSelector.ts rename to packages/sdk-metrics/src/export/AggregationSelector.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationTemporality.ts b/packages/sdk-metrics/src/export/AggregationTemporality.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/export/AggregationTemporality.ts rename to packages/sdk-metrics/src/export/AggregationTemporality.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/ConsoleMetricExporter.ts b/packages/sdk-metrics/src/export/ConsoleMetricExporter.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/export/ConsoleMetricExporter.ts rename to packages/sdk-metrics/src/export/ConsoleMetricExporter.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/InMemoryMetricExporter.ts b/packages/sdk-metrics/src/export/InMemoryMetricExporter.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/export/InMemoryMetricExporter.ts rename to packages/sdk-metrics/src/export/InMemoryMetricExporter.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts b/packages/sdk-metrics/src/export/MetricData.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/export/MetricData.ts rename to packages/sdk-metrics/src/export/MetricData.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts b/packages/sdk-metrics/src/export/MetricExporter.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/export/MetricExporter.ts rename to packages/sdk-metrics/src/export/MetricExporter.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricProducer.ts b/packages/sdk-metrics/src/export/MetricProducer.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/export/MetricProducer.ts rename to packages/sdk-metrics/src/export/MetricProducer.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts b/packages/sdk-metrics/src/export/MetricReader.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/export/MetricReader.ts rename to packages/sdk-metrics/src/export/MetricReader.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts b/packages/sdk-metrics/src/export/PeriodicExportingMetricReader.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/export/PeriodicExportingMetricReader.ts rename to packages/sdk-metrics/src/export/PeriodicExportingMetricReader.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/index.ts b/packages/sdk-metrics/src/index.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/index.ts rename to packages/sdk-metrics/src/index.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/AsyncMetricStorage.ts b/packages/sdk-metrics/src/state/AsyncMetricStorage.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/AsyncMetricStorage.ts rename to packages/sdk-metrics/src/state/AsyncMetricStorage.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/DeltaMetricProcessor.ts b/packages/sdk-metrics/src/state/DeltaMetricProcessor.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/DeltaMetricProcessor.ts rename to packages/sdk-metrics/src/state/DeltaMetricProcessor.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/HashMap.ts b/packages/sdk-metrics/src/state/HashMap.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/HashMap.ts rename to packages/sdk-metrics/src/state/HashMap.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterProviderSharedState.ts b/packages/sdk-metrics/src/state/MeterProviderSharedState.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/MeterProviderSharedState.ts rename to packages/sdk-metrics/src/state/MeterProviderSharedState.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts b/packages/sdk-metrics/src/state/MeterSharedState.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/MeterSharedState.ts rename to packages/sdk-metrics/src/state/MeterSharedState.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricCollector.ts b/packages/sdk-metrics/src/state/MetricCollector.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/MetricCollector.ts rename to packages/sdk-metrics/src/state/MetricCollector.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorage.ts b/packages/sdk-metrics/src/state/MetricStorage.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorage.ts rename to packages/sdk-metrics/src/state/MetricStorage.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorageRegistry.ts b/packages/sdk-metrics/src/state/MetricStorageRegistry.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/MetricStorageRegistry.ts rename to packages/sdk-metrics/src/state/MetricStorageRegistry.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/MultiWritableMetricStorage.ts b/packages/sdk-metrics/src/state/MultiWritableMetricStorage.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/MultiWritableMetricStorage.ts rename to packages/sdk-metrics/src/state/MultiWritableMetricStorage.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/ObservableRegistry.ts b/packages/sdk-metrics/src/state/ObservableRegistry.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/ObservableRegistry.ts rename to packages/sdk-metrics/src/state/ObservableRegistry.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/SyncMetricStorage.ts b/packages/sdk-metrics/src/state/SyncMetricStorage.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/SyncMetricStorage.ts rename to packages/sdk-metrics/src/state/SyncMetricStorage.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/TemporalMetricProcessor.ts b/packages/sdk-metrics/src/state/TemporalMetricProcessor.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/TemporalMetricProcessor.ts rename to packages/sdk-metrics/src/state/TemporalMetricProcessor.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/state/WritableMetricStorage.ts b/packages/sdk-metrics/src/state/WritableMetricStorage.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/state/WritableMetricStorage.ts rename to packages/sdk-metrics/src/state/WritableMetricStorage.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/types.ts b/packages/sdk-metrics/src/types.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/types.ts rename to packages/sdk-metrics/src/types.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/utils.ts b/packages/sdk-metrics/src/utils.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/utils.ts rename to packages/sdk-metrics/src/utils.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/Aggregation.ts b/packages/sdk-metrics/src/view/Aggregation.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/view/Aggregation.ts rename to packages/sdk-metrics/src/view/Aggregation.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/AttributesProcessor.ts b/packages/sdk-metrics/src/view/AttributesProcessor.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/view/AttributesProcessor.ts rename to packages/sdk-metrics/src/view/AttributesProcessor.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/InstrumentSelector.ts b/packages/sdk-metrics/src/view/InstrumentSelector.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/view/InstrumentSelector.ts rename to packages/sdk-metrics/src/view/InstrumentSelector.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/MeterSelector.ts b/packages/sdk-metrics/src/view/MeterSelector.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/view/MeterSelector.ts rename to packages/sdk-metrics/src/view/MeterSelector.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/Predicate.ts b/packages/sdk-metrics/src/view/Predicate.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/view/Predicate.ts rename to packages/sdk-metrics/src/view/Predicate.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/RegistrationConflicts.ts b/packages/sdk-metrics/src/view/RegistrationConflicts.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/view/RegistrationConflicts.ts rename to packages/sdk-metrics/src/view/RegistrationConflicts.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/View.ts b/packages/sdk-metrics/src/view/View.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/view/View.ts rename to packages/sdk-metrics/src/view/View.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/src/view/ViewRegistry.ts b/packages/sdk-metrics/src/view/ViewRegistry.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/src/view/ViewRegistry.ts rename to packages/sdk-metrics/src/view/ViewRegistry.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/ExemplarFilter.test.ts b/packages/sdk-metrics/test/ExemplarFilter.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/ExemplarFilter.test.ts rename to packages/sdk-metrics/test/ExemplarFilter.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/ExemplarReservoir.test.ts b/packages/sdk-metrics/test/ExemplarReservoir.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/ExemplarReservoir.test.ts rename to packages/sdk-metrics/test/ExemplarReservoir.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/InstrumentDescriptor.test.ts b/packages/sdk-metrics/test/InstrumentDescriptor.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/InstrumentDescriptor.test.ts rename to packages/sdk-metrics/test/InstrumentDescriptor.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts b/packages/sdk-metrics/test/Instruments.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/Instruments.test.ts rename to packages/sdk-metrics/test/Instruments.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/Meter.test.ts b/packages/sdk-metrics/test/Meter.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/Meter.test.ts rename to packages/sdk-metrics/test/Meter.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts b/packages/sdk-metrics/test/MeterProvider.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/MeterProvider.test.ts rename to packages/sdk-metrics/test/MeterProvider.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts b/packages/sdk-metrics/test/ObservableResult.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/ObservableResult.test.ts rename to packages/sdk-metrics/test/ObservableResult.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Drop.test.ts b/packages/sdk-metrics/test/aggregator/Drop.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Drop.test.ts rename to packages/sdk-metrics/test/aggregator/Drop.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Histogram.test.ts b/packages/sdk-metrics/test/aggregator/Histogram.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Histogram.test.ts rename to packages/sdk-metrics/test/aggregator/Histogram.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/aggregator/LastValue.test.ts b/packages/sdk-metrics/test/aggregator/LastValue.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/aggregator/LastValue.test.ts rename to packages/sdk-metrics/test/aggregator/LastValue.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Sum.test.ts b/packages/sdk-metrics/test/aggregator/Sum.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/aggregator/Sum.test.ts rename to packages/sdk-metrics/test/aggregator/Sum.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/ConsoleMetricExporter.test.ts b/packages/sdk-metrics/test/export/ConsoleMetricExporter.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/export/ConsoleMetricExporter.test.ts rename to packages/sdk-metrics/test/export/ConsoleMetricExporter.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/InMemoryMetricExporter.test.ts b/packages/sdk-metrics/test/export/InMemoryMetricExporter.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/export/InMemoryMetricExporter.test.ts rename to packages/sdk-metrics/test/export/InMemoryMetricExporter.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts b/packages/sdk-metrics/test/export/MetricReader.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/export/MetricReader.test.ts rename to packages/sdk-metrics/test/export/MetricReader.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts b/packages/sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts rename to packages/sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricExporter.ts b/packages/sdk-metrics/test/export/TestMetricExporter.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricExporter.ts rename to packages/sdk-metrics/test/export/TestMetricExporter.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricProducer.ts b/packages/sdk-metrics/test/export/TestMetricProducer.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricProducer.ts rename to packages/sdk-metrics/test/export/TestMetricProducer.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts b/packages/sdk-metrics/test/export/TestMetricReader.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/export/TestMetricReader.ts rename to packages/sdk-metrics/test/export/TestMetricReader.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/export/utils.ts b/packages/sdk-metrics/test/export/utils.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/export/utils.ts rename to packages/sdk-metrics/test/export/utils.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/index-webpack.ts b/packages/sdk-metrics/test/index-webpack.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/index-webpack.ts rename to packages/sdk-metrics/test/index-webpack.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/AsyncMetricStorage.test.ts b/packages/sdk-metrics/test/state/AsyncMetricStorage.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/AsyncMetricStorage.test.ts rename to packages/sdk-metrics/test/state/AsyncMetricStorage.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/DeltaMetricProcessor.test.ts b/packages/sdk-metrics/test/state/DeltaMetricProcessor.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/DeltaMetricProcessor.test.ts rename to packages/sdk-metrics/test/state/DeltaMetricProcessor.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/HashMap.test.ts b/packages/sdk-metrics/test/state/HashMap.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/HashMap.test.ts rename to packages/sdk-metrics/test/state/HashMap.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts b/packages/sdk-metrics/test/state/MeterSharedState.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/MeterSharedState.test.ts rename to packages/sdk-metrics/test/state/MeterSharedState.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts b/packages/sdk-metrics/test/state/MetricCollector.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/MetricCollector.test.ts rename to packages/sdk-metrics/test/state/MetricCollector.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts b/packages/sdk-metrics/test/state/MetricStorageRegistry.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/MetricStorageRegistry.test.ts rename to packages/sdk-metrics/test/state/MetricStorageRegistry.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/MultiWritableMetricStorage.test.ts b/packages/sdk-metrics/test/state/MultiWritableMetricStorage.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/MultiWritableMetricStorage.test.ts rename to packages/sdk-metrics/test/state/MultiWritableMetricStorage.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/ObservableRegistry.test.ts b/packages/sdk-metrics/test/state/ObservableRegistry.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/ObservableRegistry.test.ts rename to packages/sdk-metrics/test/state/ObservableRegistry.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/SyncMetricStorage.test.ts b/packages/sdk-metrics/test/state/SyncMetricStorage.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/SyncMetricStorage.test.ts rename to packages/sdk-metrics/test/state/SyncMetricStorage.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/state/TemporalMetricProcessor.test.ts b/packages/sdk-metrics/test/state/TemporalMetricProcessor.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/state/TemporalMetricProcessor.test.ts rename to packages/sdk-metrics/test/state/TemporalMetricProcessor.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/test-utils.ts b/packages/sdk-metrics/test/test-utils.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/test-utils.ts rename to packages/sdk-metrics/test/test-utils.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/util.ts b/packages/sdk-metrics/test/util.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/util.ts rename to packages/sdk-metrics/test/util.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/utils.test.ts b/packages/sdk-metrics/test/utils.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/utils.test.ts rename to packages/sdk-metrics/test/utils.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/view/Aggregation.test.ts b/packages/sdk-metrics/test/view/Aggregation.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/view/Aggregation.test.ts rename to packages/sdk-metrics/test/view/Aggregation.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/view/AttributesProcessor.test.ts b/packages/sdk-metrics/test/view/AttributesProcessor.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/view/AttributesProcessor.test.ts rename to packages/sdk-metrics/test/view/AttributesProcessor.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/view/Predicate.test.ts b/packages/sdk-metrics/test/view/Predicate.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/view/Predicate.test.ts rename to packages/sdk-metrics/test/view/Predicate.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/view/View.test.ts b/packages/sdk-metrics/test/view/View.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/view/View.test.ts rename to packages/sdk-metrics/test/view/View.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/test/view/ViewRegistry.test.ts b/packages/sdk-metrics/test/view/ViewRegistry.test.ts similarity index 100% rename from experimental/packages/opentelemetry-sdk-metrics/test/view/ViewRegistry.test.ts rename to packages/sdk-metrics/test/view/ViewRegistry.test.ts diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.all.json b/packages/sdk-metrics/tsconfig.all.json similarity index 78% rename from experimental/packages/opentelemetry-sdk-metrics/tsconfig.all.json rename to packages/sdk-metrics/tsconfig.all.json index 06c5491334..4d28a993d3 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.all.json +++ b/packages/sdk-metrics/tsconfig.all.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "files": [], "references": [ { "path": "./tsconfig.json" }, diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json b/packages/sdk-metrics/tsconfig.esm.json similarity index 78% rename from experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json rename to packages/sdk-metrics/tsconfig.esm.json index 379f547a46..a94adff6aa 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esm.json +++ b/packages/sdk-metrics/tsconfig.esm.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.esm.json", + "extends": "../../tsconfig.base.esm.json", "compilerOptions": { "rootDir": "src", "outDir": "build/esm", diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json b/packages/sdk-metrics/tsconfig.esnext.json similarity index 78% rename from experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json rename to packages/sdk-metrics/tsconfig.esnext.json index cb78dd6ff3..65a918cf6b 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.esnext.json +++ b/packages/sdk-metrics/tsconfig.esnext.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.esnext.json", + "extends": "../../tsconfig.base.esnext.json", "compilerOptions": { "rootDir": "src", "outDir": "build/esnext", diff --git a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json b/packages/sdk-metrics/tsconfig.json similarity index 51% rename from experimental/packages/opentelemetry-sdk-metrics/tsconfig.json rename to packages/sdk-metrics/tsconfig.json index f93e34131f..9b42c9bb79 100644 --- a/experimental/packages/opentelemetry-sdk-metrics/tsconfig.json +++ b/packages/sdk-metrics/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "rootDir": ".", "outDir": "build" @@ -10,13 +10,13 @@ ], "references": [ { - "path": "../../../api" + "path": "../../api" }, { - "path": "../../../packages/opentelemetry-core" + "path": "../opentelemetry-core" }, { - "path": "../../../packages/opentelemetry-resources" + "path": "../opentelemetry-resources" } ] } diff --git a/packages/template/package.json b/packages/template/package.json index 77493ccde3..6342f2876c 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/template", - "version": "1.7.0", + "version": "1.8.0", "private": true, "publishConfig": { "access": "restricted" diff --git a/selenium-tests/package.json b/selenium-tests/package.json index 4647c0f149..fc1ec5f3c0 100644 --- a/selenium-tests/package.json +++ b/selenium-tests/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/selenium-tests", - "version": "1.7.0", + "version": "1.8.0", "private": true, "description": "OpenTelemetry Selenium Tests", "main": "index.js", @@ -56,16 +56,16 @@ "@opentelemetry/api": "^1.0.0" }, "dependencies": { - "@opentelemetry/context-zone-peer-dep": "1.7.0", - "@opentelemetry/core": "1.7.0", - "@opentelemetry/exporter-trace-otlp-http": "0.33.0", - "@opentelemetry/exporter-zipkin": "1.7.0", - "@opentelemetry/instrumentation": "0.33.0", - "@opentelemetry/instrumentation-fetch": "0.33.0", - "@opentelemetry/instrumentation-xml-http-request": "0.33.0", - "@opentelemetry/sdk-metrics": "0.33.0", - "@opentelemetry/sdk-trace-base": "1.7.0", - "@opentelemetry/sdk-trace-web": "1.7.0", + "@opentelemetry/context-zone-peer-dep": "1.8.0", + "@opentelemetry/core": "1.8.0", + "@opentelemetry/exporter-trace-otlp-http": "0.34.0", + "@opentelemetry/exporter-zipkin": "1.8.0", + "@opentelemetry/instrumentation": "0.34.0", + "@opentelemetry/instrumentation-fetch": "0.34.0", + "@opentelemetry/instrumentation-xml-http-request": "0.34.0", + "@opentelemetry/sdk-metrics": "1.8.0", + "@opentelemetry/sdk-trace-base": "1.8.0", + "@opentelemetry/sdk-trace-web": "1.8.0", "zone.js": "0.11.4" } } diff --git a/tsconfig.json b/tsconfig.json index 371ba80055..e2133c3f7f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -94,6 +94,9 @@ { "path": "packages/opentelemetry-shim-opentracing" }, + { + "path": "packages/sdk-metrics" + }, { "path": "packages/template" }, @@ -139,9 +142,6 @@ { "path": "experimental/packages/opentelemetry-instrumentation" }, - { - "path": "experimental/packages/opentelemetry-sdk-metrics" - }, { "path": "experimental/packages/opentelemetry-sdk-node" }, From 74e39c77889cca5df4171982268399c5bb6d9062 Mon Sep 17 00:00:00 2001 From: Weyert de Boer Date: Thu, 10 Nov 2022 13:53:09 +0000 Subject: [PATCH 65/77] docs: add Metrics documentation to project (#3360) Co-authored-by: Chengzhong Wu Co-authored-by: Marc Pichler Co-authored-by: Marc Pichler Co-authored-by: Daniel Dyla --- CHANGELOG.md | 1 + doc/metrics.md | 558 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- tsconfig.json | 6 +- 4 files changed, 564 insertions(+), 3 deletions(-) create mode 100644 doc/metrics.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 6df58ae19c..545e002cd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/ ### :books: (Refine Doc) +* doc: Added Metrics documentation [#3360](https://github.com/open-telemetry/opentelemetry-js/pull/3360) @weyert * docs(api): fix counter negative value wording [#3396](https://github.com/open-telemetry/opentelemetry-js/pull/3396) @legendecas ### :house: (Internal) diff --git a/doc/metrics.md b/doc/metrics.md new file mode 100644 index 0000000000..7162f43638 --- /dev/null +++ b/doc/metrics.md @@ -0,0 +1,558 @@ +# Metrics + +This quick start is for end users of OpenTelemetry who wish to manually measure their applications. If you are a library author, please see the [Library Authors Guide](library-author.md). If you wish to automatically instrument your application, see the automatic instrumentation documentation for the SDK you wish to use. + +For a high-level overview of OpenTelemetry metrics in general and definitions of some common terms, you can refer to the [OpenTelemetry Specification Overview][spec-overview] + +_Metrics API Specification: _ + +_Metrics API Reference: _ + +- [Getting Started](#getting-started) +- [Acquiring a Meter](#acquiring-a-meter) +- [Create a metric instrument](#create-a-metric-instrument) +- [Describing a instrument measurement](#describing-a-instrument-measurement) + - [Metric Attributes](#metric-attributes) + - [Semantic Conventions](#semantic-conventions) +- [Configuring metric views](#configuring-metric-views) + - [Configuring explicit bucket sizes for the Histogram instrument](#configuring-explicit-bucket-sizes-for-the-histogram-instrument) + - [Dropping instrument from being exported](#dropping-instrument-from-being-exported) + - [Customizing the metric attributes of instrument](#customizing-the-metric-attributes-of-instrument) +- [Exporting measurements](#exporting-measurements) + - [Exporting measurements to Prometheus](#exporting-measurements-to-prometheus) + - [Exporting measurements to Opentelemetry Protocol](#exporting-measurements-to-opentelemetry-protocol) + +## Getting Started + +In this page, you'll learn how to setup OpenTelemetry JS to export metrics from an HTTP server with Fastify. If you're not using Fastify, that's fine -- this guide will also work with Express, etc. + +### Installation + +To begin, set up an environment in a new directory: + +```bash +mkdir otel-getting-started +cd otel-getting-started +npm init -y +``` + +Now install Fastify and OpenTelemetry: + +```bash +npm install fastify @opentelemetry/sdk-node @opentelemetry/exporter-prometheus @opentelemetry/auto-instrumentations-node +``` + +The `@opentelemetry/sdk-node` and `@opentelemetry/auto-instrumentations-node` will install all the +necessary packages to start with OpenTelemetry including instrumentation for a wide variety of popular +packages, such as `http`, `fetch` etc. The package `@opentelemetry/exporter-prometheus` is installed +to export our collected metrics to Prometheus. + +### Create the sample HTTP Server + +Create a file `app.js`: + +```javaScript +const api = require('@opentelemetry/api') +const opentelemetry = require("@opentelemetry/sdk-node"); +const { PrometheusExporter } = require("@opentelemetry/exporter-prometheus"); +const { + getNodeAutoInstrumentations, +} = require("@opentelemetry/auto-instrumentations-node"); + +const prometheusExporter = new PrometheusExporter({ startServer: true }); + +const sdk = new opentelemetry.NodeSDK({ + // Optional - If omitted, the metrics SDK will not be initialized + metricReader: prometheusExporter, + // Optional - you can use the metapackage or load each instrumentation individually + instrumentations: [getNodeAutoInstrumentations()], + // See the Configuration section below for additional configuration options +}); + +// You can optionally detect resources asynchronously from the environment. +// Detected resources are merged with the resources provided in the SDK configuration. +sdk.start().then(() => { + // Resources have been detected and SDK is started + console.log(`SDK started`) + +// Start the http server + const fastify = require('fastify')({ + logger: true + }) + + fastify.get('/', function (request, reply) { + reply.send({ hello: 'world' }) + }) + + fastify.listen({ port: 3000 }, function (err, address) { + if (err) { + fastify.log.error(err) + process.exit(1) + } + + console.log(`Server is now listening on ${address}`) + }) +}); + +// You can also use the shutdown method to gracefully shut down the SDK before process shutdown +// or on some operating system signal. +const process = require("process"); +process.on("SIGTERM", () => { + sdk + .shutdown() + .then( + () => console.log("SDK shut down successfully"), + (err) => console.log("Error shutting down SDK", err) + ) + .finally(() => process.exit(0)); +}); +``` + +In the above example we are initializing the Node SDK to enable the Metrics SDK +and configure it to export the metrics in Prometheus format by registering the +`PrometheusExporter`. + +You can now run the instrument application and it will run the HTTP server on +port 3000 with command: + +```bash +node app.js +``` + +Now when accessing the HTTP server via you will +see the following: + +```json +{"hello":"world"} +``` + +### Add manual instrumentation + +Automatic instrumentation is powerful but it doesn't capture what's going on in +your application. For that you'll need to write some manual instrumentation. Below +we will show you how you can count the number of times a HTTP endpoint has been +accessed. + +#### Counting number of incoming http requests + +First, modify `app.js` to include code that initializes a meter and uses it to +create a counter instrument which counts the number of times the `/` http endpoint +has been requested. + +```javaScript +const api = require('@opentelemetry/api') +const opentelemetry = require("@opentelemetry/sdk-node"); +const { PrometheusExporter } = require("@opentelemetry/exporter-prometheus"); +const { + getNodeAutoInstrumentations, +} = require("@opentelemetry/auto-instrumentations-node"); + +const prometheusExporter = new PrometheusExporter({ startServer: true }); + +const sdk = new opentelemetry.NodeSDK({ + // Optional - If omitted, the metrics SDK will not be initialized + metricReader: prometheusExporter, + // Optional - you can use the metapackage or load each instrumentation individually + instrumentations: [getNodeAutoInstrumentations()], + // See the Configuration section below for additional configuration options +}); + +// You can optionally detect resources asynchronously from the environment. +// Detected resources are merged with the resources provided in the SDK configuration. +sdk.start().then(() => { + // Resources have been detected and SDK is started + console.log(`SDK started`) + + // Create Meter with the name `http-server` + const appMeter = api.metrics.getMeter('http-server') + // Use the created Meter to create a counter instrument + const numberOfRequests = appMeter.createCounter('request-counter') + + // Start the http server + const fastify = require('fastify')({ + logger: true + }) + + fastify.get('/', function (request, reply) { + // Increase the counter by 1 each time the `/` endpoint is requested + numberOfRequests.add(1) + reply.send({ hello: 'world' }) + }) + + fastify.listen({ port: 3000 }, function (err, address) { + if (err) { + fastify.log.error(err) + process.exit(1) + } + + console.log(`Server is now listening on ${address}`) + }) +}); + +// You can also use the shutdown method to gracefully shut down the SDK before process shutdown +// or on some operating system signal. +const process = require("process"); +process.on("SIGTERM", () => { + sdk + .shutdown() + .then( + () => console.log("SDK shut down successfully"), + (err) => console.log("Error shutting down SDK", err) + ) + .finally(() => process.exit(0)); +}); +``` + +Now run the application again: + +```bash +node app.js +``` + +When you navigate to , the counter instrument will be increased +each time the page is accessed. If you want to see the exporter instruments, you +can access via the dedicates metrics endpoint for Prometheus by accessing: + the contents will look similar to: + +```text +# HELP request_counter_total description missing +# TYPE request_counter_total counter +request_counter_total 6 1666624810428 +``` + +In the above example output you can that one instrument is available with the +name `request_counter_total`: + +```text +request_counter_total 6 1666624810428 +``` + +The postfixed `_total` get automatically to the instrument name for each counter instrument +when the measurements are getting exported in the Prometheus format. In the above +example you see that we accessed our `/` endpoint six times. + +## Acquiring a Meter + +In OpenTelemetry, Instruments that allow for measurement operations are acquired through a _meter_. You can get a meter by calling [`getMeter`](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api.MeterProvider.html#getMeter) on the global meter provider. `getMeter` takes the name and version of the application or library acquiring the meter, and provides a meter which can be used to create instruments. + +```typescript +import { metrics } from '@opentelemetry/api'; + +const meter = metrics.getMeter("my-application", "0.1.0"); +``` + +## Create a metric instrument + +In OpenTelemetry, all _metrics_ are composed of [`Instruments`](https://open-telemetry.github.io/opentelemetry-js/enums/_opentelemetry_sdk_metrics.InstrumentType.html). An instrument is responsible for reporting measurements, +there are four types of instruments that can be created: + +- Counter, a synchronous instrument which supports non-negative increments +- Asynchronous Counter, a asynchronous instrument which supports non-negative increments +- Histogram, a synchronous instrument which supports arbitrary values that are statistically meaningful, such as histograms, summaries or percentile +- Asynchronous Gauge, an asynchronous instrument which supports non-additive values, such as room temperature +- UpDownCounter, a synchronous instrument which supports increments and decrements, such as number of active requests +- Asynchronous UpDownCounter, an asynchronous instrument which supports increments and decrements + +You can create a Counter instrument by calling [`Meter#createCounter`](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api.Meter.html#createCounter). The only required argument to `createCounter` is the _instrument name_, which should describe the item that is being measurement. + +```typescript +const counter = meter.createCounter("events.counter"); + +// increase the counter +counter.add(1); +``` + +Most of the time, instruments will be used to measure operations in your application. The following example shows what it might look like to manually measure a function's duration. + +```typescript +async function myTask() { + const histogram = meter.createHistogram("taks.duration"); + const startTime = new Date().getTime() + try { + // Wait for five seconds before continuing code execution + await setTimeout(5_000) + } catch (err) { + } finally { + const endTime = new Date().getTime() + const executionTime = endTime - startTime + + // Record the duration of the task operation + histogram.record(executionTime) + } +} + +await myTask() +``` + +## Describing a instrument measurement + +Using attributes, kind, and the related [semantic conventions](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions), we can more accurately describe the measurement in a way our metrics backend will more easily understand. The following example uses these mechanisms, which are described below, for recording a measurement +of a HTTP request. + +Each metric instruments allows to associate a description, unit of measure, and the value type. +The description of a metric instrument can expose up in the metrics backend, the unit or value type +can be used to information about the record measurement itself. + +```typescript +async function myTask() { + const httpServerDuration = meter.createHistogram("http.server.duration", { + description: 'A http server duration', + unit: 'milliseconds', + valueType: ValueType.INT + }); + const startTime = new Date().getTime() + try { + // Wait for five seconds before continuing code execution + await setTimeout(5_000) + } catch (err) { + } finally { + const endTime = new Date().getTime() + const executionTime = endTime - startTime + + httpServerDuration.record(executionTime, { + [SemanticAttributes.HTTP_METHOD]: 'POST', + [SemanticAttributes.HTTP_STATUS_CODE]: '200', + [SemanticAttributes.HTTP_SCHEME]: 'https', + }) + } +} + +await myTask() +``` + +In the above example we are recording a measurement of roughly 5000ms and associate +three metric attributes with this measurement. Metrics backends can show these metric +attributes. In Prometheus the metric attributes would become labels and can be used +as part of queries, and allow search queries, such as what's the 90% percentile of +all successful POST requests. + +### Metric Attributes + +While name and measurement are the minimum required to record a metric measurement, +most of the time they will not be enough information on their own to effectively observe +an application. To solve this, OpenTelemetry uses _Metric Attributes_. Metric attributes are object with +string keys and string values which add more context to the measurement. + +For example, when you are measuring the number of inflight requests, you might want to be able to count +the number of POST, or GET requests. You can add the a metric attribute for `http.method` to allow more +flexibility when leveraging your metric measurement like in Grafana dashboards. + +### Semantic Conventions + +One problem with metrics names and attributes is recognizing, categorizing, and analyzing them in your metrics backend. Between different applications, libraries, and metrics backends there might be different names and expected values for various attributes. For example, your application may use `http.status` to describe the HTTP status code, but a library you use may use `http.status_code`. In order to solve this problem, OpenTelemetry uses a library of semantic conventions which describe the name and attributes which should be used for specific types of metrics. + +The use of semantic conventions is always recommended where applicable, but they are merely conventions. For example, you may find that some name other than the name suggested by the semantic conventions more accurately describes your metric, you may decide not to include a metric attribute which is suggested by semantic conventions for privacy reasons, or you may wish to add a custom attribute which isn't covered by semantic conventions. All of these cases are fine, but please keep in mind that if you stray from the semantic conventions, the categorization of metrics in your metrics backend may be affected. + +_See the current metrics semantic conventions in the OpenTelemetry Specification repository: _ + +[spec-overview]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md + +## Configuring metric views + +A [Metric View](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view) provides the ability to customize the metrics that are exposed by the +Metrics SDK. Metric Views allows you to do: + +- Customize which Metric Attributes are reported on metrics +- Customize which instruments get processed/ignored +- Change the aggregation of a metric +- Define explicit bucket sizes to Histogram instruments + +The Metric view requires the instrument selection query, and the configuration +for the resulting metric. The first step is select to the metrics to whom the View +is relevant, the second step is to configure the customizations for the the selected +metrics. + +A Metric View is a class that can be instantiated via: + +````typescript +const view = new View({ + name: 'metric-view', // optionally, give the view a unique name + // select instruments with a specific name + instrumentName: 'http.server.duration', +}); +```` + +In the above example a View is created which select instruments with the name `http.server.duration` other options to select instruments are: + +- By Instrument Type: use `instrumentType` to select instruments of the given type +- By Meter: use `meterName` to select meters with the given name +- By Meter Version: use `meterVersion` to select meters with the given version +- By Meter Schema URL: use `meterSchemaUrl` to select meters with given schema url + +The `instrumentName` has support for wildcards, so you can select all instruments +using `*` or select all instruments starting with 'http.' by using `http.*`. + +_Note_: The Views can only be defined when the `MeterProvider` instance gets +instantiated. A proposal is submitted to ease the ability to define Metrics Views: + + +### Configuring explicit bucket sizes for the Histogram instrument + +The Histogram instrument has a predefined set of bucket sizes defined which might not +suit all your needs. The bucket sizes can be overridden by configuring a different +aggregation for the Histogram instrument. The `ExplicitBucketHistogramAggregation` +should be used to define the bucket sizes for the Histogram instrument. + +Below an example is given how you can define explicit buckets for a histogram. + +```typescript +// Define view for the histogram metric +const histogramView = new View({ + aggregation: new ExplicitBucketHistogramAggregation([0, 1, 5, 10, 15, 20, 25, 30]), + instrumentName: 'http.server.duration', + instrumentType: InstrumentType.HISTOGRAM, +}); + +// Note, the instrumentName is the same as the name that has been passed for +// the Meter#createHistogram function + +// Create an instance of the metric provider +const meterProvider = new MeterProvider({ + views: [ + histogramView + ] +}); + +// Create histogram metric +const httpServerDuration = meter.createHistogram("http.server.duration", { + description: 'A http server duration', + unit: 'milliseconds', + valueType: ValueType.INT +}); + +// Record measurement for histogram +httpServerDuration.record(50, { + [SemanticAttributes.HTTP_METHOD]: 'POST', + [SemanticAttributes.HTTP_STATUS_CODE]: '200', + [SemanticAttributes.HTTP_SCHEME]: 'https', +}); +``` + +### Dropping instrument from being exported + +In some circumstances you don't want specific metrics to be exported by OpenTelemetry, +for example, you might be using custom instrumentations or third-party packages that +define their own metrics you are not interested in. + +In such cases you can define a view which drops the instruments you are +not interested in. For example, you can drop instruments of a specific meter or +instruments with a specific name: + +The following view drops all instruments that are associated with a meter named `pubsub`: + +```typescript +const dropView = new View({ + aggregation: new DropAggregation(), + meterName: 'pubsub', +}); +``` + +Alternatively, you can also drop instruments with a specific instrument name, +for example, all instruments of which the name starts with `http`: + +```typescript +const dropView = new View({ + aggregation: new DropAggregation(), + instrumentName: 'http*', +}); +``` + +### Customizing the metric attributes of instrument + +If you want to limit the Metric Attributes that get exported in measurements of +an instrument, you can create a Metric View which defines which attributes should +be exported. Attributes that are missing in the list will not be exported. + +In the example below will drop all attributes except attribute `environment` for +all instruments. + +```typescript +new View({ + // only export the attribute 'environment' + attributeKeys: ['environment'], + // apply the view to all instruments + instrumentName: '*', +}) +``` + +## Exporting measurements + +After you have instrumented your application with metrics, you also need to make +sure that the metrics get collected by your metrics backend. The most common formats +that are used are Prometheus and OLTP. + +The latter is the [OpenTelemetry protocol format](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md) +which is supported by the OpenTelemetry Collector. The former is based on the [OpenMetrics +format](https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md) can be consumed by Prometheus and Thanos or other OpenMetrics compatible +backends. + +_Note_: Both OpenTelemetry JavaScript and OpenTelemetry Collector support +exporters for different formats, such as [Cloud Monitoring](https://github.com/GoogleCloudPlatform/opentelemetry-operations-js/tree/master/packages/opentelemetry-cloud-monitoring-exporter). + +## Exporting measurements to Prometheus + +If you want to export your metrics to Prometheus you need to initialize OpenTelemetry +to use the Prometheus exporter `PrometheusExporter` which is included in the +`@opentelemetry/exporter-prometheus`-package. + +```typescript +const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); +const { MeterProvider } = require('@opentelemetry/sdk-metrics'); + +// Add your port and startServer to the Prometheus options +const options = { port: 9464, startServer: true }; +const exporter = new PrometheusExporter(options); + +// Creates MeterProvider and installs the exporter as a MetricReader +const meterProvider = new MeterProvider(); +meterProvider.addMetricReader(exporter); +const meter = meterProvider.getMeter('example-prometheus'); + +// Now, start recording data +const counter = meter.createCounter('metric_name', { + description: 'Example of a counter' +}); +counter.add(10, { pid: process.pid }); +``` + +In the above example the instantiated `PrometheusExporter` is configured to expose +a new http server on port 9464. You can now access the metrics at the endpoint +. This is the URL that can be scraped by Prometheus so it can consumed the metrics collected by OpenTelemetry in your application. + +More information about Prometheus and how to configure can be found at: +[https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config](Prometheus Scraping Config) + +For a fully functioning code example for using this exporter, please have a look +at: + +## Exporting measurements to OpenTelemetry Protocol + +OpenTelemetry JavaScript comes with three different kinds of exporters that export +the OTLP protocol, a) [over HTTP](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-http), b) [over GRPC](https://www.npmjs.com/package/@opentelemetry/exporter-metrics-otlp-grpc), c) [over Protofbuf](https://www.npmjs.com/package/@opentelemetry/exporter-metrics-otlp-proto). + +The example below shows how you can configure OpenTelemetry JavaScript to use +the OTLP exporter using http/protobuf. + +```typescript +const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); +const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-proto'); +const collectorOptions = { + url: '', // url is optional and can be omitted - default is http://localhost:4318/v1/metrics + concurrencyLimit: 1, // an optional limit on pending requests +}; +const exporter = new OTLPMetricExporter(collectorOptions); +const meterProvider = new MeterProvider({}); + +meterProvider.addMetricReader(new PeriodicExportingMetricReader({ + exporter: metricExporter, + exportIntervalMillis: 1000, +})); + +// Now, start recording data +const meter = meterProvider.getMeter('example-meter'); +const counter = meter.createCounter('metric_name'); +counter.add(10, { 'key': 'value' }); +``` + +For a fully functioning code example for using this exporter, please have a look +at: diff --git a/package.json b/package.json index 26755f3cb8..4be8d6e76b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "predocs-test": "npm run docs", "docs": "typedoc --readme none && touch docs/.nojekyll", "docs-deploy": "gh-pages --dotfiles --dist docs", - "docs:test": "linkinator docs --silent --retry && linkinator doc/*.md --silent --retry", + "docs:test": "linkinator docs --silent --retry && linkinator doc/*.md --skip http://localhost:3000 --skip http://localhost:9464 --silent --retry", "lint": "lerna run lint", "lint:changed": "lerna run --concurrency 1 --stream lint --since HEAD --exclude-dependents", "lint:fix": "lerna run lint:fix", diff --git a/tsconfig.json b/tsconfig.json index e2133c3f7f..09ccfeb07f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,9 +5,11 @@ "entryPointStrategy": "packages", "entryPoints": [ "api", + "experimental/packages/api-logs", "experimental/packages/exporter-trace-otlp-grpc", "experimental/packages/exporter-trace-otlp-http", "experimental/packages/exporter-trace-otlp-proto", + "experimental/packages/opentelemetry-browser-detector", "experimental/packages/opentelemetry-exporter-metrics-otlp-grpc", "experimental/packages/opentelemetry-exporter-metrics-otlp-http", "experimental/packages/opentelemetry-exporter-metrics-otlp-proto", @@ -17,7 +19,6 @@ "experimental/packages/opentelemetry-instrumentation-http", "experimental/packages/opentelemetry-instrumentation-xml-http-request", "experimental/packages/opentelemetry-instrumentation", - "experimental/packages/opentelemetry-sdk-metrics", "experimental/packages/opentelemetry-sdk-node", "experimental/packages/otlp-exporter-base", "experimental/packages/otlp-grpc-exporter-base", @@ -36,7 +37,8 @@ "packages/opentelemetry-sdk-trace-node", "packages/opentelemetry-sdk-trace-web", "packages/opentelemetry-semantic-conventions", - "packages/opentelemetry-shim-opentracing" + "packages/opentelemetry-shim-opentracing", + "packages/sdk-metrics" ], "out": "docs", "exclude": [ From 258b677dbc2c985f96a5cc8b62d3b34276576361 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Thu, 10 Nov 2022 21:23:50 +0100 Subject: [PATCH 66/77] feat(console-metric-exporter): add temporality configuration (#3387) * feat(console-metric-exporter): add temporality configuration * feat(console-metric-exporter): use a temporality selector instead Co-authored-by: Daniel Dyla --- experimental/CHANGELOG.md | 1 + .../src/export/ConsoleMetricExporter.ts | 20 ++- .../test/export/ConsoleMetricExporter.test.ts | 165 +++++++++++------- packages/sdk-metrics/test/export/utils.ts | 11 +- 4 files changed, 130 insertions(+), 67 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 62ccda9e0a..6c180c18d5 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -29,6 +29,7 @@ All notable changes to experimental packages in this project will be documented * feat(detectors): add browser detector module [#3292](https://github.com/open-telemetry/opentelemetry-js/pull/3292) @abinet18 * deps: remove unused proto-loader dependencies and update grpc-js and proto-loader versions [#3337](https://github.com/open-telemetry/opentelemetry-js/pull/3337) @seemk * feat(metrics-exporters): configure temporality via environment variable [#3305](https://github.com/open-telemetry/opentelemetry-js/pull/3305) @pichlermarc +* feat(console-metric-exporter): add temporality configuration [#3387](https://github.com/open-telemetry/opentelemetry-js/pull/3387) @pichlermarc ### :bug: (Bug Fix) diff --git a/packages/sdk-metrics/src/export/ConsoleMetricExporter.ts b/packages/sdk-metrics/src/export/ConsoleMetricExporter.ts index 39b268f193..0b990dfe5e 100644 --- a/packages/sdk-metrics/src/export/ConsoleMetricExporter.ts +++ b/packages/sdk-metrics/src/export/ConsoleMetricExporter.ts @@ -13,15 +13,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ExportResult, ExportResultCode } from '@opentelemetry/core'; +import { + ExportResult, + ExportResultCode +} from '@opentelemetry/core'; import { InstrumentType } from '../InstrumentDescriptor'; import { AggregationTemporality } from './AggregationTemporality'; import { ResourceMetrics } from './MetricData'; import { PushMetricExporter } from './MetricExporter'; +import { + AggregationTemporalitySelector, + DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR, +} from './AggregationSelector'; + +interface ConsoleMetricExporterOptions { + temporalitySelector?: AggregationTemporalitySelector +} /* eslint-disable no-console */ export class ConsoleMetricExporter implements PushMetricExporter { protected _shutdown = false; + protected _temporalitySelector: AggregationTemporalitySelector; + + constructor(options?: ConsoleMetricExporterOptions) { + this._temporalitySelector = options?.temporalitySelector ?? DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR; + } export(metrics: ResourceMetrics, resultCallback: (result: ExportResult) => void): void { if (this._shutdown) { @@ -38,7 +54,7 @@ export class ConsoleMetricExporter implements PushMetricExporter { } selectAggregationTemporality(_instrumentType: InstrumentType): AggregationTemporality { - return AggregationTemporality.CUMULATIVE; + return this._temporalitySelector(_instrumentType); } shutdown(): Promise { diff --git a/packages/sdk-metrics/test/export/ConsoleMetricExporter.test.ts b/packages/sdk-metrics/test/export/ConsoleMetricExporter.test.ts index 6097aeb555..7cd8048bf9 100644 --- a/packages/sdk-metrics/test/export/ConsoleMetricExporter.test.ts +++ b/packages/sdk-metrics/test/export/ConsoleMetricExporter.test.ts @@ -22,6 +22,14 @@ import { MeterProvider } from '../../src/MeterProvider'; import { defaultResource } from '../util'; import * as assert from 'assert'; import * as sinon from 'sinon'; +import { assertAggregationTemporalitySelector } from './utils'; +import { + DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR +} from '../../src/export/AggregationSelector'; +import { + AggregationTemporality, + InstrumentType +} from '../../src'; async function waitForNumberOfExports(exporter: sinon.SinonSpy<[metrics: ResourceMetrics, resultCallback: (result: ExportResult) => void], void>, numberOfExports: number): Promise { @@ -38,71 +46,108 @@ async function waitForNumberOfExports(exporter: sinon.SinonSpy<[metrics: Resourc /* eslint-disable no-console */ describe('ConsoleMetricExporter', () => { - let previousConsoleDir: any; - let exporter: ConsoleMetricExporter; - let meterProvider: MeterProvider; - let meterReader: PeriodicExportingMetricReader; - let meter: metrics.Meter; - - beforeEach(() => { - previousConsoleDir = console.dir; - console.dir = () => {}; - - exporter = new ConsoleMetricExporter(); - meterProvider = new MeterProvider({ resource: defaultResource }); - meter = meterProvider.getMeter('ConsoleMetricExporter', '1.0.0'); - meterReader = new PeriodicExportingMetricReader({ - exporter: exporter, - exportIntervalMillis: 100, - exportTimeoutMillis: 100 + describe('export', () => { + let previousConsoleDir: any; + let exporter: ConsoleMetricExporter; + let meterProvider: MeterProvider; + let meterReader: PeriodicExportingMetricReader; + let meter: metrics.Meter; + + beforeEach(() => { + previousConsoleDir = console.dir; + console.dir = () => {}; + + exporter = new ConsoleMetricExporter(); + meterProvider = new MeterProvider({ resource: defaultResource }); + meter = meterProvider.getMeter('ConsoleMetricExporter', '1.0.0'); + meterReader = new PeriodicExportingMetricReader({ + exporter: exporter, + exportIntervalMillis: 100, + exportTimeoutMillis: 100 + }); + meterProvider.addMetricReader(meterReader); }); - meterProvider.addMetricReader(meterReader); - }); - afterEach(async () => { - console.dir = previousConsoleDir; + afterEach(async () => { + console.dir = previousConsoleDir; + + await meterReader.shutdown(); + }); + + it('should export information about metric', async () => { + const counter = meter.createCounter('counter_total', { + description: 'a test description', + }); + const counterAttribute = { key1: 'attributeValue1' }; + counter.add(10, counterAttribute); + counter.add(10, counterAttribute); + + const histogram = meter.createHistogram('histogram', { description: 'a histogram' }); + histogram.record(10); + histogram.record(100); + histogram.record(1000); + + const spyConsole = sinon.spy(console, 'dir'); + const spyExport = sinon.spy(exporter, 'export'); + + await waitForNumberOfExports(spyExport, 1); + const resourceMetrics = spyExport.args[0]; + const firstResourceMetric = resourceMetrics[0]; + const consoleArgs = spyConsole.args[0]; + const consoleMetric = consoleArgs[0]; + const keys = Object.keys(consoleMetric).sort().join(','); - await meterReader.shutdown(); + const expectedKeys = [ + 'dataPointType', + 'dataPoints', + 'descriptor', + ].join(','); + + assert.ok(firstResourceMetric.resource.attributes.resourceKey === 'my-resource', 'resourceKey'); + assert.ok(keys === expectedKeys, 'expectedKeys'); + assert.ok(consoleMetric.descriptor.name === 'counter_total', 'name'); + assert.ok(consoleMetric.descriptor.description === 'a test description', 'description'); + assert.ok(consoleMetric.descriptor.type === 'COUNTER', 'type'); + assert.ok(consoleMetric.descriptor.unit === '', 'unit'); + assert.ok(consoleMetric.descriptor.valueType === 1, 'valueType'); + assert.ok(consoleMetric.dataPoints[0].attributes.key1 === 'attributeValue1', 'ensure metric attributes exists'); + + assert.ok(spyExport.calledOnce); + }); }); - it('should export information about metric', async () => { - const counter = meter.createCounter('counter_total', { - description: 'a test description', + describe('constructor', () => { + it('with no arguments should select cumulative temporality', () => { + const exporter = new ConsoleMetricExporter(); + assertAggregationTemporalitySelector(exporter, DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR); + }); + + it('with empty options should select cumulative temporality', () => { + const exporter = new ConsoleMetricExporter({}); + assertAggregationTemporalitySelector(exporter, DEFAULT_AGGREGATION_TEMPORALITY_SELECTOR); + }); + + it('with cumulative preference should select cumulative temporality', () => { + const exporter = new ConsoleMetricExporter({ temporalitySelector: _ => AggregationTemporality.CUMULATIVE }); + assertAggregationTemporalitySelector(exporter, _ => AggregationTemporality.CUMULATIVE); + }); + + it('with mixed preference should select matching temporality', () => { + // use delta-ish example as a representation of a commonly used "mixed" preference. + const selector = (instrumentType: InstrumentType) => { + switch (instrumentType) { + case InstrumentType.COUNTER: + case InstrumentType.OBSERVABLE_COUNTER: + case InstrumentType.HISTOGRAM: + case InstrumentType.OBSERVABLE_GAUGE: + return AggregationTemporality.DELTA; + case InstrumentType.UP_DOWN_COUNTER: + case InstrumentType.OBSERVABLE_UP_DOWN_COUNTER: + return AggregationTemporality.CUMULATIVE; + } + }; + const exporter = new ConsoleMetricExporter({ temporalitySelector: selector }); + assertAggregationTemporalitySelector(exporter, selector); }); - const counterAttribute = { key1: 'attributeValue1' }; - counter.add(10, counterAttribute); - counter.add(10, counterAttribute); - - const histogram = meter.createHistogram('histogram', { description: 'a histogram' }); - histogram.record(10); - histogram.record(100); - histogram.record(1000); - - const spyConsole = sinon.spy(console, 'dir'); - const spyExport = sinon.spy(exporter, 'export'); - - await waitForNumberOfExports(spyExport, 1); - const resourceMetrics = spyExport.args[0]; - const firstResourceMetric = resourceMetrics[0]; - const consoleArgs = spyConsole.args[0]; - const consoleMetric = consoleArgs[0]; - const keys = Object.keys(consoleMetric).sort().join(','); - - const expectedKeys = [ - 'dataPointType', - 'dataPoints', - 'descriptor', - ].join(','); - - assert.ok(firstResourceMetric.resource.attributes.resourceKey === 'my-resource', 'resourceKey'); - assert.ok(keys === expectedKeys, 'expectedKeys'); - assert.ok(consoleMetric.descriptor.name === 'counter_total', 'name'); - assert.ok(consoleMetric.descriptor.description === 'a test description', 'description'); - assert.ok(consoleMetric.descriptor.type === 'COUNTER', 'type'); - assert.ok(consoleMetric.descriptor.unit === '', 'unit'); - assert.ok(consoleMetric.descriptor.valueType === 1, 'valueType'); - assert.ok(consoleMetric.dataPoints[0].attributes.key1 === 'attributeValue1', 'ensure metric attributes exists'); - - assert.ok(spyExport.calledOnce); }); }); diff --git a/packages/sdk-metrics/test/export/utils.ts b/packages/sdk-metrics/test/export/utils.ts index cd8a9cc7ae..3ad8543be7 100644 --- a/packages/sdk-metrics/test/export/utils.ts +++ b/packages/sdk-metrics/test/export/utils.ts @@ -18,7 +18,8 @@ import { AggregationSelector, AggregationTemporalitySelector, InstrumentType, - MetricReader + MetricReader, + PushMetricExporter } from '../../src'; import * as assert from 'assert'; @@ -36,9 +37,9 @@ const instrumentTypes = [ * @param reader * @param expectedSelector */ -export function assertAggregationSelector(reader: MetricReader, expectedSelector: AggregationSelector) { +export function assertAggregationSelector(reader: MetricReader | PushMetricExporter, expectedSelector: AggregationSelector) { for (const instrumentType of instrumentTypes) { - assert.strictEqual(reader.selectAggregation(instrumentType), + assert.strictEqual(reader.selectAggregation?.(instrumentType), expectedSelector(instrumentType), `incorrect aggregation selection for ${InstrumentType[instrumentType]}`); } @@ -49,9 +50,9 @@ export function assertAggregationSelector(reader: MetricReader, expectedSelector * @param reader * @param expectedSelector */ -export function assertAggregationTemporalitySelector(reader: MetricReader, expectedSelector: AggregationTemporalitySelector) { +export function assertAggregationTemporalitySelector(reader: MetricReader | PushMetricExporter, expectedSelector: AggregationTemporalitySelector) { for (const instrumentType of instrumentTypes) { - assert.strictEqual(reader.selectAggregationTemporality(instrumentType), + assert.strictEqual(reader.selectAggregationTemporality?.(instrumentType), expectedSelector(instrumentType), `incorrect aggregation temporality selection for ${InstrumentType[instrumentType]}`); } From d1621d2c8bb21484e72706834b53ad0c7da73ca6 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 10 Nov 2022 17:09:03 -0500 Subject: [PATCH 67/77] Update API readme and doc links (#3401) * Update readme docs link to reflect new API location * Update feature status * Fix API doc links and readme --- README.md | 17 ++++---- api/README.md | 41 ++++--------------- doc/context.md | 2 +- doc/sdk-registration.md | 6 +-- doc/tracing.md | 8 ++-- .../README.md | 2 +- 6 files changed, 26 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 160ec8d3e0..c4561df9c0 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,7 @@ Getting Started   •   - API Reference -   •   - SDK Reference + API and SDK Reference

      @@ -142,6 +140,7 @@ The below table describes which versions of each set of packages are expected to | API | Stable Packages | Experimental Packages | | ----- | --------------- | --------------------- | +| 1.3.x | 1.8.x | 0.34.x | | 1.2.x | 1.7.x | 0.33.x | | 1.2.x | 1.6.x | 0.32.x | | 1.1.x | 1.5.x | 0.31.x | @@ -158,11 +157,11 @@ The current version for each package can be found in the respective `package.jso ## Feature Status -| Signal | API Status | SDK Status | -| ------- | ----------- | ----------------- | -| Tracing | Stable | Release Candidate | -| Metrics | Development | Development | -| Logs | Roadmap | Roadmap | +| Signal | API Status | SDK Status | +| ------- | ----------- | ----------- | +| Tracing | Stable | Stable | +| Metrics | Stable | Stable | +| Logs | Development | Development | For a more detailed breakdown of feature support see the [specification compliance matrix][compliance-matrix]. @@ -550,7 +549,7 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [otel-shim-opentracing]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-shim-opentracing [otel-tracing]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-base [otel-web]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web -[otel-api]: https://github.com/open-telemetry/opentelemetry-js-api +[otel-api]: https://github.com/open-telemetry/opentelemetry-js/tree/main/api [otel-core]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-core [otel-propagator-b3]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-propagator-b3 diff --git a/api/README.md b/api/README.md index dc44969675..56dd23d177 100644 --- a/api/README.md +++ b/api/README.md @@ -1,38 +1,17 @@ - ---- -

      - - API Documentation -   •   - Getting In Touch (GitHub Discussions) - -

      +# OpenTelemetry API for JavaScript

      - - GitHub release (latest by date including pre-releases) - - - Codecov Status - - - license - -
      - - Build Status - - - Build Status + +API Reference +  •   +Documentation +
      + + NPM Release +

      ---- - -# OpenTelemetry API for JavaScript - -[![NPM Published Version][npm-img]][npm-url] - This package provides everything needed to interact with the OpenTelemetry API, including all TypeScript interfaces, enums, and no-op implementations. It is intended for use both on the server and in the browser. The methods in this package perform no operations by default. This means they can be safely called by a library or end-user application whether there is an SDK registered or not. In order to generate and export telemetry data, you will also need an SDK such as the [OpenTelemetry JS SDK][opentelemetry-js]. @@ -134,7 +113,5 @@ Apache 2.0 - See [LICENSE][license-url] for more information. [discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions [license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/api/LICENSE [license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat -[npm-url]: https://www.npmjs.com/package/@opentelemetry/api -[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi.svg [docs-tracing]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/tracing.md [docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/sdk-registration.md diff --git a/doc/context.md b/doc/context.md index 4f3d8bd2bb..d49f8e44ec 100644 --- a/doc/context.md +++ b/doc/context.md @@ -7,7 +7,7 @@ This document describes the OpenTelemetry context API for JavaScript and how it _Context Specification: _ -_Context API Reference: _ +_Context API Reference: _ - [Context Manager](#context-manager) - [Root Context](#root-context) diff --git a/doc/sdk-registration.md b/doc/sdk-registration.md index 2d6490c9bb..a7a3bc72b7 100644 --- a/doc/sdk-registration.md +++ b/doc/sdk-registration.md @@ -23,6 +23,6 @@ api.propagation.setGlobalPropagator(httpTraceContextPropagator); api.context.setGlobalContextManager(asyncHooksContextManager); ``` -[trace-api-docs]: https://open-telemetry.github.io/opentelemetry-js-api/classes/traceapi.html -[propagation-api-docs]: https://open-telemetry.github.io/opentelemetry-js-api/classes/propagationapi.html -[context-api-docs]: https://open-telemetry.github.io/opentelemetry-js-api/classes/contextapi.html +[trace-api-docs]: https://open-telemetry.github.io/opentelemetry-js/classes/_opentelemetry_api.TraceAPI.html +[propagation-api-docs]: https://open-telemetry.github.io/opentelemetry-js/classes/_opentelemetry_api.PropagationAPI.html +[context-api-docs]: https://open-telemetry.github.io/opentelemetry-js/classes/_opentelemetry_api.ContextAPI.html diff --git a/doc/tracing.md b/doc/tracing.md index ba13dc22a1..ea3e38284b 100644 --- a/doc/tracing.md +++ b/doc/tracing.md @@ -6,7 +6,7 @@ For a high-level overview of OpenTelemetry tracing in general and definitions of _Trace API Specification: _ -_Trace API Reference: _ +_Trace API Reference: _ - [Acquiring a Tracer](#acquiring-a-tracer) - [Starting and Ending a Span](#starting-and-ending-a-span) @@ -23,7 +23,7 @@ _Trace API Reference: Date: Sun, 13 Nov 2022 16:18:49 +0100 Subject: [PATCH 68/77] chore: remove experimental note in sdk-metrics (#3403) --- packages/sdk-metrics/README.md | 2 -- packages/sdk-metrics/package.json | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/sdk-metrics/README.md b/packages/sdk-metrics/README.md index ab5f2dd0a0..78bd3c000d 100644 --- a/packages/sdk-metrics/README.md +++ b/packages/sdk-metrics/README.md @@ -3,8 +3,6 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] -**Note: This is an experimental package under active development. New releases may include breaking changes.** - OpenTelemetry metrics module contains the foundation for all metrics SDKs of [opentelemetry-js](https://github.com/open-telemetry/opentelemetry-js). Used standalone, this module provides methods for manual instrumentation of code, offering full control over recording metrics for client-side JavaScript (browser) and Node.js. diff --git a/packages/sdk-metrics/package.json b/packages/sdk-metrics/package.json index f1c9e29474..f799b62b78 100644 --- a/packages/sdk-metrics/package.json +++ b/packages/sdk-metrics/package.json @@ -1,7 +1,7 @@ { "name": "@opentelemetry/sdk-metrics", "version": "1.8.0", - "description": "Work in progress OpenTelemetry metrics SDK", + "description": "OpenTelemetry metrics SDK", "main": "build/src/index.js", "module": "build/esm/index.js", "esnext": "build/esnext/index.js", @@ -81,6 +81,6 @@ "@opentelemetry/resources": "1.8.0", "lodash.merge": "4.6.2" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-metrics", + "homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/sdk-metrics", "sideEffects": false } From b4f04ae01da8925bdd828975f3271174347d7b16 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Sun, 13 Nov 2022 23:42:26 +0800 Subject: [PATCH 69/77] feat(instrumentation-http): monitor error events with events.errorMonitor (#3402) Co-authored-by: Valentin Marchaud --- experimental/CHANGELOG.md | 2 + .../src/http.ts | 5 ++- .../test/functionals/http-enable.test.ts | 45 ++++++++++--------- .../test/functionals/https-enable.test.ts | 45 ++++++++++--------- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 6c180c18d5..f0e7bf5ab3 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) +* feat(instrumentation-http): monitor error events with events.errorMonitor [#3402](https://github.com/open-telemetry/opentelemetry-js/pull/3402) @legendecas + ### :bug: (Bug Fix) ### :books: (Refine Doc) diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts index 4129759589..71f3363f2d 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts @@ -54,6 +54,7 @@ import { safeExecuteInTheMiddle, } from '@opentelemetry/instrumentation'; import { RPCMetadata, RPCType, setRPCMetadata } from '@opentelemetry/core'; +import { errorMonitor } from 'events'; /** * Http instrumentation instrumentation for Opentelemetry @@ -361,7 +362,7 @@ export class HttpInstrumentation extends InstrumentationBase { this._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes); }); - response.on('error', (error: Err) => { + response.on(errorMonitor, (error: Err) => { this._diag.debug('outgoingRequest on error()', error); utils.setSpanWithError(span, error); const code = utils.parseResponseStatus(SpanKind.CLIENT, response.statusCode); @@ -376,7 +377,7 @@ export class HttpInstrumentation extends InstrumentationBase { this._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes); } }); - request.on('error', (error: Err) => { + request.on(errorMonitor, (error: Err) => { this._diag.debug('outgoingRequest on request error()', error); utils.setSpanWithError(span, error); this._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts index bee473ed3d..ecf5191427 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts @@ -670,21 +670,21 @@ describe('HttpInstrumentation', () => { ); req.setTimeout(10, () => { req.abort(); - reject('timeout'); + }); + // Instrumentation should not swallow error event. + assert.strictEqual(req.listeners('error').length, 0); + req.on('error', err => { + reject(err); }); return req.end(); }); - try { - await promiseRequest; - assert.fail(); - } catch (error) { - const spans = memoryExporter.getFinishedSpans(); - const [span] = spans; - assert.strictEqual(spans.length, 1); - assert.strictEqual(span.status.code, SpanStatusCode.ERROR); - assert.ok(Object.keys(span.attributes).length >= 6); - } + await assert.rejects(promiseRequest, /Error: socket hang up/); + const spans = memoryExporter.getFinishedSpans(); + const [span] = spans; + assert.strictEqual(spans.length, 1); + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.ok(Object.keys(span.attributes).length >= 6); }); it('should have 1 ended span when request is aborted after receiving response', async () => { @@ -701,7 +701,7 @@ describe('HttpInstrumentation', () => { (resp: http.IncomingMessage) => { let data = ''; resp.on('data', chunk => { - req.destroy(Error()); + req.destroy(Error('request destroyed')); data += chunk; }); resp.on('end', () => { @@ -709,20 +709,21 @@ describe('HttpInstrumentation', () => { }); } ); + // Instrumentation should not swallow error event. + assert.strictEqual(req.listeners('error').length, 0); + req.on('error', err => { + reject(err); + }); return req.end(); }); - try { - await promiseRequest; - assert.fail(); - } catch (error) { - const spans = memoryExporter.getFinishedSpans(); - const [span] = spans; - assert.strictEqual(spans.length, 1); - assert.strictEqual(span.status.code, SpanStatusCode.ERROR); - assert.ok(Object.keys(span.attributes).length > 7); - } + await assert.rejects(promiseRequest, /Error: request destroyed/); + const spans = memoryExporter.getFinishedSpans(); + const [span] = spans; + assert.strictEqual(spans.length, 1); + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.ok(Object.keys(span.attributes).length > 7); }); it("should have 1 ended client span when request doesn't listening response", done => { diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-enable.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-enable.test.ts index 2611642b4c..5cfe4ac953 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-enable.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-enable.test.ts @@ -639,21 +639,21 @@ describe('HttpsInstrumentation', () => { ); req.setTimeout(10, () => { req.abort(); - reject('timeout'); + }); + // Instrumentation should not swallow error event. + assert.strictEqual(req.listeners('error').length, 0); + req.on('error', err => { + reject(err); }); return req.end(); }); - try { - await promiseRequest; - assert.fail(); - } catch (error) { - const spans = memoryExporter.getFinishedSpans(); - const [span] = spans; - assert.strictEqual(spans.length, 1); - assert.strictEqual(span.status.code, SpanStatusCode.ERROR); - assert.ok(Object.keys(span.attributes).length >= 6); - } + await assert.rejects(promiseRequest, /Error: socket hang up/); + const spans = memoryExporter.getFinishedSpans(); + const [span] = spans; + assert.strictEqual(spans.length, 1); + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.ok(Object.keys(span.attributes).length >= 6); }); it('should have 1 ended span when request is aborted after receiving response', async () => { @@ -670,7 +670,7 @@ describe('HttpsInstrumentation', () => { (resp: http.IncomingMessage) => { let data = ''; resp.on('data', chunk => { - req.destroy(Error()); + req.destroy(Error('request destroyed')); data += chunk; }); resp.on('end', () => { @@ -678,20 +678,21 @@ describe('HttpsInstrumentation', () => { }); } ); + // Instrumentation should not swallow error event. + assert.strictEqual(req.listeners('error').length, 0); + req.on('error', err => { + reject(err); + }); return req.end(); }); - try { - await promiseRequest; - assert.fail(); - } catch (error) { - const spans = memoryExporter.getFinishedSpans(); - const [span] = spans; - assert.strictEqual(spans.length, 1); - assert.strictEqual(span.status.code, SpanStatusCode.ERROR); - assert.ok(Object.keys(span.attributes).length > 7); - } + await assert.rejects(promiseRequest, /Error: request destroyed/); + const spans = memoryExporter.getFinishedSpans(); + const [span] = spans; + assert.strictEqual(spans.length, 1); + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.ok(Object.keys(span.attributes).length > 7); }); it("should have 1 ended span when response is listened by using req.on('response')", done => { From c032493d09069bb0abff27ebccd4e68e6e35f036 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sun, 13 Nov 2022 17:06:32 +0100 Subject: [PATCH 70/77] chore(deps): update dependency lerna to v6 (#3333) Co-authored-by: Valentin Marchaud --- package.json | 2 +- packages/opentelemetry-core/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4be8d6e76b..716db784bb 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "eslint-plugin-header": "3.1.1", "eslint-plugin-node": "11.1.0", "gh-pages": "4.0.0", - "lerna": "5.4.3", + "lerna": "6.0.3", "lerna-changelog": "2.2.0", "linkinator": "4.0.3", "markdownlint-cli": "0.32.2", diff --git a/packages/opentelemetry-core/package.json b/packages/opentelemetry-core/package.json index 7803c09beb..7fa8b1d418 100644 --- a/packages/opentelemetry-core/package.json +++ b/packages/opentelemetry-core/package.json @@ -77,7 +77,7 @@ "karma-mocha": "2.0.1", "karma-spec-reporter": "0.0.32", "karma-webpack": "4.0.2", - "lerna": "5.4.3", + "lerna": "6.0.3", "mocha": "10.0.0", "nyc": "15.1.0", "rimraf": "3.0.2", From 1b7246abb49164ec5c2cff7b66956c454f230fed Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 15 Nov 2022 06:38:29 +0100 Subject: [PATCH 71/77] chore(deps): update actions/stale action to v6 (#3273) --- .github/workflows/close-stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/close-stale.yml b/.github/workflows/close-stale.yml index 122ab1c931..c26c21ca56 100644 --- a/.github/workflows/close-stale.yml +++ b/.github/workflows/close-stale.yml @@ -7,7 +7,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v5 + - uses: actions/stale@v6 with: days-before-stale: 60 days-before-close: 14 From 125f11e721a49119cd5cae437213cf394ae96ea1 Mon Sep 17 00:00:00 2001 From: Marc Pichler Date: Tue, 15 Nov 2022 16:43:41 +0100 Subject: [PATCH 72/77] fix(sdk-metrics): use default Resource to comply with semconv (#3411) * fix(sdk-metrics): use default Resource to comply with semantic conventions * fix(prometheus-exporter): escape default resource attribute values * fix(changelog): use correct pr number --- CHANGELOG.md | 7 ++++ .../test/metricsHelper.ts | 4 +- .../test/metricsHelper.ts | 4 +- .../package.json | 1 + .../test/PrometheusExporter.test.ts | 42 +++++++++++-------- .../test/PrometheusSerializer.test.ts | 14 ++++--- .../test/util.ts | 11 +++++ .../tsconfig.json | 3 ++ packages/sdk-metrics/src/MeterProvider.ts | 3 +- packages/sdk-metrics/test/util.ts | 4 +- 10 files changed, 63 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 545e002cd8..d605eff3e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,13 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/ ### :bug: (Bug Fix) +* fix(sdk-metrics): use default Resource to comply with semantic conventions [#3411](https://github.com/open-telemetry/opentelemetry-js/pull/3411) @pichlermarc + * Metrics exported by the SDK now contain the following resource attributes by default: + * `service.name` + * `telemetry.sdk.name` + * `telemetry.sdk.language` + * `telemetry.sdk.version` + ### :books: (Refine Doc) ### :house: (Internal) diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts index e7f2baa351..9a11c8b6f2 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts @@ -37,11 +37,11 @@ class TestMetricReader extends MetricReader { } } -const testResource = Resource.default().merge(new Resource({ +const testResource = new Resource({ service: 'ui', version: 1, cost: 112.12, -})); +}); let meterProvider = new MeterProvider({ resource: testResource }); diff --git a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts index ce3a70ff24..d86775d332 100644 --- a/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts +++ b/experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts @@ -42,11 +42,11 @@ export class TestMetricReader extends MetricReader { } } -const testResource = Resource.default().merge(new Resource({ +const testResource = new Resource({ service: 'ui', version: 1, cost: 112.12, -})); +}); let meterProvider = new MeterProvider({ resource: testResource }); diff --git a/experimental/packages/opentelemetry-exporter-prometheus/package.json b/experimental/packages/opentelemetry-exporter-prometheus/package.json index 8d6c32a868..0a36b920e4 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/package.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/package.json @@ -44,6 +44,7 @@ }, "devDependencies": { "@opentelemetry/api": "^1.3.0", + "@opentelemetry/semantic-conventions": "1.8.0", "@types/mocha": "10.0.0", "@types/node": "18.6.5", "@types/sinon": "10.0.13", diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts index 3104348300..31137bd156 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts @@ -26,14 +26,20 @@ import * as http from 'http'; import { PrometheusExporter } from '../src'; import { mockedHrTimeMs, - mockHrTime + mockHrTime, + sdkLanguage, + sdkName, + sdkVersion, + serviceName } from './util'; import { SinonStubbedInstance } from 'sinon'; -const serializedEmptyResourceLines = [ +const infoLine = `target_info{service_name="${serviceName}",telemetry_sdk_language="${sdkLanguage}",telemetry_sdk_name="${sdkName}",telemetry_sdk_version="${sdkVersion}"} 1`; + +const serializedDefaultResourceLines = [ '# HELP target_info Target metadata', '# TYPE target_info gauge', - 'target_info 1' + infoLine ]; describe('PrometheusExporter', () => { @@ -261,12 +267,12 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.strictEqual( - lines[serializedEmptyResourceLines.length], + lines[serializedDefaultResourceLines.length], '# HELP counter_total a test description' ); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP counter_total a test description', '# TYPE counter_total counter', `counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -296,7 +302,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP metric_observable_gauge a test description', '# TYPE metric_observable_gauge gauge', `metric_observable_gauge{pid="123",core="1"} 0.999 ${mockedHrTimeMs}`, @@ -316,7 +322,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP counter_total a test description', '# TYPE counter_total counter', `counter_total{counterKey1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -351,7 +357,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# no registered metrics' ]); }); @@ -365,7 +371,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP counter_total description missing', '# TYPE counter_total counter', `counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -382,7 +388,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP counter_bad_name_total description missing', '# TYPE counter_bad_name_total counter', `counter_bad_name_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -400,7 +406,7 @@ describe('PrometheusExporter', () => { const body = await request('http://localhost:9464/metrics'); const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP counter a test description', '# TYPE counter gauge', `counter{key1="attributeValue1"} 20 ${mockedHrTimeMs}`, @@ -429,7 +435,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP metric_observable_counter a test description', '# TYPE metric_observable_counter counter', `metric_observable_counter{key1="attributeValue1"} 20 ${mockedHrTimeMs}`, @@ -458,7 +464,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP metric_observable_up_down_counter a test description', '# TYPE metric_observable_up_down_counter gauge', `metric_observable_up_down_counter{key1="attributeValue1"} 20 ${mockedHrTimeMs}`, @@ -477,7 +483,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP test_histogram a test description', '# TYPE test_histogram histogram', `test_histogram_count{key1="attributeValue1"} 1 ${mockedHrTimeMs}`, @@ -531,7 +537,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP test_prefix_counter_total description missing', '# TYPE test_prefix_counter_total counter', `test_prefix_counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -560,7 +566,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP counter_total description missing', '# TYPE counter_total counter', `counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -589,7 +595,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP counter_total description missing', '# TYPE counter_total counter', `counter_total{key1="attributeValue1"} 10 ${mockedHrTimeMs}`, @@ -618,7 +624,7 @@ describe('PrometheusExporter', () => { const lines = body.split('\n'); assert.deepStrictEqual(lines, [ - ...serializedEmptyResourceLines, + ...serializedDefaultResourceLines, '# HELP counter_total description missing', '# TYPE counter_total counter', 'counter_total{key1="attributeValue1"} 10', diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts index 2694c96f83..a4792eef54 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts @@ -36,7 +36,11 @@ import * as sinon from 'sinon'; import { PrometheusSerializer } from '../src'; import { mockedHrTimeMs, - mockHrTime + mockHrTime, + sdkLanguage, + sdkName, + sdkVersion, + serviceName } from './util'; import { Resource } from '@opentelemetry/resources'; @@ -45,10 +49,10 @@ const attributes = { foo2: 'bar2', }; -const serializedEmptyResource = +const serializedDefaultResource = '# HELP target_info Target metadata\n' + '# TYPE target_info gauge\n' + - 'target_info 1\n'; + `target_info{service_name="${serviceName}",telemetry_sdk_language="${sdkLanguage}",telemetry_sdk_name="${sdkName}",telemetry_sdk_version="${sdkVersion}"} 1\n`; class TestMetricReader extends MetricReader { constructor() { @@ -477,7 +481,7 @@ describe('PrometheusSerializer', () => { const result = await getCounterResult('test', serializer, { unit: unitOfMetric, exportAll: true }); assert.strictEqual( result, - serializedEmptyResource + + serializedDefaultResource + '# HELP test_total description missing\n' + `# UNIT test_total ${unitOfMetric}\n` + '# TYPE test_total counter\n' + @@ -491,7 +495,7 @@ describe('PrometheusSerializer', () => { const result = await getCounterResult('test', serializer, { exportAll: true }); assert.strictEqual( result, - serializedEmptyResource + + serializedDefaultResource + '# HELP test_total description missing\n' + '# TYPE test_total counter\n' + `test_total 1 ${mockedHrTimeMs}\n` diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/util.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/util.ts index 49536a5a35..8caa7795cd 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/util.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/util.ts @@ -16,6 +16,8 @@ import * as sinon from 'sinon'; import * as perf_hooks from 'perf_hooks'; +import { Resource } from '@opentelemetry/resources'; +import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; export const mockedHrTimeMs = 1586347902211; @@ -25,3 +27,12 @@ export function mockHrTime() { sinon.stub(perf_hooks.performance, 'timeOrigin').value(0); sinon.stub(perf_hooks.performance, 'now').returns(mockedHrTimeMs); } + +export const serviceName = Resource.default().attributes[SemanticResourceAttributes.SERVICE_NAME]?.toString() + .replace(/\\/g, '\\\\').replace(/\n/g, '\\n'); +export const sdkLanguage = Resource.default().attributes[SemanticResourceAttributes.TELEMETRY_SDK_LANGUAGE]?.toString() + .replace(/\\/g, '\\\\').replace(/\n/g, '\\n'); +export const sdkName = Resource.default().attributes[SemanticResourceAttributes.TELEMETRY_SDK_NAME]?.toString() + .replace(/\\/g, '\\\\').replace(/\n/g, '\\n'); +export const sdkVersion = Resource.default().attributes[SemanticResourceAttributes.TELEMETRY_SDK_VERSION]?.toString() + .replace(/\\/g, '\\\\').replace(/\n/g, '\\n'); diff --git a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json index f0e9f90992..cd21ec8274 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json +++ b/experimental/packages/opentelemetry-exporter-prometheus/tsconfig.json @@ -18,6 +18,9 @@ { "path": "../../../packages/opentelemetry-resources" }, + { + "path": "../../../packages/opentelemetry-semantic-conventions" + }, { "path": "../../../packages/sdk-metrics" } diff --git a/packages/sdk-metrics/src/MeterProvider.ts b/packages/sdk-metrics/src/MeterProvider.ts index 01c3f54a1b..13b17fb564 100644 --- a/packages/sdk-metrics/src/MeterProvider.ts +++ b/packages/sdk-metrics/src/MeterProvider.ts @@ -45,7 +45,8 @@ export class MeterProvider implements IMeterProvider { private _shutdown = false; constructor(options?: MeterProviderOptions) { - this._sharedState = new MeterProviderSharedState(options?.resource ?? Resource.empty()); + const resource = Resource.default().merge(options?.resource ?? Resource.empty()); + this._sharedState = new MeterProviderSharedState(resource); if(options?.views != null && options.views.length > 0){ for(const view of options.views){ this._sharedState.viewRegistry.addView(view); diff --git a/packages/sdk-metrics/test/util.ts b/packages/sdk-metrics/test/util.ts index 80f9ab1c49..7227698a93 100644 --- a/packages/sdk-metrics/test/util.ts +++ b/packages/sdk-metrics/test/util.ts @@ -43,9 +43,9 @@ export type Measurement = { context?: Context; }; -export const defaultResource = new Resource({ +export const defaultResource = Resource.default().merge(new Resource({ resourceKey: 'my-resource', -}); +})); export const defaultInstrumentDescriptor: InstrumentDescriptor = { name: 'default_metric', From bd565475a9b7e273b2f9f3f4931fe1e7d3c9a26d Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Wed, 16 Nov 2022 00:50:00 +0800 Subject: [PATCH 73/77] fix(api): disable module concatenation in tree-shaking test (#3409) Co-authored-by: Daniel Dyla --- api/CHANGELOG.md | 4 ++++ api/test/tree-shaking/tree-shaking.test.ts | 2 ++ 2 files changed, 6 insertions(+) diff --git a/api/CHANGELOG.md b/api/CHANGELOG.md index 12b33c4e2c..983a0261ce 100644 --- a/api/CHANGELOG.md +++ b/api/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## Unreleased + +* test(api): disable module concatenation in tree-shaking test [#3409](https://github.com/open-telemetry/opentelemetry-js/pull/3409) @legendecas + ## [1.3.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.2.0...v1.3.0) * feat(api): merge api-metrics into api [#3374](https://github.com/open-telemetry/opentelemetry-js/pull/3374) @legendecas diff --git a/api/test/tree-shaking/tree-shaking.test.ts b/api/test/tree-shaking/tree-shaking.test.ts index 37ab5def3a..5c75b8e9d5 100644 --- a/api/test/tree-shaking/tree-shaking.test.ts +++ b/api/test/tree-shaking/tree-shaking.test.ts @@ -74,6 +74,8 @@ describe('tree-shaking', () => { optimization: { // disable minimization so that we can inspect the output easily. minimize: false, + // disable module concatenation so that variable names will not be mangled. + concatenateModules: false, } }); From e133f3f5c3d9467c5c96df14a5fdd6c43706d450 Mon Sep 17 00:00:00 2001 From: Amir Blum Date: Wed, 16 Nov 2022 21:11:53 +0200 Subject: [PATCH 74/77] fix(api): deprecate MetricAttributes and MetricAttributeValue (#3406) * docs: fix comment in metrics api refering to span * fix(api): deprecate MetricsAttributes and MetricAttributeValue * fix: typo in changelog Co-authored-by: Daniel Dyla --- api/CHANGELOG.md | 1 + api/src/metrics/Metric.ts | 10 ++-------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/api/CHANGELOG.md b/api/CHANGELOG.md index 983a0261ce..3784f8abc8 100644 --- a/api/CHANGELOG.md +++ b/api/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ## Unreleased +* fix(api): deprecate MetricAttributes and MetricAttributeValue [#3406](https://github.com/open-telemetry/opentelemetry-js/pull/3406) @blumamir * test(api): disable module concatenation in tree-shaking test [#3409](https://github.com/open-telemetry/opentelemetry-js/pull/3409) @legendecas ## [1.3.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.2.0...v1.3.0) diff --git a/api/src/metrics/Metric.ts b/api/src/metrics/Metric.ts index d0b6909bd7..687369b92f 100644 --- a/api/src/metrics/Metric.ts +++ b/api/src/metrics/Metric.ts @@ -83,19 +83,13 @@ export interface Histogram Date: Fri, 18 Nov 2022 10:00:13 +0100 Subject: [PATCH 75/77] chore(deps): update dependency chromedriver to v107 (#3382) --- selenium-tests/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selenium-tests/package.json b/selenium-tests/package.json index fc1ec5f3c0..7ede549bee 100644 --- a/selenium-tests/package.json +++ b/selenium-tests/package.json @@ -40,7 +40,7 @@ "babel-loader": "8.2.3", "babel-polyfill": "6.26.0", "browserstack-local": "1.4.8", - "chromedriver": "104.0.0", + "chromedriver": "107.0.3", "dotenv": "16.0.0", "fast-safe-stringify": "2.1.1", "geckodriver": "3.0.1", From b29deeed5029598385aedd30f9b540b1248bea52 Mon Sep 17 00:00:00 2001 From: Osher Vaknin <81672378+osherv@users.noreply.github.com> Date: Sun, 20 Nov 2022 17:28:26 +0200 Subject: [PATCH 76/77] feat(instrumentation): add new setMeterInstruments method (#3267) Co-authored-by: Chengzhong Wu Fixes https://github.com/open-telemetry/opentelemetry-js/issues/3249 --- experimental/CHANGELOG.md | 1 + .../src/http.ts | 11 ++------ .../package.json | 1 + .../src/instrumentation.ts | 10 +++++++ .../test/common/Instrumentation.test.ts | 27 ++++++++++++++++++- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index f0e7bf5ab3..7d39f3e228 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) * feat(instrumentation-http): monitor error events with events.errorMonitor [#3402](https://github.com/open-telemetry/opentelemetry-js/pull/3402) @legendecas +* feat(instrumentation): add new `_setMeterInstruments` protected method that update the meter instruments every meter provider update. ### :bug: (Bug Fix) diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts index 71f3363f2d..0f19ffd867 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts @@ -26,9 +26,8 @@ import { SpanStatusCode, trace, Histogram, - MeterProvider, MetricAttributes, - ValueType, + ValueType } from '@opentelemetry/api'; import { hrTime, hrTimeDuration, hrTimeToMilliseconds, suppressTracing } from '@opentelemetry/core'; import type * as http from 'http'; @@ -74,15 +73,9 @@ export class HttpInstrumentation extends InstrumentationBase { config ); this._headerCapture = this._createHeaderCapture(); - this._updateMetricInstruments(); } - override setMeterProvider(meterProvider: MeterProvider) { - super.setMeterProvider(meterProvider); - this._updateMetricInstruments(); - } - - private _updateMetricInstruments() { + protected override _updateMetricInstruments() { this._httpServerDurationHistogram = this.meter.createHistogram('http.server.duration', { description: 'measures the duration of the inbound HTTP requests', unit: 'ms', diff --git a/experimental/packages/opentelemetry-instrumentation/package.json b/experimental/packages/opentelemetry-instrumentation/package.json index 29b186d510..8dc3dfb9d2 100644 --- a/experimental/packages/opentelemetry-instrumentation/package.json +++ b/experimental/packages/opentelemetry-instrumentation/package.json @@ -76,6 +76,7 @@ "@opentelemetry/api": "^1.3.0" }, "devDependencies": { + "@opentelemetry/sdk-metrics": "^1.8.0", "@babel/core": "7.16.0", "@opentelemetry/api": "^1.3.0", "@types/mocha": "10.0.0", diff --git a/experimental/packages/opentelemetry-instrumentation/src/instrumentation.ts b/experimental/packages/opentelemetry-instrumentation/src/instrumentation.ts index 5024b5d536..d562ed9056 100644 --- a/experimental/packages/opentelemetry-instrumentation/src/instrumentation.ts +++ b/experimental/packages/opentelemetry-instrumentation/src/instrumentation.ts @@ -56,6 +56,7 @@ implements types.Instrumentation { this._tracer = trace.getTracer(instrumentationName, instrumentationVersion); this._meter = metrics.getMeter(instrumentationName, instrumentationVersion); + this._updateMetricInstruments(); } /* Api to wrap instrumented method */ @@ -81,6 +82,15 @@ implements types.Instrumentation { this.instrumentationName, this.instrumentationVersion ); + + this._updateMetricInstruments(); + } + + /** + * Sets the new metric instruments with the current Meter. + */ + protected _updateMetricInstruments(): void { + return; } /* Returns InstrumentationConfig */ diff --git a/experimental/packages/opentelemetry-instrumentation/test/common/Instrumentation.test.ts b/experimental/packages/opentelemetry-instrumentation/test/common/Instrumentation.test.ts index ac0c5b0a90..be53d1ca59 100644 --- a/experimental/packages/opentelemetry-instrumentation/test/common/Instrumentation.test.ts +++ b/experimental/packages/opentelemetry-instrumentation/test/common/Instrumentation.test.ts @@ -21,6 +21,8 @@ import { InstrumentationConfig, } from '../../src'; +import { MeterProvider } from '@opentelemetry/sdk-metrics'; + interface TestInstrumentationConfig extends InstrumentationConfig { isActive?: boolean; } @@ -54,13 +56,36 @@ describe('BaseInstrumentation', () => { describe('constructor', () => { it('should enable instrumentation by default', () => { - let called = false; + let enableCalled = false; + let updateMetricInstrumentsCalled = false; class TestInstrumentation2 extends TestInstrumentation { override enable() { + enableCalled = true; + } + override _updateMetricInstruments() { + updateMetricInstrumentsCalled = true; + } + } + instrumentation = new TestInstrumentation2(); + assert.strictEqual(enableCalled, true); + assert.strictEqual(updateMetricInstrumentsCalled, true); + }); + }); + + describe('setMeterProvider', () => { + let otelTestingMeterProvider: MeterProvider; + beforeEach(() => { + otelTestingMeterProvider = new MeterProvider(); + }); + it('should call _updateMetricInstruments', () => { + let called = true; + class TestInstrumentation2 extends TestInstrumentation { + override _updateMetricInstruments() { called = true; } } instrumentation = new TestInstrumentation2(); + instrumentation.setMeterProvider(otelTestingMeterProvider); assert.strictEqual(called, true); }); }); From b9f5561d1994424282c822a3792a2d1689d544d2 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Sun, 20 Nov 2022 07:50:16 -0800 Subject: [PATCH 77/77] Add getActiveBaggage API (#3385) Co-authored-by: Valentin Marchaud Resolves https://github.com/open-telemetry/opentelemetry-js/issues/3354 --- CHANGELOG.md | 2 ++ api/src/api/propagation.ts | 3 +++ api/src/baggage/context-helpers.ts | 10 ++++++++++ api/test/common/baggage/Baggage.test.ts | 15 +++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d605eff3e1..ab76cfe617 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/ ### :rocket: (Enhancement) +* feat(api): add `getActiveBaggage` API [#3385](https://github.com/open-telemetry/opentelemetry-js/pull/3385) + ### :bug: (Bug Fix) * fix(sdk-metrics): use default Resource to comply with semantic conventions [#3411](https://github.com/open-telemetry/opentelemetry-js/pull/3411) @pichlermarc diff --git a/api/src/api/propagation.ts b/api/src/api/propagation.ts index 2cd9aec760..24c9c1f73f 100644 --- a/api/src/api/propagation.ts +++ b/api/src/api/propagation.ts @@ -30,6 +30,7 @@ import { } from '../propagation/TextMapPropagator'; import { getBaggage, + getActiveBaggage, setBaggage, deleteBaggage, } from '../baggage/context-helpers'; @@ -112,6 +113,8 @@ export class PropagationAPI { public getBaggage = getBaggage; + public getActiveBaggage = getActiveBaggage; + public setBaggage = setBaggage; public deleteBaggage = deleteBaggage; diff --git a/api/src/baggage/context-helpers.ts b/api/src/baggage/context-helpers.ts index ae7b4a78e0..93a5ffca83 100644 --- a/api/src/baggage/context-helpers.ts +++ b/api/src/baggage/context-helpers.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { ContextAPI } from '../api/context'; import { createContextKey } from '../context/context'; import { Context } from '../context/types'; import { Baggage } from './types'; @@ -33,6 +34,15 @@ export function getBaggage(context: Context): Baggage | undefined { return (context.getValue(BAGGAGE_KEY) as Baggage) || undefined; } +/** + * Retrieve the current baggage from the active/current context + * + * @returns {Baggage} Extracted baggage from the context + */ +export function getActiveBaggage(): Baggage | undefined { + return getBaggage(ContextAPI.getInstance().active()); +} + /** * Store a baggage in the given context * diff --git a/api/test/common/baggage/Baggage.test.ts b/api/test/common/baggage/Baggage.test.ts index 81895306c0..28401c0524 100644 --- a/api/test/common/baggage/Baggage.test.ts +++ b/api/test/common/baggage/Baggage.test.ts @@ -16,6 +16,7 @@ import * as assert from 'assert'; import { + context, ROOT_CONTEXT, propagation, baggageEntryMetadataFromString, @@ -131,6 +132,20 @@ describe('Baggage', () => { assert.strictEqual(bag, propagation.getBaggage(ctx)); }); + + it('should get the current baggage', () => { + const entries = { + 'banana': {value: 'boats'} + }; + const bag = propagation.createBaggage(entries); + const ctx = propagation.setBaggage(ROOT_CONTEXT, bag); + + context.setGlobalContextManager({ active: () => ctx, disable: () => {} } as any); + + assert.strictEqual(bag, propagation.getActiveBaggage()); + + context.disable(); + }); }); describe('metadata', () => {