Skip to content

Commit

Permalink
feat(metrics): multi-instrument async callback support (#2966)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Dyla <dyladan@users.noreply.github.com>
  • Loading branch information
legendecas and dyladan authored May 25, 2022
1 parent 610808d commit ba3e320
Show file tree
Hide file tree
Showing 28 changed files with 1,099 additions and 247 deletions.
5 changes: 5 additions & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ All notable changes to experimental packages in this project will be documented

* feat(metrics): metric readers and exporters now select aggregation temporality based on instrument type #2902 @seemk
* refactor(metrics-sdk): rename InstrumentationLibrary -> InstrumentationScope #2959 @pichlermarc
* feat(metrics): multi-instrument async callback support #2966 @legendecas
* changes on `meter.createObservableCounter`, `meter.createObservableGauge`, `meter.createObservableUpDownCounter`
* removed the second parameter `callback`
* returns an `Observable` object on which callbacks can be registered or unregistered.
* added `meter.addBatchObservableCallback` and `meter.removeBatchObservableCallback`.

### :rocket: (Enhancement)

Expand Down
77 changes: 47 additions & 30 deletions experimental/packages/opentelemetry-api-metrics/src/NoopMeter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@

import { Meter } from './types/Meter';
import {
MetricOptions,
MetricAttributes,
BatchObservableCallback,
Counter,
Histogram,
UpDownCounter,
MetricOptions,
ObservableCallback,
ObservableCounter,
ObservableGauge,
ObservableUpDownCounter,
UpDownCounter,
MetricAttributes,
Observable,
} from './types/Metric';

/**
Expand All @@ -32,67 +37,65 @@ export class NoopMeter implements Meter {
constructor() {}

/**
* Returns a constant noop histogram.
* @param name the name of the metric.
* @param [options] the metric options.
* @see {@link Meter.createHistogram}
*/
createHistogram(_name: string, _options?: MetricOptions): Histogram {
return NOOP_HISTOGRAM_METRIC;
}

/**
* Returns a constant noop counter.
* @param name the name of the metric.
* @param [options] the metric options.
* @see {@link Meter.createCounter}
*/
createCounter(_name: string, _options?: MetricOptions): Counter {
return NOOP_COUNTER_METRIC;
}

/**
* Returns a constant noop UpDownCounter.
* @param name the name of the metric.
* @param [options] the metric options.
* @see {@link Meter.createUpDownCounter}
*/
createUpDownCounter(_name: string, _options?: MetricOptions): UpDownCounter {
return NOOP_UP_DOWN_COUNTER_METRIC;
}

/**
* Returns a constant noop observable gauge.
* @param name the name of the metric.
* @param callback the observable gauge callback
* @param [options] the metric options.
* @see {@link Meter.createObservableGauge}
*/
createObservableGauge(
_name: string,
_callback: ObservableCallback,
_options?: MetricOptions,
): void {}
): ObservableGauge {
return NOOP_OBSERVABLE_GAUGE_METRIC;
}

/**
* Returns a constant noop observable counter.
* @param name the name of the metric.
* @param callback the observable counter callback
* @param [options] the metric options.
* @see {@link Meter.createObservableCounter}
*/
createObservableCounter(
_name: string,
_callback: ObservableCallback,
_options?: MetricOptions,
): void {}
): ObservableCounter {
return NOOP_OBSERVABLE_COUNTER_METRIC;
}

/**
* Returns a constant noop up down observable counter.
* @param name the name of the metric.
* @param callback the up down observable counter callback
* @param [options] the metric options.
* @see {@link Meter.createObservableUpDownCounter}
*/
createObservableUpDownCounter(
_name: string,
_callback: ObservableCallback,
_options?: MetricOptions,
): void {}
): ObservableUpDownCounter {
return NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC;
}

/**
* @see {@link Meter.addBatchObservableCallback}
*/
addBatchObservableCallback(_callback: BatchObservableCallback, _observables: Observable[]): void {}

/**
* @see {@link Meter.removeBatchObservableCallback}
*/
removeBatchObservableCallback(_callback: BatchObservableCallback): void {}
}

export class NoopMetric {}
Expand All @@ -109,9 +112,23 @@ export class NoopHistogramMetric extends NoopMetric implements Histogram {
record(_value: number, _attributes: MetricAttributes): void {}
}

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();

// Synchronous instruments
export const NOOP_COUNTER_METRIC = new NoopCounterMetric();
export const NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric();
export const NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric();

// Asynchronous instruments
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();
62 changes: 42 additions & 20 deletions experimental/packages/opentelemetry-api-metrics/src/types/Meter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
* limitations under the License.
*/

import { CounterOptions, HistogramOptions, UpDownCounterOptions } from '..';
import {
BatchObservableCallback,
Counter,
Histogram,
ObservableCallback,
ObservableCounterOptions,
ObservableGaugeOptions,
ObservableUpDownCounterOptions,
MetricOptions,
Observable,
ObservableCounter,
ObservableGauge,
ObservableUpDownCounter,
UpDownCounter,
} from './Metric';

Expand All @@ -48,7 +49,7 @@ export interface Meter {
* @param name the name of the metric.
* @param [options] the metric options.
*/
createHistogram(name: string, options?: HistogramOptions): Histogram;
createHistogram(name: string, options?: MetricOptions): Histogram;

/**
* Creates a new `Counter` metric. Generally, this kind of metric when the
Expand All @@ -57,7 +58,7 @@ export interface Meter {
* @param name the name of the metric.
* @param [options] the metric options.
*/
createCounter(name: string, options?: CounterOptions): Counter;
createCounter(name: string, options?: MetricOptions): Counter;

/**
* Creates a new `UpDownCounter` metric. UpDownCounter is a synchronous
Expand All @@ -76,50 +77,71 @@ export interface Meter {
* @param name the name of the metric.
* @param [options] the metric options.
*/
createUpDownCounter(name: string, options?: UpDownCounterOptions): UpDownCounter;
createUpDownCounter(name: string, options?: MetricOptions): UpDownCounter;

/**
* Creates a new `ObservableGauge` metric.
*
* The callback SHOULD be safe to be invoked concurrently.
*
* @param name the name of the metric.
* @param callback the observable callback
* @param [options] the metric options.
*/
createObservableGauge(
name: string,
callback: ObservableCallback,
options?: ObservableGaugeOptions
): void;
options?: MetricOptions
): ObservableGauge;

/**
* Creates a new `ObservableCounter` metric.
*
* The callback SHOULD be safe to be invoked concurrently.
*
* @param name the name of the metric.
* @param callback the observable callback
* @param [options] the metric options.
*/
createObservableCounter(
name: string,
callback: ObservableCallback,
options?: ObservableCounterOptions
): void;
options?: MetricOptions
): ObservableCounter;

/**
* Creates a new `ObservableUpDownCounter` metric.
*
* The callback SHOULD be safe to be invoked concurrently.
*
* @param name the name of the metric.
* @param callback the observable callback
* @param [options] the metric options.
*/
createObservableUpDownCounter(
name: string,
callback: ObservableCallback,
options?: ObservableUpDownCounterOptions
): void;
options?: MetricOptions
): ObservableUpDownCounter;

/**
* 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.
*
* Only the associated observables can be observed in the callback.
* Measurements of observables that are not associated observed in the
* callback are dropped.
*
* @param callback the batch observable callback
* @param observables the observables associated with this batch observable callback
*/
addBatchObservableCallback(callback: BatchObservableCallback, observables: Observable[]): void;

/**
* Removes a callback previously registered with {@link Meter.addBatchObservableCallback}.
*
* The callback to be removed is identified using a combination of the callback itself,
* and the set of the observables associated with it.
*
* @param callback the batch observable callback
* @param observables the observables associated with this batch observable callback
*/
removeBatchObservableCallback(callback: BatchObservableCallback, observables: Observable[]): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import { Context } from '@opentelemetry/api';
import { ObservableResult } from './ObservableResult';
import { BatchObservableResult, ObservableResult } from './ObservableResult';

/**
* Options needed for metric creation
Expand All @@ -40,13 +40,6 @@ export interface MetricOptions {
valueType?: ValueType;
}

export type CounterOptions = MetricOptions;
export type UpDownCounterOptions = MetricOptions;
export type ObservableGaugeOptions = MetricOptions;
export type ObservableCounterOptions = MetricOptions;
export type ObservableUpDownCounterOptions = MetricOptions;
export type HistogramOptions = MetricOptions;

/** The Type of value. It describes how the data is reported. */
export enum ValueType {
INT,
Expand Down Expand Up @@ -98,3 +91,26 @@ export type MetricAttributes = { [key: string]: string };
* The observable callback for Observable instruments.
*/
export type ObservableCallback = (observableResult: ObservableResult) => void | Promise<void>;

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

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;

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

export type ObservableCounter = Observable;
export type ObservableUpDownCounter = Observable;
export type ObservableGauge = Observable;
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
* limitations under the License.
*/

import { MetricAttributes } from './Metric';
import { MetricAttributes, Observable } from './Metric';

/**
* Interface that is being used in callback function for Observable Metric
* Interface that is being used in callback function for Observable Metric.
*/
export interface ObservableResult {
/**
Expand All @@ -30,3 +30,19 @@ export interface ObservableResult {
*/
observe(value: number, attributes?: MetricAttributes): void;
}

/**
* Interface that is being used in batch observable callback function.
*/
export interface BatchObservableResult {
/**
* Observe a measurement of the value associated with the given attributes.
*
* @param metric The observable metric to be observed.
* @param value The value to be observed.
* @param attributes The attributes associated with the value. If more than
* 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;
}
Loading

0 comments on commit ba3e320

Please sign in to comment.