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

feat: Export MinMaxLastSumCountAggregator metrics to the collector as Summary #1320

Merged
merged 14 commits into from
Aug 4, 2020
44 changes: 39 additions & 5 deletions packages/opentelemetry-exporter-collector/src/transformMetrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ export function toCollectorType(
if (metric.aggregator instanceof HistogramAggregator) {
return opentelemetryProto.metrics.v1.MetricDescriptorType.HISTOGRAM;
}
if (metric.aggregator instanceof MinMaxLastSumCountAggregator) {
return opentelemetryProto.metrics.v1.MetricDescriptorType.SUMMARY;
}
if (metric.descriptor.valueType == api.ValueType.INT) {
return opentelemetryProto.metrics.v1.MetricDescriptorType.INT64;
}
Expand Down Expand Up @@ -132,10 +135,7 @@ export function toSingularPoint(
timeUnixNano: number;
value: number;
} {
const pointValue =
metric.aggregator instanceof MinMaxLastSumCountAggregator
? (metric.aggregator.toPoint().value as Distribution).last
: (metric.aggregator.toPoint().value as number);
const pointValue = metric.aggregator.toPoint().value as number;
davidwitten marked this conversation as resolved.
Show resolved Hide resolved

return {
labels: toCollectorLabels(metric.labels),
Expand Down Expand Up @@ -172,6 +172,31 @@ export function toHistogramPoint(
};
}

/**
* Returns a SummaryPoint to the collector
* @param metric
* @param startTime
*/
export function toSummaryPoint(
metric: MetricRecord,
startTime: number
): opentelemetryProto.metrics.v1.SummaryDataPoint {
const distValue = metric.aggregator.toPoint().value as Distribution;
return {
labels: toCollectorLabels(metric.labels),
sum: distValue.sum,
count: distValue.count,
startTimeUnixNano: startTime,
timeUnixNano: core.hrTimeToNanoseconds(
metric.aggregator.toPoint().timestamp
davidwitten marked this conversation as resolved.
Show resolved Hide resolved
),
percentileValues: [
{ percentile: 0, value: distValue.min },
{ percentile: 100, value: distValue.max },
],
};
}

/**
* Converts a metric to be compatible with the collector
* @param metric
Expand All @@ -190,6 +215,15 @@ export function toCollectorMetric(
histogramDataPoints: [toHistogramPoint(metric, startTime)],
};
}
if (
toCollectorType(metric) ===
opentelemetryProto.metrics.v1.MetricDescriptorType.SUMMARY
) {
return {
metricDescriptor: toCollectorMetricDescriptor(metric),
summaryDataPoints: [toSummaryPoint(metric, startTime)],
};
}
if (metric.descriptor.valueType == api.ValueType.INT) {
return {
metricDescriptor: toCollectorMetricDescriptor(metric),
Expand All @@ -201,7 +235,7 @@ export function toCollectorMetric(
metricDescriptor: toCollectorMetricDescriptor(metric),
doubleDataPoints: [toSingularPoint(metric, startTime)],
};
} // TODO: Add support for summary points once implemented
}

return {
metricDescriptor: toCollectorMetricDescriptor(metric),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ describe('CollectorMetricExporter - common', () => {
};
collectorExporter = new CollectorMetricExporter(collectorExporterConfig);
metrics = [];
metrics.push(Object.assign({}, mockCounter));
metrics.push(Object.assign({}, mockObserver));
metrics.push(mockCounter());
metrics.push(mockObserver());
});

afterEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,95 @@ import * as assert from 'assert';
import * as transform from '../../src/transformMetrics';
import {
mockCounter,
mockDoubleCounter,
mockObserver,
mockedResources,
mockedInstrumentationLibraries,
multiResourceMetrics,
multiInstrumentationLibraryMetrics,
ensureCounterIsCorrect,
ensureDoubleCounterIsCorrect,
ensureObserverIsCorrect,
mockHistogram,
ensureHistogramIsCorrect,
ensureValueRecorderIsCorrect,
mockValueRecorder,
} from '../helper';
import { HistogramAggregator } from '@opentelemetry/metrics';
import {
HistogramAggregator,
MetricRecord,
SumAggregator,
} from '@opentelemetry/metrics';
import { hrTimeToNanoseconds } from '@opentelemetry/core';
import { Resource } from '@opentelemetry/resources';
describe('transformMetrics', () => {
describe('toCollectorMetric', () => {
const counter: MetricRecord = mockCounter();
const doubleCounter: MetricRecord = mockDoubleCounter();
const observer: MetricRecord = mockObserver();
const histogram: MetricRecord = mockHistogram();
const recorder: MetricRecord = mockValueRecorder();
const invalidMetric: MetricRecord = {
descriptor: {
name: 'name',
description: 'description',
unit: 'unit',
metricKind: 8, // Not a valid metricKind
valueType: 2, // Not double or int
},
labels: {},
aggregator: new SumAggregator(),
resource: new Resource({}),
instrumentationLibrary: { name: 'x', version: 'y' },
};
beforeEach(() => {
// Counter
counter.aggregator.update(1);

// Double Counter
doubleCounter.aggregator.update(8);

// Observer
observer.aggregator.update(3);
observer.aggregator.update(6);

// Histogram
histogram.aggregator.update(7);
histogram.aggregator.update(14);
(histogram.aggregator as HistogramAggregator).reset();

// ValueRecorder
recorder.aggregator.update(5);
});
it('should convert metric', () => {
mockCounter.aggregator.update(1);
ensureCounterIsCorrect(
transform.toCollectorMetric(mockCounter, 1592602232694000000),
hrTimeToNanoseconds(mockCounter.aggregator.toPoint().timestamp)
transform.toCollectorMetric(counter, 1592602232694000000),
hrTimeToNanoseconds(counter.aggregator.toPoint().timestamp)
);
mockObserver.aggregator.update(10);
ensureObserverIsCorrect(
transform.toCollectorMetric(mockObserver, 1592602232694000000),
hrTimeToNanoseconds(mockObserver.aggregator.toPoint().timestamp)
transform.toCollectorMetric(observer, 1592602232694000000),
hrTimeToNanoseconds(observer.aggregator.toPoint().timestamp)
);
mockHistogram.aggregator.update(7);
mockHistogram.aggregator.update(14);
(mockHistogram.aggregator as HistogramAggregator).reset();
ensureHistogramIsCorrect(
transform.toCollectorMetric(mockHistogram, 1592602232694000000),
hrTimeToNanoseconds(mockHistogram.aggregator.toPoint().timestamp)
transform.toCollectorMetric(histogram, 1592602232694000000),
hrTimeToNanoseconds(histogram.aggregator.toPoint().timestamp)
);

mockValueRecorder.aggregator.update(5);
ensureValueRecorderIsCorrect(
transform.toCollectorMetric(mockValueRecorder, 1592602232694000000),
hrTimeToNanoseconds(mockValueRecorder.aggregator.toPoint().timestamp)
transform.toCollectorMetric(recorder, 1592602232694000000),
hrTimeToNanoseconds(recorder.aggregator.toPoint().timestamp)
);

ensureDoubleCounterIsCorrect(
transform.toCollectorMetric(doubleCounter, 1592602232694000000),
hrTimeToNanoseconds(doubleCounter.aggregator.toPoint().timestamp)
);

const emptyMetric = transform.toCollectorMetric(
invalidMetric,
1592602232694000000
);
assert.deepStrictEqual(emptyMetric.int64DataPoints, []);
});
});
describe('toCollectorMetricDescriptor', () => {
Expand Down
Loading