Skip to content

Commit

Permalink
refactor(metrics): distinguish different aggregator types
Browse files Browse the repository at this point in the history
Separate the `toPoint` definition to distinguish the return value of
one aggregator possibly returning.
  • Loading branch information
legendecas committed Jul 17, 2020
1 parent 0b6dc93 commit 2c3bd5d
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
Meter,
MeterProvider,
Point,
Sum,
} from '@opentelemetry/metrics';
import * as assert from 'assert';
import * as http from 'http';
Expand All @@ -30,10 +31,10 @@ const mockedHrTime: HrTime = [1586347902211, 0];
const mockedTimeMS = 1586347902211000;

describe('PrometheusExporter', () => {
let toPoint: () => Point;
let toPoint: () => Point<Sum>;
before(() => {
toPoint = SumAggregator.prototype.toPoint;
SumAggregator.prototype.toPoint = function (): Point {
SumAggregator.prototype.toPoint = function (): Point<Sum> {
const point = toPoint.apply(this);
point.timestamp = mockedHrTime;
return point;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
* limitations under the License.
*/

import { Aggregator, Point } from '../types';
import { Point, AggregatorKind, DistributionAggregatorType } from '../types';
import { HrTime } from '@opentelemetry/api';
import { hrTime } from '@opentelemetry/core';
import { Distribution } from '../types';

/**
* Basic aggregator keeping all raw values (events, sum, max, last and min).
*/
export class MinMaxLastSumCountAggregator implements Aggregator {
export class MinMaxLastSumCountAggregator
implements DistributionAggregatorType {
public kind: AggregatorKind.DISTRIBUTION = AggregatorKind.DISTRIBUTION;
private _distribution: Distribution;
private _lastUpdateTime: HrTime = [0, 0];

Expand All @@ -45,7 +47,7 @@ export class MinMaxLastSumCountAggregator implements Aggregator {
this._lastUpdateTime = hrTime();
}

toPoint(): Point {
toPoint(): Point<Distribution> {
return {
value: this._distribution,
timestamp: this._lastUpdateTime,
Expand Down
7 changes: 4 additions & 3 deletions packages/opentelemetry-metrics/src/export/aggregators/Sum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
* limitations under the License.
*/

import { Aggregator, Point } from '../types';
import { Point, Sum, AggregatorKind, SumAggregatorType } from '../types';
import { HrTime } from '@opentelemetry/api';
import { hrTime } from '@opentelemetry/core';

/** Basic aggregator which calculates a Sum from individual measurements. */
export class SumAggregator implements Aggregator {
export class SumAggregator implements SumAggregatorType {
public kind: AggregatorKind.SUM = AggregatorKind.SUM;
private _current: number = 0;
private _lastUpdateTime: HrTime = [0, 0];

Expand All @@ -28,7 +29,7 @@ export class SumAggregator implements Aggregator {
this._lastUpdateTime = hrTime();
}

toPoint(): Point {
toPoint(): Point<Sum> {
return {
value: this._current,
timestamp: this._lastUpdateTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,21 @@
* limitations under the License.
*/

import { Aggregator, Point, Histogram } from '../types';
import {
HistogramAggregatorType,
Point,
Histogram,
AggregatorKind,
} from '../types';
import { HrTime } from '@opentelemetry/api';
import { hrTime } from '@opentelemetry/core';

/**
* Basic aggregator which observes events and counts them in pre-defined buckets
* and provides the total sum and count of all observations.
*/
export class HistogramAggregator implements Aggregator {
export class HistogramAggregator implements HistogramAggregatorType {
public kind: AggregatorKind.HISTOGRAM = AggregatorKind.HISTOGRAM;
private _lastCheckpoint: Histogram;
private _currentCheckpoint: Histogram;
private _lastCheckpointTime: HrTime;
Expand Down Expand Up @@ -61,7 +67,7 @@ export class HistogramAggregator implements Aggregator {
this._currentCheckpoint = this._newEmptyCheckpoint();
}

toPoint(): Point {
toPoint(): Point<Histogram> {
return {
value: this._lastCheckpoint,
timestamp: this._lastCheckpointTime,
Expand Down
71 changes: 67 additions & 4 deletions packages/opentelemetry-metrics/src/export/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,21 @@ export enum MetricKind {
VALUE_OBSERVER,
}

/** The kind of aggregator. */
export enum AggregatorKind {
SUM,
LAST_VALUE,
DISTRIBUTION,
HISTOGRAM,
}

/** Sum returns an aggregated sum. */
export type Sum = number;

/** LastValue returns last value. */
export type LastValue = number;

/** Distribution returns an aggregated distribution. */
export interface Distribution {
min: number;
max: number;
Expand Down Expand Up @@ -69,6 +78,8 @@ export interface Histogram {
count: number;
}

export type PointValueType = Sum | LastValue | Distribution | Histogram;

export interface MetricRecord {
readonly descriptor: MetricDescriptor;
readonly labels: Labels;
Expand Down Expand Up @@ -102,16 +113,68 @@ export interface MetricExporter {
/**
* Base interface for aggregators. Aggregators are responsible for holding
* aggregated values and taking a snapshot of these values upon export.
*
* Use {@link Aggregator} instead of this BaseAggregator.
*/
export interface Aggregator {
interface BaseAggregator {
/** The kind of the aggregator. */
kind: AggregatorKind;

/** Updates the current with the new value. */
update(value: number): void;
}

/** SumAggregatorType aggregate values into a {@link Sum} point type. */
export interface SumAggregatorType extends BaseAggregator {
kind: AggregatorKind.SUM;

/** Returns snapshot of the current point (value with timestamp). */
toPoint(): Point<Sum>;
}

/**
* LastValueAggregatorType aggregate values into a {@link LastValue} point
* type.
*/
export interface LastValueAggregatorType extends BaseAggregator {
kind: AggregatorKind.LAST_VALUE;

/** Returns snapshot of the current point (value with timestamp). */
toPoint(): Point<LastValue>;
}

/**
* DistributionAggregatorType aggregate values into a {@link Distribution}
* point type.
*/
export interface DistributionAggregatorType extends BaseAggregator {
kind: AggregatorKind.DISTRIBUTION;

/** Returns snapshot of the current point (value with timestamp). */
toPoint(): Point<Distribution>;
}

/**
* HistogramAggregatorType aggregate values into a {@link Histogram} point
* type.
*/
export interface HistogramAggregatorType extends BaseAggregator {
kind: AggregatorKind.HISTOGRAM;

/** Returns snapshot of the current point (value with timestamp). */
toPoint(): Point;
toPoint(): Point<Histogram>;
}

export interface Point {
value: Sum | LastValue | Distribution | Histogram;
export type Aggregator =
| SumAggregatorType
| LastValueAggregatorType
| DistributionAggregatorType
| HistogramAggregatorType;

/**
* Point represents a snapshot of aggregated values of aggregators.
*/
export interface Point<T extends PointValueType> {
value: T;
timestamp: HrTime;
}

0 comments on commit 2c3bd5d

Please sign in to comment.