Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(metrics): distinguish different aggregator types #1325

Merged
merged 4 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
obecny marked this conversation as resolved.
Show resolved Hide resolved
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 {
obecny marked this conversation as resolved.
Show resolved Hide resolved
/** 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 {
obecny marked this conversation as resolved.
Show resolved Hide resolved
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> {
obecny marked this conversation as resolved.
Show resolved Hide resolved
value: T;
timestamp: HrTime;
}