379 lines
11 KiB
TypeScript
379 lines
11 KiB
TypeScript
/*
|
|
* 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 { HrTime, ValueType } from '@opentelemetry/api';
|
|
import * as assert from 'assert';
|
|
import {
|
|
AggregationTemporality,
|
|
InstrumentType,
|
|
DataPointType,
|
|
MetricData,
|
|
} from '../../src';
|
|
import {
|
|
HistogramAccumulation,
|
|
HistogramAggregator,
|
|
} from '../../src/aggregator';
|
|
import { commonValues, defaultInstrumentDescriptor } from '../util';
|
|
|
|
describe('HistogramAggregator', () => {
|
|
describe('createAccumulation', () => {
|
|
it('no exceptions on createAccumulation', () => {
|
|
const aggregator = new HistogramAggregator([1, 10, 100], true);
|
|
const accumulation = aggregator.createAccumulation([0, 0]);
|
|
assert.ok(accumulation instanceof HistogramAccumulation);
|
|
});
|
|
});
|
|
|
|
describe('merge', () => {
|
|
it('no exceptions', () => {
|
|
const aggregator = new HistogramAggregator([1, 10, 100], true);
|
|
const prev = aggregator.createAccumulation([0, 0]);
|
|
prev.record(0);
|
|
prev.record(1);
|
|
|
|
const delta = aggregator.createAccumulation([1, 1]);
|
|
delta.record(2);
|
|
delta.record(11);
|
|
|
|
const expected = aggregator.createAccumulation([0, 0]);
|
|
// replay actions on prev
|
|
expected.record(0);
|
|
expected.record(1);
|
|
// replay actions on delta
|
|
expected.record(2);
|
|
expected.record(11);
|
|
|
|
assert.deepStrictEqual(aggregator.merge(prev, delta), expected);
|
|
});
|
|
|
|
it('with only negatives', () => {
|
|
const aggregator = new HistogramAggregator([1, 10, 100], true);
|
|
const prev = aggregator.createAccumulation([0, 0]);
|
|
prev.record(-10);
|
|
prev.record(-20);
|
|
|
|
const delta = aggregator.createAccumulation([1, 1]);
|
|
delta.record(-5);
|
|
delta.record(-30);
|
|
|
|
assert.deepStrictEqual(aggregator.merge(prev, delta).toPointValue(), {
|
|
buckets: {
|
|
boundaries: [1, 10, 100],
|
|
counts: [4, 0, 0, 0],
|
|
},
|
|
count: 4,
|
|
hasMinMax: true,
|
|
max: -5,
|
|
min: -30,
|
|
sum: -65,
|
|
});
|
|
});
|
|
|
|
it('with single bucket', function () {
|
|
const aggregator = new HistogramAggregator([], true);
|
|
const prev = aggregator.createAccumulation([0, 0]);
|
|
prev.record(0);
|
|
prev.record(1);
|
|
|
|
const delta = aggregator.createAccumulation([1, 1]);
|
|
delta.record(2);
|
|
delta.record(11);
|
|
|
|
const expected = new HistogramAccumulation([0, 0], [], true, {
|
|
buckets: {
|
|
boundaries: [],
|
|
counts: [4],
|
|
},
|
|
count: 4,
|
|
sum: 14,
|
|
hasMinMax: true,
|
|
min: 0,
|
|
max: 11,
|
|
});
|
|
assert.deepStrictEqual(aggregator.merge(prev, delta), expected);
|
|
});
|
|
});
|
|
|
|
describe('diff', () => {
|
|
it('no exceptions', () => {
|
|
const aggregator = new HistogramAggregator([1, 10, 100], true);
|
|
const prev = aggregator.createAccumulation([0, 0]);
|
|
prev.record(0);
|
|
prev.record(1);
|
|
|
|
const curr = aggregator.createAccumulation([1, 1]);
|
|
// replay actions on prev
|
|
curr.record(0);
|
|
curr.record(1);
|
|
// perform new actions
|
|
curr.record(2);
|
|
curr.record(11);
|
|
|
|
const expected = new HistogramAccumulation([1, 1], [1, 10, 100], true, {
|
|
buckets: {
|
|
boundaries: [1, 10, 100],
|
|
counts: [0, 1, 1, 0],
|
|
},
|
|
count: 2,
|
|
sum: 13,
|
|
hasMinMax: false,
|
|
min: Infinity,
|
|
max: -Infinity,
|
|
});
|
|
|
|
assert.deepStrictEqual(aggregator.diff(prev, curr), expected);
|
|
});
|
|
|
|
it('with single bucket', function () {
|
|
const aggregator = new HistogramAggregator([], true);
|
|
const prev = aggregator.createAccumulation([0, 0]);
|
|
prev.record(0);
|
|
prev.record(1);
|
|
|
|
const curr = aggregator.createAccumulation([1, 1]);
|
|
// replay actions on prev
|
|
curr.record(0);
|
|
curr.record(1);
|
|
// perform new actions
|
|
curr.record(2);
|
|
curr.record(11);
|
|
|
|
const expected = new HistogramAccumulation([1, 1], [], true, {
|
|
buckets: {
|
|
boundaries: [],
|
|
counts: [2],
|
|
},
|
|
count: 2,
|
|
sum: 13,
|
|
hasMinMax: false,
|
|
min: Infinity,
|
|
max: -Infinity,
|
|
});
|
|
|
|
assert.deepStrictEqual(aggregator.diff(prev, curr), expected);
|
|
});
|
|
});
|
|
|
|
describe('toMetricData', () => {
|
|
it('should transform to expected data with recordMinMax = true', () => {
|
|
const aggregator = new HistogramAggregator([1, 10, 100], true);
|
|
|
|
const startTime: HrTime = [0, 0];
|
|
const endTime: HrTime = [1, 1];
|
|
const accumulation = aggregator.createAccumulation(startTime);
|
|
accumulation.record(0);
|
|
accumulation.record(1);
|
|
|
|
const expected: MetricData = {
|
|
descriptor: defaultInstrumentDescriptor,
|
|
aggregationTemporality: AggregationTemporality.CUMULATIVE,
|
|
dataPointType: DataPointType.HISTOGRAM,
|
|
dataPoints: [
|
|
{
|
|
attributes: {},
|
|
startTime,
|
|
endTime,
|
|
value: {
|
|
buckets: {
|
|
boundaries: [1, 10, 100],
|
|
counts: [2, 0, 0, 0],
|
|
},
|
|
count: 2,
|
|
sum: 1,
|
|
min: 0,
|
|
max: 1,
|
|
},
|
|
},
|
|
],
|
|
};
|
|
assert.deepStrictEqual(
|
|
aggregator.toMetricData(
|
|
defaultInstrumentDescriptor,
|
|
AggregationTemporality.CUMULATIVE,
|
|
[[{}, accumulation]],
|
|
endTime
|
|
),
|
|
expected
|
|
);
|
|
});
|
|
|
|
it('should transform to expected data with recordMinMax = false', () => {
|
|
const aggregator = new HistogramAggregator([1, 10, 100], false);
|
|
|
|
const startTime: HrTime = [0, 0];
|
|
const endTime: HrTime = [1, 1];
|
|
const accumulation = aggregator.createAccumulation(startTime);
|
|
accumulation.record(0);
|
|
accumulation.record(1);
|
|
|
|
const expected: MetricData = {
|
|
descriptor: defaultInstrumentDescriptor,
|
|
aggregationTemporality: AggregationTemporality.CUMULATIVE,
|
|
dataPointType: DataPointType.HISTOGRAM,
|
|
dataPoints: [
|
|
{
|
|
attributes: {},
|
|
startTime,
|
|
endTime,
|
|
value: {
|
|
buckets: {
|
|
boundaries: [1, 10, 100],
|
|
counts: [2, 0, 0, 0],
|
|
},
|
|
count: 2,
|
|
sum: 1,
|
|
min: undefined,
|
|
max: undefined,
|
|
},
|
|
},
|
|
],
|
|
};
|
|
assert.deepStrictEqual(
|
|
aggregator.toMetricData(
|
|
defaultInstrumentDescriptor,
|
|
AggregationTemporality.CUMULATIVE,
|
|
[[{}, accumulation]],
|
|
endTime
|
|
),
|
|
expected
|
|
);
|
|
});
|
|
|
|
it('should transform to expected data with empty boundaries', () => {
|
|
const aggregator = new HistogramAggregator([], false);
|
|
|
|
const startTime: HrTime = [0, 0];
|
|
const endTime: HrTime = [1, 1];
|
|
const accumulation = aggregator.createAccumulation(startTime);
|
|
accumulation.record(0);
|
|
accumulation.record(1);
|
|
|
|
const expected: MetricData = {
|
|
descriptor: defaultInstrumentDescriptor,
|
|
aggregationTemporality: AggregationTemporality.CUMULATIVE,
|
|
dataPointType: DataPointType.HISTOGRAM,
|
|
dataPoints: [
|
|
{
|
|
attributes: {},
|
|
startTime,
|
|
endTime,
|
|
value: {
|
|
buckets: {
|
|
boundaries: [],
|
|
counts: [2],
|
|
},
|
|
count: 2,
|
|
sum: 1,
|
|
min: undefined,
|
|
max: undefined,
|
|
},
|
|
},
|
|
],
|
|
};
|
|
assert.deepStrictEqual(
|
|
aggregator.toMetricData(
|
|
defaultInstrumentDescriptor,
|
|
AggregationTemporality.CUMULATIVE,
|
|
[[{}, accumulation]],
|
|
endTime
|
|
),
|
|
expected
|
|
);
|
|
});
|
|
|
|
function testSum(instrumentType: InstrumentType, expectSum: boolean) {
|
|
const aggregator = new HistogramAggregator([1, 10, 100], true);
|
|
|
|
const startTime: HrTime = [0, 0];
|
|
const endTime: HrTime = [1, 1];
|
|
|
|
const accumulation = aggregator.createAccumulation(startTime);
|
|
accumulation.record(0);
|
|
accumulation.record(1);
|
|
accumulation.record(4);
|
|
|
|
const aggregatedData = aggregator.toMetricData(
|
|
{
|
|
name: 'default_metric',
|
|
description: 'a simple instrument',
|
|
type: instrumentType,
|
|
unit: '1',
|
|
valueType: ValueType.DOUBLE,
|
|
advice: {},
|
|
},
|
|
AggregationTemporality.CUMULATIVE,
|
|
[[{}, accumulation]],
|
|
endTime
|
|
);
|
|
|
|
assert.notStrictEqual(aggregatedData, undefined);
|
|
assert.strictEqual(
|
|
aggregatedData?.dataPoints[0].value.sum,
|
|
expectSum ? 5 : undefined
|
|
);
|
|
}
|
|
|
|
describe('should have undefined sum when used with', () => {
|
|
it('UpDownCounter', () => testSum(InstrumentType.UP_DOWN_COUNTER, false));
|
|
it('ObservableUpDownCounter', () =>
|
|
testSum(InstrumentType.OBSERVABLE_UP_DOWN_COUNTER, false));
|
|
it('ObservableUpDownCounter', () =>
|
|
testSum(InstrumentType.OBSERVABLE_GAUGE, false));
|
|
});
|
|
|
|
describe('should include sum with', () => {
|
|
it('UpDownCounter', () => testSum(InstrumentType.COUNTER, true));
|
|
it('ObservableUpDownCounter', () =>
|
|
testSum(InstrumentType.HISTOGRAM, true));
|
|
it('ObservableUpDownCounter', () =>
|
|
testSum(InstrumentType.OBSERVABLE_COUNTER, true));
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('HistogramAccumulation', () => {
|
|
describe('record', () => {
|
|
it('no exceptions on record', () => {
|
|
const accumulation = new HistogramAccumulation([0, 0], [1, 10, 100]);
|
|
|
|
for (const value of commonValues) {
|
|
accumulation.record(value);
|
|
}
|
|
});
|
|
|
|
it('ignores NaN', () => {
|
|
const accumulation = new HistogramAccumulation([0, 0], [1, 10, 100]);
|
|
|
|
accumulation.record(NaN);
|
|
|
|
const pointValue = accumulation.toPointValue();
|
|
assert.strictEqual(pointValue.max, -Infinity);
|
|
assert.strictEqual(pointValue.min, Infinity);
|
|
assert.strictEqual(pointValue.sum, 0);
|
|
assert.strictEqual(pointValue.count, 0);
|
|
assert.deepStrictEqual(pointValue.buckets.counts, [0, 0, 0, 0]);
|
|
});
|
|
});
|
|
|
|
describe('setStartTime', () => {
|
|
it('should set start time', () => {
|
|
const accumulation = new HistogramAccumulation([0, 0], [1, 10, 100]);
|
|
accumulation.setStartTime([1, 1]);
|
|
assert.deepStrictEqual(accumulation.startTime, [1, 1]);
|
|
});
|
|
});
|
|
});
|