Skip to content

Commit

Permalink
feat(opentelemetry-api-metrics): Adding generics to `create{metricTyp…
Browse files Browse the repository at this point in the history
…e}` (#3170)

Co-authored-by: Daniel Dyla <[email protected]>
  • Loading branch information
tomerghelber-tm and dyladan authored Sep 12, 2022
1 parent b73c29d commit f9f7fed
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 29 deletions.
1 change: 1 addition & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
35 changes: 24 additions & 11 deletions experimental/packages/opentelemetry-api-metrics/src/types/Meter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
BatchObservableCallback,
Counter,
Histogram,
MetricAttributes,
MetricOptions,
Observable,
ObservableCounter,
Expand Down Expand Up @@ -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<AttributesTypes extends MetricAttributes = MetricAttributes>(
name: string,
options?: MetricOptions
): Histogram<AttributesTypes>;

/**
* Creates a new `Counter` metric. Generally, this kind of metric when the
Expand All @@ -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<AttributesTypes extends MetricAttributes = MetricAttributes>(
name: string,
options?: MetricOptions
): Counter<AttributesTypes>;

/**
* Creates a new `UpDownCounter` metric. UpDownCounter is a synchronous
Expand All @@ -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<AttributesTypes extends MetricAttributes = MetricAttributes>(name: string, options?: MetricOptions): UpDownCounter<AttributesTypes>;

/**
* Creates a new `ObservableGauge` metric.
Expand All @@ -87,10 +94,10 @@ export interface Meter {
* @param name the name of the metric.
* @param [options] the metric options.
*/
createObservableGauge(
createObservableGauge<AttributesTypes extends MetricAttributes = MetricAttributes>(
name: string,
options?: MetricOptions
): ObservableGauge;
): ObservableGauge<AttributesTypes>;

/**
* Creates a new `ObservableCounter` metric.
Expand All @@ -100,10 +107,10 @@ export interface Meter {
* @param name the name of the metric.
* @param [options] the metric options.
*/
createObservableCounter(
createObservableCounter<AttributesTypes extends MetricAttributes = MetricAttributes>(
name: string,
options?: MetricOptions
): ObservableCounter;
): ObservableCounter<AttributesTypes>;

/**
* Creates a new `ObservableUpDownCounter` metric.
Expand All @@ -113,10 +120,10 @@ export interface Meter {
* @param name the name of the metric.
* @param [options] the metric options.
*/
createObservableUpDownCounter(
createObservableUpDownCounter<AttributesTypes extends MetricAttributes = MetricAttributes>(
name: string,
options?: MetricOptions
): ObservableUpDownCounter;
): ObservableUpDownCounter<AttributesTypes>;

/**
* Sets up a function that will be called whenever a metric collection is
Expand All @@ -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<AttributesTypes extends MetricAttributes = MetricAttributes>(
callback: BatchObservableCallback<AttributesTypes>,
observables: Observable<AttributesTypes>[]
): void;

/**
* Removes a callback previously registered with {@link Meter.addBatchObservableCallback}.
Expand All @@ -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<AttributesTypes extends MetricAttributes = MetricAttributes>(
callback: BatchObservableCallback<AttributesTypes>,
observables: Observable<AttributesTypes>[]
): void;
}
30 changes: 16 additions & 14 deletions experimental/packages/opentelemetry-api-metrics/src/types/Metric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,25 @@ export enum ValueType {
* <li> count the number of 5xx errors. </li>
* <ol>
*/
export interface Counter {
export interface Counter<AttributesTypes extends MetricAttributes = MetricAttributes> {
/**
* 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<AttributesTypes extends MetricAttributes = MetricAttributes> {
/**
* 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<AttributesTypes extends MetricAttributes = MetricAttributes> {
/**
* 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.
Expand All @@ -101,27 +101,29 @@ export type MetricAttributeValue = SpanAttributeValue;
/**
* The observable callback for Observable instruments.
*/
export type ObservableCallback = (observableResult: ObservableResult) => void | Promise<void>;
export type ObservableCallback<AttributesTypes extends MetricAttributes = MetricAttributes> =
(observableResult: ObservableResult<AttributesTypes>) => void | Promise<void>;

/**
* The observable callback for a batch of Observable instruments.
*/
export type BatchObservableCallback = (observableResult: BatchObservableResult) => void | Promise<void>;
export type BatchObservableCallback<AttributesTypes extends MetricAttributes = MetricAttributes> =
(observableResult: BatchObservableResult<AttributesTypes>) => void | Promise<void>;

export interface Observable {
export interface Observable<AttributesTypes extends MetricAttributes = MetricAttributes> {
/**
* 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<AttributesTypes>): void;

/**
* Removes a callback previously registered with {@link Observable.addCallback}.
*/
removeCallback(callback: ObservableCallback): void;
removeCallback(callback: ObservableCallback<AttributesTypes>): void;
}

export type ObservableCounter = Observable;
export type ObservableUpDownCounter = Observable;
export type ObservableGauge = Observable;
export type ObservableCounter<AttributesTypes extends MetricAttributes=MetricAttributes> = Observable<AttributesTypes>;
export type ObservableUpDownCounter<AttributesTypes extends MetricAttributes=MetricAttributes> = Observable<AttributesTypes>;
export type ObservableGauge<AttributesTypes extends MetricAttributes=MetricAttributes> = Observable<AttributesTypes>;
Original file line number Diff line number Diff line change
Expand Up @@ -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<AttributesTypes extends MetricAttributes = MetricAttributes> {
/**
* Observe a measurement of the value associated with the given attributes.
*
Expand All @@ -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<AttributesTypes extends MetricAttributes = MetricAttributes> {
/**
* Observe a measurement of the value associated with the given attributes.
*
Expand All @@ -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<AttributesTypes>, value: number, attributes?: AttributesTypes): void;
}
Original file line number Diff line number Diff line change
@@ -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<Attributes> = {
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<Attributes> = {
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<Attributes> = {
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<Attributes> = {
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<Attributes> = {
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<Attributes> = {
record(_value: number, _attribute: Attributes) {}
};
// @ts-expect-error Expacting the type of Attributes
counter.record(1, { 'another-attribute': 'value' });
});
});
});

0 comments on commit f9f7fed

Please sign in to comment.