From 935e572a1d990208e9f4a903cc054e4fbfbfd5c5 Mon Sep 17 00:00:00 2001 From: Tomer Ghelber Date: Mon, 5 Sep 2022 15:23:12 +0300 Subject: [PATCH] feat(opentelemetry-api-metrics): Adding generics to `create{metricType}` --- 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 9c3307b0b49..5c61bdcfd94 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -65,6 +65,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 3931f01622b..1904c488714 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 dcf779bc694..6ca013766f5 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 a38755982db..3bc4bc9c119 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 00000000000..a499db168f1 --- /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' }); + }); + }); +});