Skip to content

Commit

Permalink
Add support for monotonic sums, add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
saul committed Oct 29, 2024
1 parent 218c71a commit b412857
Show file tree
Hide file tree
Showing 2 changed files with 323 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Diagnostics;
using OpenTelemetry.Metrics;

namespace OpenTelemetry.Exporter.Prometheus;
Expand Down Expand Up @@ -28,8 +29,11 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe
cursor = WriteUnitMetadata(buffer, cursor, prometheusMetric, openMetricsRequested);
cursor = WriteHelpMetadata(buffer, cursor, prometheusMetric, metric.Description, openMetricsRequested);

var isLong = metric.MetricType.IsLong();
if (!metric.MetricType.IsHistogram())
{
var isSum = metric.MetricType.IsSum();

foreach (ref readonly var metricPoint in metric.GetMetricPoints())
{
var timestamp = metricPoint.EndTime.ToUnixTimeMilliseconds();
Expand All @@ -40,12 +44,9 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe

buffer[cursor++] = unchecked((byte)' ');

// TODO: MetricType is same for all MetricPoints
// within a given Metric, so this check can avoided
// for each MetricPoint
if (((int)metric.MetricType & 0b_0000_1111) == 0x0a /* I8 */)
if (isLong)
{
if (metric.MetricType.IsSum())
if (isSum)
{
cursor = WriteLong(buffer, cursor, metricPoint.GetSumLong());
}
Expand All @@ -56,7 +57,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe
}
else
{
if (metric.MetricType.IsSum())
if (isSum)
{
cursor = WriteDouble(buffer, cursor, metricPoint.GetSumDouble());
}
Expand All @@ -70,11 +71,18 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe

cursor = WriteTimestamp(buffer, cursor, timestamp, openMetricsRequested);

if (isSum && metricPoint.TryGetExemplars(out var exemplarCollection))
{
cursor = WriteSumExemplar(buffer, cursor, metric, openMetricsRequested, exemplarCollection);
}

buffer[cursor++] = ASCII_LINEFEED;
}
}
else
{
Debug.Assert(!isLong, "Expected histogram metric to be of type `double`");

foreach (ref readonly var metricPoint in metric.GetMetricPoints())
{
var tags = metricPoint.Tags;
Expand Down Expand Up @@ -115,7 +123,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe
{
if (exemplars.Current.DoubleValue <= histogramMeasurement.ExplicitBound)
{
cursor = WriteExemplar(buffer, cursor, exemplars.Current, openMetricsRequested, metric.Name);
cursor = WriteExemplar(buffer, cursor, exemplars.Current, openMetricsRequested, metric.Name, isLong: false);
}

while (hasExemplar && exemplars.Current.DoubleValue <= histogramMeasurement.ExplicitBound)
Expand Down Expand Up @@ -160,7 +168,44 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric, Promethe
return cursor;
}

private static int WriteExemplar(byte[] buffer, int cursor, in Exemplar exemplar, bool openMetricsRequested, string metricName)
private static int WriteSumExemplar(
byte[] buffer,
int cursor,
in Metric metric,
bool openMetricsRequested,
in ReadOnlyExemplarCollection exemplarCollection)
{
var exemplars = exemplarCollection.GetEnumerator();
if (!exemplars.MoveNext())
{
return cursor;
}

ref readonly Exemplar maxExemplar = ref exemplars.Current;
var isLong = metric.MetricType.IsLong();

while (exemplars.MoveNext())
{
if (isLong)
{
if (exemplars.Current.LongValue >= maxExemplar.LongValue)
{
maxExemplar = ref exemplars.Current;
}
}
else
{
if (exemplars.Current.DoubleValue >= maxExemplar.DoubleValue)
{
maxExemplar = ref exemplars.Current;
}
}
}

return WriteExemplar(buffer, cursor, maxExemplar, openMetricsRequested, metric.Name, isLong);
}

private static int WriteExemplar(byte[] buffer, int cursor, in Exemplar exemplar, bool openMetricsRequested, string metricName, bool isLong)
{
buffer[cursor++] = unchecked((byte)' ');
buffer[cursor++] = unchecked((byte)'#');
Expand Down Expand Up @@ -204,7 +249,15 @@ private static int WriteExemplar(byte[] buffer, int cursor, in Exemplar exemplar
buffer[cursor - 1] = unchecked((byte)'}'); // Note: We write the '}' over the last written comma, which is extra.
buffer[cursor++] = unchecked((byte)' ');

cursor = WriteDouble(buffer, cursor, exemplar.DoubleValue);
if (isLong)
{
cursor = WriteLong(buffer, cursor, exemplar.LongValue);
}
else
{
cursor = WriteDouble(buffer, cursor, exemplar.DoubleValue);
}

buffer[cursor++] = unchecked((byte)' ');
cursor = WriteTimestamp(buffer, cursor, exemplar.Timestamp.ToUnixTimeMilliseconds(), openMetricsRequested);

Expand Down
Loading

0 comments on commit b412857

Please sign in to comment.