From 5bb83224be3afd54fa9cf197a8e70550306b96f1 Mon Sep 17 00:00:00 2001 From: legendecas Date: Wed, 3 Nov 2021 02:14:48 +0800 Subject: [PATCH] feat(api-metrics): remove bind/unbind and bound instruments (#2559) Co-authored-by: Valentin Marchaud Co-authored-by: Daniel Dyla --- examples/otlp-exporter-node/metrics.js | 6 +- examples/prometheus/index.js | 4 +- examples/tracer-web/examples/metrics/index.js | 4 +- .../src/NoopMeter.ts | 104 +++--------------- .../opentelemetry-api-metrics/src/index.ts | 1 - .../src/types/BoundInstrument.ts | 38 ------- .../src/types/Metric.ts | 48 +------- .../noop-implementations/noop-meter.test.ts | 10 +- .../README.md | 5 - .../test/PrometheusExporter.test.ts | 28 +++-- .../test/PrometheusLabelsBatcher.test.ts | 8 +- .../test/PrometheusSerializer.test.ts | 74 ++++++------- .../opentelemetry-sdk-metrics-base/README.md | 12 +- .../src/BatchObserverResult.ts | 4 +- .../src/BoundInstrument.ts | 10 +- .../src/Metric.ts | 3 +- .../test/Meter.test.ts | 24 ++-- .../test/MeterProvider.test.ts | 2 +- .../test/Processor.test.ts | 9 +- .../test/export/ConsoleMetricExporter.test.ts | 4 +- .../test/export/Controller.test.ts | 6 +- 21 files changed, 114 insertions(+), 290 deletions(-) delete mode 100644 experimental/packages/opentelemetry-api-metrics/src/types/BoundInstrument.ts diff --git a/examples/otlp-exporter-node/metrics.js b/examples/otlp-exporter-node/metrics.js index 3a2294f43f..cb90169405 100644 --- a/examples/otlp-exporter-node/metrics.js +++ b/examples/otlp-exporter-node/metrics.js @@ -38,7 +38,7 @@ const histogram = meter.createHistogram('test_histogram', { const labels = { pid: process.pid, environment: 'staging' }; setInterval(() => { - requestCounter.bind(labels).add(1); - upDownCounter.bind(labels).add(Math.random() > 0.5 ? 1 : -1); - histogram.bind(labels).record(Math.random()); + requestCounter.add(1, labels); + upDownCounter.add(Math.random() > 0.5 ? 1 : -1, labels); + histogram.record(Math.random(), labels); }, 1000); diff --git a/examples/prometheus/index.js b/examples/prometheus/index.js index e486c2701e..ea3f2e6882 100644 --- a/examples/prometheus/index.js +++ b/examples/prometheus/index.js @@ -30,6 +30,6 @@ const upDownCounter = meter.createUpDownCounter('test_up_down_counter', { const labels = { pid: process.pid, environment: 'staging' }; setInterval(() => { - requestCounter.bind(labels).add(1); - upDownCounter.bind(labels).add(Math.random() > 0.5 ? 1 : -1); + requestCounter.add(1, labels); + upDownCounter.add(Math.random() > 0.5 ? 1 : -1, labels); }, 1000); diff --git a/examples/tracer-web/examples/metrics/index.js b/examples/tracer-web/examples/metrics/index.js index 53d6ac6a07..e067e30c7e 100644 --- a/examples/tracer-web/examples/metrics/index.js +++ b/examples/tracer-web/examples/metrics/index.js @@ -41,8 +41,8 @@ function startMetrics() { const labels = { pid: process.pid, environment: 'staging' }; interval = setInterval(() => { - requestCounter.bind(labels).add(1); - upDownCounter.bind(labels).add(Math.random() > 0.5 ? 1 : -1); + requestCounter.add(1, labels); + upDownCounter.add(Math.random() > 0.5 ? 1 : -1, labels); }, 1000); } diff --git a/experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts b/experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts index 775ad78f00..d60562fe78 100644 --- a/experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts +++ b/experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts @@ -18,7 +18,6 @@ import { BatchObserverResult } from './types/BatchObserverResult'; import { Meter } from './types/Meter'; import { MetricOptions, - UnboundMetric, Labels, Counter, Histogram, @@ -28,11 +27,6 @@ import { ObservableCounter, ObservableUpDownCounter, } from './types/Metric'; -import { - BoundHistogram, - BoundCounter, - BoundObservableBase, -} from './types/BoundInstrument'; import { ObservableResult } from './types/ObservableResult'; import { Observation } from './types/Observation'; @@ -67,7 +61,7 @@ export class NoopMeter implements Meter { * @param [options] the metric options. */ createUpDownCounter(_name: string, _options?: MetricOptions): UpDownCounter { - return NOOP_COUNTER_METRIC; + return NOOP_UP_DOWN_COUNTER_METRIC; } /** @@ -124,59 +118,21 @@ export class NoopMeter implements Meter { } } -export class NoopMetric implements UnboundMetric { - private readonly _instrument: T; - - constructor(instrument: T) { - this._instrument = instrument; - } +export class NoopMetric {} - /** - * Returns a Bound Instrument associated with specified Labels. - * It is recommended to keep a reference to the Bound Instrument instead of - * always calling this method for every operations. - * @param labels key-values pairs that are associated with a specific metric - * that you want to record. - */ - bind(_labels: Labels): T { - return this._instrument; - } - - /** - * Removes the Binding from the metric, if it is present. - * @param labels key-values pairs that are associated with a specific metric. - */ - unbind(_labels: Labels): void { - return; - } - - /** - * Clears all timeseries from the Metric. - */ - clear(): void { - return; - } +export class NoopCounterMetric extends NoopMetric implements Counter { + add(_value: number, _labels: Labels): void {} } -export class NoopCounterMetric - extends NoopMetric - implements Counter { - add(value: number, labels: Labels): void { - this.bind(labels).add(value); - } +export class NoopUpDownCounterMetric extends NoopMetric implements UpDownCounter { + add(_value: number, _labels: Labels): void {} } -export class NoopHistogramMetric - extends NoopMetric - implements Histogram { - record(value: number, labels: Labels): void { - this.bind(labels).record(value); - } +export class NoopHistogramMetric extends NoopMetric implements Histogram { + record(_value: number, _labels: Labels): void {} } -export class NoopObservableBaseMetric - extends NoopMetric - implements ObservableBase { +export class NoopObservableBaseMetric extends NoopMetric implements ObservableBase { observation(): Observation { return { observable: this as ObservableBase, @@ -187,42 +143,14 @@ export class NoopObservableBaseMetric export class NoopBatchObserver {} -export class NoopBoundCounter implements BoundCounter { - add(_value: number): void { - return; - } -} - -export class NoopBoundHistogram implements BoundHistogram { - record(_value: number, _baggage?: unknown, _spanContext?: unknown): void { - return; - } -} +export const NOOP_METER = new NoopMeter(); -export class NoopBoundObservableBase implements BoundObservableBase { - update(_value: number): void {} -} +export const NOOP_COUNTER_METRIC = new NoopCounterMetric(); +export const NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric(); +export const NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric(); -export const NOOP_METER = new NoopMeter(); -export const NOOP_BOUND_COUNTER = new NoopBoundCounter(); -export const NOOP_COUNTER_METRIC = new NoopCounterMetric(NOOP_BOUND_COUNTER); - -export const NOOP_BOUND_HISTOGRAM = new NoopBoundHistogram(); -export const NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric( - NOOP_BOUND_HISTOGRAM -); - -export const NOOP_BOUND_OBSERVABLE_BASE = new NoopBoundObservableBase(); -export const NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableBaseMetric( - NOOP_BOUND_OBSERVABLE_BASE -); - -export const NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableBaseMetric( - NOOP_BOUND_OBSERVABLE_BASE -); - -export const NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableBaseMetric( - NOOP_BOUND_OBSERVABLE_BASE -); +export const NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableBaseMetric(); +export const NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableBaseMetric(); +export const NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableBaseMetric(); export const NOOP_BATCH_OBSERVER = new NoopBatchObserver(); diff --git a/experimental/packages/opentelemetry-api-metrics/src/index.ts b/experimental/packages/opentelemetry-api-metrics/src/index.ts index 2a7a0dd255..7203a857c9 100644 --- a/experimental/packages/opentelemetry-api-metrics/src/index.ts +++ b/experimental/packages/opentelemetry-api-metrics/src/index.ts @@ -17,7 +17,6 @@ export * from './NoopMeter'; export * from './NoopMeterProvider'; export * from './types/BatchObserverResult'; -export * from './types/BoundInstrument'; export * from './types/Meter'; export * from './types/MeterProvider'; export * from './types/Metric'; diff --git a/experimental/packages/opentelemetry-api-metrics/src/types/BoundInstrument.ts b/experimental/packages/opentelemetry-api-metrics/src/types/BoundInstrument.ts deleted file mode 100644 index 378c934988..0000000000 --- a/experimental/packages/opentelemetry-api-metrics/src/types/BoundInstrument.ts +++ /dev/null @@ -1,38 +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. - */ - -/** An Instrument for Counter Metric. */ -export interface BoundCounter { - /** - * Adds the given value to the current value. Values cannot be negative. - * @param value the value to add. - */ - add(value: number): void; -} - -/** Histogram to report instantaneous measurement of a value. */ -export interface BoundHistogram { - /** - * Records the given value to this histogram. - * @param value to record. - */ - record(value: number): void; -} - -/** An Instrument for Base Observable */ -export interface BoundObservableBase { - update(value: number): void; -} diff --git a/experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts b/experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts index 55b51218f8..424666f4ee 100644 --- a/experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts +++ b/experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts @@ -14,11 +14,6 @@ * limitations under the License. */ -import { - BoundObservableBase, - BoundCounter, - BoundHistogram, -} from './BoundInstrument'; import { Observation, } from './Observation'; @@ -88,38 +83,6 @@ export enum AggregationTemporality { AGGREGATION_TEMPORALITY_CUMULATIVE, } -/** - * Metric represents a base class for different types of metric - * pre aggregations. - */ -export interface Metric { - /** - * Clears all bound instruments from the Metric. - */ - clear(): void; -} - -/** - * UnboundMetric represents a base class for different types of metric - * pre aggregations without label value bound yet. - */ -export interface UnboundMetric extends Metric { - /** - * Returns a Instrument associated with specified Labels. - * It is recommended to keep a reference to the Instrument instead of always - * calling this method for every operations. - * @param labels key-values pairs that are associated with a specific metric - * that you want to record. - */ - bind(labels: Labels): T; - - /** - * Removes the Instrument from the metric, if it is present. - * @param labels key-values pairs that are associated with a specific metric. - */ - unbind(labels: Labels): void; -} - /** * Counter is the most common synchronous instrument. This instrument supports * an `Add(increment)` function for reporting a sum, and is restricted to @@ -135,21 +98,21 @@ export interface UnboundMetric extends Metric { *
  • count the number of 5xx errors.
  • *
      */ -export interface Counter extends UnboundMetric { +export interface Counter { /** * Adds the given value to the current value. Values cannot be negative. */ add(value: number, labels?: Labels): void; } -export interface UpDownCounter extends UnboundMetric { +export interface UpDownCounter { /** * Adds the given value to the current value. Values can be negative. */ add(value: number, labels?: Labels): void; } -export interface Histogram extends UnboundMetric { +export interface Histogram { /** * Records the given value to this histogram. */ @@ -157,9 +120,10 @@ export interface Histogram extends UnboundMetric { } /** Base interface for the Observable metrics. */ -export interface ObservableBase extends UnboundMetric { +export interface ObservableBase { observation: ( - value: number + value: number, + labels?: Labels, ) => Observation; } 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 07b2e7b402..b09c2cdd0e 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,8 +17,6 @@ import * as assert from 'assert'; import { NoopMeterProvider, - NOOP_BOUND_COUNTER, - NOOP_BOUND_HISTOGRAM, NOOP_COUNTER_METRIC, NOOP_HISTOGRAM_METRIC, } from '../../src'; @@ -30,20 +28,16 @@ describe('NoopMeter', () => { const labels = {}; // ensure NoopMetric does not crash. - counter.bind(labels).add(1); - counter.unbind(labels); + counter.add(1, labels); // ensure the correct noop const is returned assert.strictEqual(counter, NOOP_COUNTER_METRIC); - assert.strictEqual(counter.bind(labels), NOOP_BOUND_COUNTER); - counter.clear(); const histogram = meter.createHistogram('some-name'); - histogram.bind(labels).record(1); + histogram.record(1, labels); // ensure the correct noop const is returned assert.strictEqual(histogram, NOOP_HISTOGRAM_METRIC); - assert.strictEqual(histogram.bind(labels), NOOP_BOUND_HISTOGRAM); const options = { component: 'tests', diff --git a/experimental/packages/opentelemetry-exporter-prometheus/README.md b/experimental/packages/opentelemetry-exporter-prometheus/README.md index 95ad498edf..9d401c0e62 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/README.md +++ b/experimental/packages/opentelemetry-exporter-prometheus/README.md @@ -40,11 +40,6 @@ const counter = meter.createCounter('metric_name', { }); counter.add(10, { pid: process.pid }); -// Record data using Instrument: It is recommended to keep a reference to the Bound Instrument instead of -// always calling `bind()` method for every operations. -const boundCounter = counter.bind({ pid: process.pid }); -boundCounter.add(10); - // .. some other work ``` diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts index f05c151c40..3528df2c42 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusExporter.test.ts @@ -243,15 +243,14 @@ describe('PrometheusExporter', () => { description: 'a test description', }); - const boundCounter = counter.bind({ key1: 'labelValue1' }); - boundCounter.add(10); + counter.add(10, { key1: 'labelValue1' }); meter.collect().then(() => { exporter.export(meter.getProcessor().checkPointSet(), () => { // TODO: Remove this special case once the PR is ready. // This is to test the special case where counters are destroyed // and recreated in the exporter in order to get around prom-client's // aggregation and use ours. - boundCounter.add(10); + counter.add(10, { key1: 'labelValue1' }); exporter.export(meter.getProcessor().checkPointSet(), () => { http .get('http://localhost:9464/metrics', res => { @@ -327,8 +326,8 @@ describe('PrometheusExporter', () => { description: 'a test description', }) as CounterMetric; - counter.bind({ counterKey1: 'labelValue1' }).add(10); - counter.bind({ counterKey1: 'labelValue2' }).add(20); + counter.add(10, { counterKey1: 'labelValue1' }); + counter.add(20, { counterKey1: 'labelValue2' }); meter.collect().then(() => { exporter.export(meter.getProcessor().checkPointSet(), () => { http @@ -358,9 +357,9 @@ describe('PrometheusExporter', () => { description: 'a test description', }) as CounterMetric; - counter.bind({ counterKey1: 'labelValue1' }).add(10); - counter.bind({ counterKey1: 'labelValue2' }).add(20); - counter.bind({ counterKey1: 'labelValue3' }).add(30); + counter.add(10, { counterKey1: 'labelValue1' }); + counter.add(20, { counterKey1: 'labelValue2' }); + counter.add(30, { counterKey1: 'labelValue3' }); meterProvider.shutdown().then(() => { // exporter has been shut down along with meter provider. http @@ -394,8 +393,7 @@ describe('PrometheusExporter', () => { it('should add a description if missing', done => { const counter = meter.createCounter('counter_total'); - const boundCounter = counter.bind({ key1: 'labelValue1' }); - boundCounter.add(10); + counter.add(10, { key1: 'labelValue1' }); meter.collect().then(() => { exporter.export(meter.getProcessor().checkPointSet(), () => { http @@ -421,8 +419,8 @@ describe('PrometheusExporter', () => { it('should sanitize names', done => { const counter = meter.createCounter('counter.bad-name'); - const boundCounter = counter.bind({ key1: 'labelValue1' }); - boundCounter.add(10); + + counter.add(10, { key1: 'labelValue1' }); meter.collect().then(() => { exporter.export(meter.getProcessor().checkPointSet(), () => { http @@ -451,7 +449,7 @@ describe('PrometheusExporter', () => { description: 'a test description', }); - counter.bind({ key1: 'labelValue1' }).add(20); + counter.add(20, { key1: 'labelValue1' }); meter.collect().then(() => { exporter.export(meter.getProcessor().checkPointSet(), () => { http @@ -557,7 +555,7 @@ describe('PrometheusExporter', () => { description: 'a test description', }); - histogram.bind({ key1: 'labelValue1' }).record(20); + histogram.record(20, { key1: 'labelValue1' }); meter.collect().then(() => { exporter.export(meter.getProcessor().checkPointSet(), () => { @@ -593,7 +591,7 @@ describe('PrometheusExporter', () => { beforeEach(() => { meter = new MeterProvider().getMeter('test-prometheus'); counter = meter.createCounter('counter') as CounterMetric; - counter.bind({ key1: 'labelValue1' }).add(10); + counter.add(10, { key1: 'labelValue1' }); }); afterEach(done => { diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusLabelsBatcher.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusLabelsBatcher.test.ts index 6e0a0d38c6..8ef180a27e 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusLabelsBatcher.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusLabelsBatcher.test.ts @@ -40,8 +40,8 @@ describe('PrometheusBatcher', () => { it('should aggregate metric records with same metric name', async () => { const batcher = new PrometheusLabelsBatcher(); const counter = meter.createCounter('test_counter') as CounterMetric; - counter.bind({ val: '1' }).add(1); - counter.bind({ val: '2' }).add(1); + counter.add(1, { val: '1' }); + counter.add(1, { val: '2' }); const records = await counter.getMetricRecord(); records.forEach(it => batcher.process(it)); @@ -65,8 +65,8 @@ describe('PrometheusBatcher', () => { label2.key2 = '2'; label2.key1 = '1'; - counter.bind(label1).add(1); - counter.bind(label2).add(1); + counter.add(1, label1); + counter.add(1, label2); const records = await counter.getMetricRecord(); records.forEach(it => batcher.process(it)); diff --git a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts index 7c3582f07b..88a5422344 100644 --- a/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts +++ b/experimental/packages/opentelemetry-exporter-prometheus/test/PrometheusSerializer.test.ts @@ -55,7 +55,7 @@ describe('PrometheusSerializer', () => { processor: new ExactProcessor(SumAggregator), }).getMeter('test'); const counter = meter.createCounter('test_total') as CounterMetric; - counter.bind(labels).add(1); + counter.add(1, labels); const records = await counter.getMetricRecord(); const record = records[0]; @@ -77,7 +77,7 @@ describe('PrometheusSerializer', () => { processor: new ExactProcessor(SumAggregator), }).getMeter('test'); const counter = meter.createCounter('test_total') as CounterMetric; - counter.bind(labels).add(1); + counter.add(1, labels); const records = await counter.getMetricRecord(); const record = records[0]; @@ -157,7 +157,7 @@ describe('PrometheusSerializer', () => { description: 'foobar', }) as HistogramMetric; - histogram.bind(labels).record(5); + histogram.record(5, labels); const records = await histogram.getMetricRecord(); const record = records[0]; @@ -185,7 +185,7 @@ describe('PrometheusSerializer', () => { description: 'foobar', boundaries: [1, 10, 100], }) as HistogramMetric; - histogram.bind(labels).record(5); + histogram.record(5, labels); const records = await histogram.getMetricRecord(); const record = records[0]; @@ -213,7 +213,7 @@ describe('PrometheusSerializer', () => { const histogram = meter.createHistogram('test', { description: 'foobar', }) as HistogramMetric; - histogram.bind(labels).record(5); + histogram.record(5, labels); const records = await histogram.getMetricRecord(); const record = records[0]; @@ -249,8 +249,8 @@ describe('PrometheusSerializer', () => { const counter = meter.createCounter('test_total', { description: 'foobar', }) as CounterMetric; - counter.bind({ val: '1' }).add(1); - counter.bind({ val: '2' }).add(1); + counter.add(1, { val: '1' }); + counter.add(1, { val: '2' }); const records = await counter.getMetricRecord(); records.forEach(it => processor.process(it)); @@ -276,8 +276,8 @@ describe('PrometheusSerializer', () => { const counter = meter.createCounter('test_total', { description: 'foobar', }) as CounterMetric; - counter.bind({ val: '1' }).add(1); - counter.bind({ val: '2' }).add(1); + counter.add(1, { val: '1' }); + counter.add(1, { val: '2' }); const records = await counter.getMetricRecord(); records.forEach(it => processor.process(it)); @@ -339,11 +339,11 @@ describe('PrometheusSerializer', () => { const histogram = meter.createHistogram('test', { description: 'foobar', }) as HistogramMetric; - histogram.bind({ val: '1' }).record(5); - histogram.bind({ val: '1' }).record(50); - histogram.bind({ val: '1' }).record(120); + histogram.record(5, { val: '1' }); + histogram.record(50, { val: '1' }); + histogram.record(120, { val: '1' }); - histogram.bind({ val: '2' }).record(5); + histogram.record(5, { val: '2' }); const records = await histogram.getMetricRecord(); const labelBatcher = new PrometheusLabelsBatcher(); @@ -382,7 +382,7 @@ describe('PrometheusSerializer', () => { processor: new ExactProcessor(SumAggregator), }).getMeter('test'); const counter = meter.createCounter('test') as CounterMetric; - counter.bind({}).add(1); + counter.add(1); const records = await counter.getMetricRecord(); const record = records[0]; @@ -410,7 +410,7 @@ describe('PrometheusSerializer', () => { processor: new ExactProcessor(SumAggregator), }).getMeter('test'); const counter = meter.createCounter('test_total') as CounterMetric; - counter.bind({}).add(1); + counter.add(1); const records = await counter.getMetricRecord(); const record = records[0]; @@ -432,7 +432,7 @@ describe('PrometheusSerializer', () => { processor: new ExactProcessor(SumAggregator), }).getMeter('test'); const counter = meter.createCounter('test_total') as CounterMetric; - counter.bind({}).add(1); + counter.add(1); const records = await counter.getMetricRecord(); const record = records[0]; @@ -451,14 +451,12 @@ describe('PrometheusSerializer', () => { processor: new ExactProcessor(SumAggregator), }).getMeter('test'); const counter = meter.createCounter('test_total') as CounterMetric; - counter - .bind(({ - object: {}, - NaN: NaN, - null: null, - undefined: undefined, - } as unknown) as Labels) - .add(1); + counter.add(1, ({ + object: {}, + NaN: NaN, + null: null, + undefined: undefined, + } as unknown) as Labels); const records = await counter.getMetricRecord(); const record = records[0]; @@ -487,7 +485,7 @@ describe('PrometheusSerializer', () => { const counter = meter.createUpDownCounter( 'test' ) as UpDownCounterMetric; - counter.bind(labels).add(esac[0]); + counter.add(esac[0], labels); const records = await counter.getMetricRecord(); const record = records[0]; @@ -509,16 +507,14 @@ describe('PrometheusSerializer', () => { processor: new ExactProcessor(SumAggregator), }).getMeter('test'); const counter = meter.createCounter('test_total') as CounterMetric; - counter - .bind(({ - backslash: '\u005c', // \ => \\ (\u005c\u005c) - doubleQuote: '\u0022', // " => \" (\u005c\u0022) - lineFeed: '\u000a', // ↵ => \n (\u005c\u006e) - backslashN: '\u005c\u006e', // \n => \\n (\u005c\u005c\u006e) - backslashDoubleQuote: '\u005c\u0022', // \" => \\\" (\u005c\u005c\u005c\u0022) - backslashLineFeed: '\u005c\u000a', // \↵ => \\\n (\u005c\u005c\u005c\u006e) - } as unknown) as Labels) - .add(1); + counter.add(1, ({ + backslash: '\u005c', // \ => \\ (\u005c\u005c) + doubleQuote: '\u0022', // " => \" (\u005c\u0022) + lineFeed: '\u000a', // ↵ => \n (\u005c\u006e) + backslashN: '\u005c\u006e', // \n => \\n (\u005c\u005c\u006e) + backslashDoubleQuote: '\u005c\u0022', // \" => \\\" (\u005c\u005c\u005c\u0022) + backslashLineFeed: '\u005c\u000a', // \↵ => \\\n (\u005c\u005c\u005c\u006e) + } as unknown) as Labels); const records = await counter.getMetricRecord(); const record = records[0]; @@ -549,11 +545,9 @@ describe('PrometheusSerializer', () => { // if you try to use a label 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 - .bind(({ - 'account-id': '123456', - } as unknown) as Labels) - .add(1); + counter.add(1, ({ + 'account-id': '123456', + } as unknown) as Labels); const records = await counter.getMetricRecord(); const record = records[0]; diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/README.md b/experimental/packages/opentelemetry-sdk-metrics-base/README.md index b760ecc336..c68fb1cf68 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/README.md +++ b/experimental/packages/opentelemetry-sdk-metrics-base/README.md @@ -37,11 +37,7 @@ const counter = meter.createCounter('metric_name', { }); const labels = { pid: process.pid }; - -// Create a BoundInstrument associated with specified label values. -const boundCounter = counter.bind(labels); -boundCounter.add(10); - +counter.add(10, labels); ``` ### UpDownCounter @@ -66,11 +62,7 @@ const counter = meter.createUpDownCounter('metric_name', { }); const labels = { pid: process.pid }; - -// Create a BoundInstrument associated with specified label values. -const boundCounter = counter.bind(labels); -boundCounter.add(Math.random() > 0.5 ? 1 : -1); - +counter.add(Math.random() > 0.5 ? 1 : -1, labels); ``` ### Observable Gauge diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/src/BatchObserverResult.ts b/experimental/packages/opentelemetry-sdk-metrics-base/src/BatchObserverResult.ts index f882774ad0..d05284010f 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/src/BatchObserverResult.ts +++ b/experimental/packages/opentelemetry-sdk-metrics-base/src/BatchObserverResult.ts @@ -15,6 +15,7 @@ */ import * as api from '@opentelemetry/api-metrics'; +import { ObservableBaseMetric } from './ObservableBaseMetric'; /** * Implementation of api BatchObserverResult @@ -44,7 +45,8 @@ export class BatchObserverResult implements api.BatchObserverResult { return; } observations.forEach(observation => { - observation.observable.bind(labels).update(observation.value); + const observable = observation.observable as ObservableBaseMetric; + observable.bind(labels).update(observation.value); }); if (!this._immediate) { this._immediate = setImmediate(() => { diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/src/BoundInstrument.ts b/experimental/packages/opentelemetry-sdk-metrics-base/src/BoundInstrument.ts index 67a66b204c..e09524e3a2 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/src/BoundInstrument.ts +++ b/experimental/packages/opentelemetry-sdk-metrics-base/src/BoundInstrument.ts @@ -72,7 +72,7 @@ export class BaseBoundInstrument { */ export class BoundCounter extends BaseBoundInstrument - implements api.BoundCounter { + implements api.Counter { constructor( labels: api.Labels, disabled: boolean, @@ -99,7 +99,7 @@ export class BoundCounter */ export class BoundUpDownCounter extends BaseBoundInstrument - implements api.BoundCounter { + implements api.UpDownCounter { constructor( labels: api.Labels, disabled: boolean, @@ -119,7 +119,7 @@ export class BoundUpDownCounter */ export class BoundHistogram extends BaseBoundInstrument - implements api.BoundHistogram { + implements api.Histogram { constructor( labels: api.Labels, disabled: boolean, @@ -137,9 +137,7 @@ export class BoundHistogram /** * BoundObservable is an implementation of the {@link BoundObservable} interface. */ -export class BoundObservable - extends BaseBoundInstrument - implements api.BoundObservableBase { +export class BoundObservable extends BaseBoundInstrument { constructor( labels: api.Labels, disabled: boolean, diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/src/Metric.ts b/experimental/packages/opentelemetry-sdk-metrics-base/src/Metric.ts index fc3cc06664..4dc8b96878 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/src/Metric.ts +++ b/experimental/packages/opentelemetry-sdk-metrics-base/src/Metric.ts @@ -21,8 +21,7 @@ import { MetricDescriptor, MetricKind, MetricRecord } from './export/types'; import { hashLabels } from './Utils'; /** This is a SDK implementation of {@link Metric} interface. */ -export abstract class Metric - implements api.UnboundMetric { +export abstract class Metric { protected readonly _disabled: boolean; protected readonly _valueType: api.ValueType; protected readonly _descriptor: MetricDescriptor; diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/test/Meter.test.ts b/experimental/packages/opentelemetry-sdk-metrics-base/test/Meter.test.ts index 3dae4e6230..b422add268 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/test/Meter.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics-base/test/Meter.test.ts @@ -227,7 +227,7 @@ describe('Meter', () => { }); it('should not fail when removing non existing instrument', () => { - const counter = meter.createCounter('name'); + const counter = meter.createCounter('name') as CounterMetric; counter.unbind({}); }); @@ -366,7 +366,7 @@ describe('Meter', () => { describe('.bind()', () => { it('should create a UpDownCounter instrument', async () => { - const upDownCounter = meter.createUpDownCounter('name'); + const upDownCounter = meter.createUpDownCounter('name') as UpDownCounterMetric; const boundCounter = upDownCounter.bind(labels); boundCounter.add(10); await meter.collect(); @@ -390,7 +390,7 @@ describe('Meter', () => { it('should not add the instrument data when disabled', async () => { const upDownCounter = meter.createUpDownCounter('name', { disabled: true, - }); + }) as UpDownCounterMetric; const boundCounter = upDownCounter.bind(labels); boundCounter.add(10); await meter.collect(); @@ -399,7 +399,7 @@ describe('Meter', () => { }); it('should return same instrument on same label values', async () => { - const upDownCounter = meter.createUpDownCounter('name'); + const upDownCounter = meter.createUpDownCounter('name') as UpDownCounterMetric; const boundCounter = upDownCounter.bind(labels); boundCounter.add(10); const boundCounter1 = upDownCounter.bind(labels); @@ -414,7 +414,7 @@ describe('Meter', () => { it('should truncate non-integer values for INT valueType', async () => { const upDownCounter = meter.createUpDownCounter('name', { valueType: api.ValueType.INT, - }); + }) as UpDownCounterMetric; const boundCounter = upDownCounter.bind(labels); [-1.1, 2.2].forEach(val => { @@ -428,7 +428,7 @@ describe('Meter', () => { it('should ignore non-number values for INT valueType', async () => { const upDownCounter = meter.createUpDownCounter('name', { valueType: api.ValueType.DOUBLE, - }); + }) as UpDownCounterMetric; const boundCounter = upDownCounter.bind(labels); await Promise.all( @@ -446,7 +446,7 @@ describe('Meter', () => { it('should ignore non-number values for DOUBLE valueType', async () => { const upDownCounter = meter.createUpDownCounter('name', { valueType: api.ValueType.DOUBLE, - }); + }) as UpDownCounterMetric; const boundCounter = upDownCounter.bind(labels); await Promise.all( @@ -477,7 +477,7 @@ describe('Meter', () => { }); it('should not fail when removing non existing instrument', () => { - const upDownCounter = meter.createUpDownCounter('name'); + const upDownCounter = meter.createUpDownCounter('name') as UpDownCounterMetric; upDownCounter.unbind({}); }); @@ -670,7 +670,7 @@ describe('Meter', () => { }); it('should accept negative (and positive) values', async () => { - const histogram = meter.createHistogram('name'); + const histogram = meter.createHistogram('name') as HistogramMetric; const boundHistogram = histogram.bind(labels); boundHistogram.record(-10); boundHistogram.record(50); @@ -761,7 +761,7 @@ describe('Meter', () => { }); it('should not fail when removing non existing instrument', () => { - const histogram = meter.createHistogram('name'); + const histogram = meter.createHistogram('name') as HistogramMetric; histogram.unbind({}); }); @@ -1314,7 +1314,7 @@ describe('Meter', () => { const key = 'key'; const counter = meter.createCounter('counter', { description: 'test', - }); + }) as CounterMetric; const labels = { [key]: 'counter-value' }; const boundCounter = counter.bind(labels); boundCounter.add(10.45); @@ -1340,7 +1340,7 @@ describe('Meter', () => { const counter = meter.createCounter('counter', { description: 'test', valueType: api.ValueType.INT, - }); + }) as CounterMetric; const labels = { [key]: 'counter-value' }; const boundCounter = counter.bind(labels); boundCounter.add(10.45); diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/test/MeterProvider.test.ts b/experimental/packages/opentelemetry-sdk-metrics-base/test/MeterProvider.test.ts index 5411f63b8f..36e68e1271 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/test/MeterProvider.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics-base/test/MeterProvider.test.ts @@ -100,7 +100,7 @@ describe('MeterProvider', () => { assert.throws(() => { const histogram = meter.createHistogram('myHistogram'); - histogram.bind({}).record(1); + histogram.record(1); }, /aggregatorFor method not implemented/); }); }); diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/test/Processor.test.ts b/experimental/packages/opentelemetry-sdk-metrics-base/test/Processor.test.ts index cd2ac2c4df..cb1a459b03 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/test/Processor.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics-base/test/Processor.test.ts @@ -16,19 +16,18 @@ import * as api from '@opentelemetry/api-metrics'; import * as assert from 'assert'; -import { Meter, MeterProvider } from '../src'; +import { CounterMetric, Meter, MeterProvider } from '../src'; describe('Processor', () => { describe('Ungrouped', () => { let meter: Meter; - let fooCounter: api.BoundCounter; - let barCounter: api.BoundCounter; - let counter: api.Counter; + let fooCounter: api.Counter; + let barCounter: api.Counter; beforeEach(() => { meter = new MeterProvider({ interval: 10000, }).getMeter('test-meter'); - counter = meter.createCounter('ungrouped-processor-test'); + const counter = meter.createCounter('ungrouped-processor-test') as CounterMetric; fooCounter = counter.bind({ key: 'foo' }); barCounter = counter.bind({ key: 'bar' }); }); diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/test/export/ConsoleMetricExporter.test.ts b/experimental/packages/opentelemetry-sdk-metrics-base/test/export/ConsoleMetricExporter.test.ts index 0cd111cc5c..4935c498d8 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/test/export/ConsoleMetricExporter.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics-base/test/export/ConsoleMetricExporter.test.ts @@ -16,7 +16,7 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; -import { ConsoleMetricExporter, MeterProvider, MetricKind } from '../../src'; +import { ConsoleMetricExporter, CounterMetric, MeterProvider, MetricKind } from '../../src'; import { ValueType } from '@opentelemetry/api-metrics'; /* eslint-disable no-console */ @@ -43,7 +43,7 @@ describe('ConsoleMetricExporter', () => { ); const counter = meter.createCounter('counter', { description: 'a test description', - }); + }) as CounterMetric; const boundCounter = counter.bind({ key1: 'labelValue1', key2: 'labelValue2', diff --git a/experimental/packages/opentelemetry-sdk-metrics-base/test/export/Controller.test.ts b/experimental/packages/opentelemetry-sdk-metrics-base/test/export/Controller.test.ts index ec7c872648..c753db6a48 100644 --- a/experimental/packages/opentelemetry-sdk-metrics-base/test/export/Controller.test.ts +++ b/experimental/packages/opentelemetry-sdk-metrics-base/test/export/Controller.test.ts @@ -16,7 +16,7 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; -import { MeterProvider, MetricExporter, MetricRecord } from '../../src'; +import { CounterMetric, MeterProvider, MetricExporter, MetricRecord } from '../../src'; import { ExportResult, ExportResultCode, @@ -50,10 +50,10 @@ describe('Controller', () => { error: expectedError, }), }).getMeter('test-console-metric-exporter'); - const counter = meter + const counter = (meter .createCounter('counter', { description: 'a test description', - }) + }) as CounterMetric) .bind({}); counter.add(10);