Skip to content

Commit

Permalink
feat(metrics): prototype experimental advice support (#3876)
Browse files Browse the repository at this point in the history
Co-authored-by: Marc Pichler <[email protected]>
  • Loading branch information
legendecas and pichlermarc authored Oct 11, 2023
1 parent f8e187b commit b6e532b
Show file tree
Hide file tree
Showing 22 changed files with 252 additions and 56 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/

### :rocket: (Enhancement)

* feat(metrics): prototype experimental advice support [#3876](https://github.com/open-telemetry/opentelemetry-js/pull/3876) @legendecas

### :bug: (Bug Fix)

### :books: (Refine Doc)
Expand Down
4 changes: 4 additions & 0 deletions api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.

## Unreleased

### :rocket: (Enhancement)

* feat(metrics): prototype experimental advice support [#3876](https://github.com/open-telemetry/opentelemetry-js/pull/3876) @legendecas

## 1.6.0

### :bug: (Bug Fix)
Expand Down
1 change: 1 addition & 0 deletions api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export {
ObservableUpDownCounter,
UpDownCounter,
BatchObservableCallback,
MetricAdvice,
MetricAttributes,
MetricAttributeValue,
ObservableCallback,
Expand Down
18 changes: 18 additions & 0 deletions api/src/metrics/Metric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ import { Attributes, AttributeValue } from '../common/Attributes';
import { Context } from '../context/types';
import { BatchObservableResult, ObservableResult } from './ObservableResult';

/**
* Advisory options influencing aggregation configuration parameters.
* @experimental
*/
export interface MetricAdvice {
/**
* Hint the explicit bucket boundaries for SDK if the metric is been
* aggregated with a HistogramAggregator.
*/
explicitBucketBoundaries?: number[];
}

/**
* Options needed for metric creation
*/
Expand All @@ -39,6 +51,12 @@ export interface MetricOptions {
* @default {@link ValueType.DOUBLE}
*/
valueType?: ValueType;

/**
* The advice influencing aggregation configuration parameters.
* @experimental
*/
advice?: MetricAdvice;
}

/** The Type of value. It describes how the data is reported. */
Expand Down
18 changes: 16 additions & 2 deletions packages/sdk-metrics/src/InstrumentDescriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
* limitations under the License.
*/

import { MetricOptions, ValueType, diag } from '@opentelemetry/api';
import {
MetricAdvice,
MetricOptions,
ValueType,
diag,
} from '@opentelemetry/api';
import { View } from './view/View';
import { equalsCaseInsensitive } from './utils';

Expand All @@ -31,14 +36,21 @@ export enum InstrumentType {
}

/**
* An interface describing the instrument.
* An internal interface describing the instrument.
*
* This is intentionally distinguished from the public MetricDescriptor (a.k.a. InstrumentDescriptor)
* which may not contains internal fields like metric advice.
*/
export interface InstrumentDescriptor {
readonly name: string;
readonly description: string;
readonly unit: string;
readonly type: InstrumentType;
readonly valueType: ValueType;
/**
* @experimental
*/
readonly advice: MetricAdvice;
}

export function createInstrumentDescriptor(
Expand All @@ -57,6 +69,7 @@ export function createInstrumentDescriptor(
description: options?.description ?? '',
unit: options?.unit ?? '',
valueType: options?.valueType ?? ValueType.DOUBLE,
advice: options?.advice ?? {},
};
}

Expand All @@ -70,6 +83,7 @@ export function createInstrumentDescriptorWithView(
type: instrument.type,
unit: instrument.unit,
valueType: instrument.valueType,
advice: instrument.advice,
};
}

Expand Down
15 changes: 7 additions & 8 deletions packages/sdk-metrics/src/ObservableResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
} from '@opentelemetry/api';
import { AttributeHashMap } from './state/HashMap';
import { isObservableInstrument, ObservableInstrument } from './Instruments';
import { InstrumentDescriptor } from '.';

/**
* The class implements {@link ObservableResult} interface.
Expand All @@ -35,24 +34,24 @@ export class ObservableResultImpl implements ObservableResult {
*/
_buffer = new AttributeHashMap<number>();

constructor(private _descriptor: InstrumentDescriptor) {}
constructor(
private _instrumentName: string,
private _valueType: ValueType
) {}

/**
* Observe a measurement of the value associated with the given attributes.
*/
observe(value: number, attributes: MetricAttributes = {}): void {
if (typeof value !== 'number') {
diag.warn(
`non-number value provided to metric ${this._descriptor.name}: ${value}`
`non-number value provided to metric ${this._instrumentName}: ${value}`
);
return;
}
if (
this._descriptor.valueType === ValueType.INT &&
!Number.isInteger(value)
) {
if (this._valueType === ValueType.INT && !Number.isInteger(value)) {
diag.warn(
`INT value type cannot accept a floating-point value for ${this._descriptor.name}, ignoring the fractional digits.`
`INT value type cannot accept a floating-point value for ${this._instrumentName}, ignoring the fractional digits.`
);
value = Math.trunc(value);
// ignore non-finite values.
Expand Down
5 changes: 2 additions & 3 deletions packages/sdk-metrics/src/aggregator/Drop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

import { HrTime } from '@opentelemetry/api';
import { AggregationTemporality } from '../export/AggregationTemporality';
import { MetricData } from '../export/MetricData';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import { MetricData, MetricDescriptor } from '../export/MetricData';
import { Maybe } from '../utils';
import { AggregatorKind, Aggregator, AccumulationRecord } from './types';

Expand All @@ -38,7 +37,7 @@ export class DropAggregator implements Aggregator<undefined> {
}

toMetricData(
_descriptor: InstrumentDescriptor,
_descriptor: MetricDescriptor,
_aggregationTemporality: AggregationTemporality,
_accumulationByAttributes: AccumulationRecord<undefined>[],
_endTime: HrTime
Expand Down
5 changes: 3 additions & 2 deletions packages/sdk-metrics/src/aggregator/ExponentialHistogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ import {
import {
DataPointType,
ExponentialHistogramMetricData,
MetricDescriptor,
} from '../export/MetricData';
import { diag, HrTime } from '@opentelemetry/api';
import { InstrumentDescriptor, InstrumentType } from '../InstrumentDescriptor';
import { InstrumentType } from '../InstrumentDescriptor';
import { Maybe } from '../utils';
import { AggregationTemporality } from '../export/AggregationTemporality';
import { Buckets } from './exponential-histogram/Buckets';
Expand Down Expand Up @@ -555,7 +556,7 @@ export class ExponentialHistogramAggregator
}

toMetricData(
descriptor: InstrumentDescriptor,
descriptor: MetricDescriptor,
aggregationTemporality: AggregationTemporality,
accumulationByAttributes: AccumulationRecord<ExponentialHistogramAccumulation>[],
endTime: HrTime
Expand Down
10 changes: 7 additions & 3 deletions packages/sdk-metrics/src/aggregator/Histogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ import {
Aggregator,
AggregatorKind,
} from './types';
import { DataPointType, HistogramMetricData } from '../export/MetricData';
import {
DataPointType,
HistogramMetricData,
MetricDescriptor,
} from '../export/MetricData';
import { HrTime } from '@opentelemetry/api';
import { InstrumentDescriptor, InstrumentType } from '../InstrumentDescriptor';
import { InstrumentType } from '../InstrumentDescriptor';
import { binarySearchLB, Maybe } from '../utils';
import { AggregationTemporality } from '../export/AggregationTemporality';

Expand Down Expand Up @@ -207,7 +211,7 @@ export class HistogramAggregator implements Aggregator<HistogramAccumulation> {
}

toMetricData(
descriptor: InstrumentDescriptor,
descriptor: MetricDescriptor,
aggregationTemporality: AggregationTemporality,
accumulationByAttributes: AccumulationRecord<HistogramAccumulation>[],
endTime: HrTime
Expand Down
9 changes: 6 additions & 3 deletions packages/sdk-metrics/src/aggregator/LastValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ import {
} from './types';
import { HrTime } from '@opentelemetry/api';
import { millisToHrTime, hrTimeToMicroseconds } from '@opentelemetry/core';
import { DataPointType, GaugeMetricData } from '../export/MetricData';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import {
DataPointType,
GaugeMetricData,
MetricDescriptor,
} from '../export/MetricData';
import { Maybe } from '../utils';
import { AggregationTemporality } from '../export/AggregationTemporality';

Expand Down Expand Up @@ -103,7 +106,7 @@ export class LastValueAggregator implements Aggregator<LastValueAccumulation> {
}

toMetricData(
descriptor: InstrumentDescriptor,
descriptor: MetricDescriptor,
aggregationTemporality: AggregationTemporality,
accumulationByAttributes: AccumulationRecord<LastValueAccumulation>[],
endTime: HrTime
Expand Down
9 changes: 6 additions & 3 deletions packages/sdk-metrics/src/aggregator/Sum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ import {
AccumulationRecord,
} from './types';
import { HrTime } from '@opentelemetry/api';
import { DataPointType, SumMetricData } from '../export/MetricData';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import {
DataPointType,
MetricDescriptor,
SumMetricData,
} from '../export/MetricData';
import { Maybe } from '../utils';
import { AggregationTemporality } from '../export/AggregationTemporality';

Expand Down Expand Up @@ -109,7 +112,7 @@ export class SumAggregator implements Aggregator<SumAccumulation> {
}

toMetricData(
descriptor: InstrumentDescriptor,
descriptor: MetricDescriptor,
aggregationTemporality: AggregationTemporality,
accumulationByAttributes: AccumulationRecord<SumAccumulation>[],
endTime: HrTime
Expand Down
7 changes: 3 additions & 4 deletions packages/sdk-metrics/src/aggregator/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

import { HrTime, MetricAttributes } from '@opentelemetry/api';
import { AggregationTemporality } from '../export/AggregationTemporality';
import { MetricData } from '../export/MetricData';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import { MetricData, MetricDescriptor } from '../export/MetricData';
import { Maybe } from '../utils';

/** The kind of aggregator. */
Expand Down Expand Up @@ -128,14 +127,14 @@ export interface Aggregator<T> {
/**
* Returns the {@link MetricData} that this {@link Aggregator} will produce.
*
* @param descriptor the metric instrument descriptor.
* @param descriptor the metric descriptor.
* @param aggregationTemporality the temporality of the resulting {@link MetricData}
* @param accumulationByAttributes the array of attributes and accumulation pairs.
* @param endTime the end time of the metric data.
* @return the {@link MetricData} that this {@link Aggregator} will produce.
*/
toMetricData(
descriptor: InstrumentDescriptor,
descriptor: MetricDescriptor,
aggregationTemporality: AggregationTemporality,
accumulationByAttributes: AccumulationRecord<T>[],
endTime: HrTime
Expand Down
18 changes: 15 additions & 3 deletions packages/sdk-metrics/src/export/MetricData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,30 @@
* limitations under the License.
*/

import { HrTime, MetricAttributes } from '@opentelemetry/api';
import { HrTime, MetricAttributes, ValueType } from '@opentelemetry/api';
import { InstrumentationScope } from '@opentelemetry/core';
import { IResource } from '@opentelemetry/resources';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import { InstrumentType } from '../InstrumentDescriptor';
import { AggregationTemporality } from './AggregationTemporality';
import { Histogram, ExponentialHistogram } from '../aggregator/types';

export interface MetricDescriptor {
readonly name: string;
readonly description: string;
readonly unit: string;
/**
* @deprecated exporter should avoid depending on the type of the instrument
* as their resulting aggregator can be re-mapped with views.
*/
readonly type: InstrumentType;
readonly valueType: ValueType;
}

/**
* Basic metric data fields.
*/
interface BaseMetricData {
readonly descriptor: InstrumentDescriptor;
readonly descriptor: MetricDescriptor;
readonly aggregationTemporality: AggregationTemporality;
/**
* DataPointType of the metric instrument.
Expand Down
9 changes: 8 additions & 1 deletion packages/sdk-metrics/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/

import { MetricDescriptor } from './export/MetricData';

export {
Sum,
LastValue,
Expand All @@ -38,6 +40,7 @@ export {
ResourceMetrics,
ScopeMetrics,
MetricData,
MetricDescriptor,
CollectionResult,
} from './export/MetricData';

Expand All @@ -56,7 +59,11 @@ export { ConsoleMetricExporter } from './export/ConsoleMetricExporter';

export { MetricCollectOptions, MetricProducer } from './export/MetricProducer';

export { InstrumentDescriptor, InstrumentType } from './InstrumentDescriptor';
export { InstrumentType } from './InstrumentDescriptor';
/**
* @deprecated Use {@link MetricDescriptor} instead.
*/
export type InstrumentDescriptor = MetricDescriptor;

export { MeterProvider, MeterProviderOptions } from './MeterProvider';

Expand Down
1 change: 1 addition & 0 deletions packages/sdk-metrics/src/state/MetricStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export abstract class MetricStorage {
description: description,
valueType: this._instrumentDescriptor.valueType,
unit: this._instrumentDescriptor.unit,
advice: this._instrumentDescriptor.advice,
}
);
}
Expand Down
5 changes: 4 additions & 1 deletion packages/sdk-metrics/src/state/ObservableRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ export class ObservableRegistry {

private _observeCallbacks(observationTime: HrTime, timeoutMillis?: number) {
return this._callbacks.map(async ({ callback, instrument }) => {
const observableResult = new ObservableResultImpl(instrument._descriptor);
const observableResult = new ObservableResultImpl(
instrument._descriptor.name,
instrument._descriptor.valueType
);
let callPromise: Promise<void> = Promise.resolve(
callback(observableResult)
);
Expand Down
5 changes: 5 additions & 0 deletions packages/sdk-metrics/src/view/Aggregation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ export class DefaultAggregation extends Aggregation {
return LAST_VALUE_AGGREGATION;
}
case InstrumentType.HISTOGRAM: {
if (instrument.advice.explicitBucketBoundaries) {
return new ExplicitBucketHistogramAggregation(
instrument.advice.explicitBucketBoundaries
);
}
return HISTOGRAM_AGGREGATION;
}
}
Expand Down
Loading

0 comments on commit b6e532b

Please sign in to comment.