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

Metrics: Use ReadOnlyTagCollection to encapsulate key/values on MetricPoint #2642

Merged
merged 9 commits into from
Nov 20, 2021
13 changes: 5 additions & 8 deletions src/OpenTelemetry.Exporter.Console/ConsoleMetricExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,12 @@ public override ExportResult Export(in Batch<Metric> batch)
{
string valueDisplay = string.Empty;
StringBuilder tagsBuilder = new StringBuilder();
if (metricPoint.Keys != null)
foreach (var tag in metricPoint.Tags)
{
for (int i = 0; i < metricPoint.Keys.Length; i++)
{
tagsBuilder.Append(metricPoint.Keys[i]);
tagsBuilder.Append(':');
tagsBuilder.Append(metricPoint.Values[i]);
tagsBuilder.Append(' ');
}
tagsBuilder.Append(tag.Key);
tagsBuilder.Append(':');
tagsBuilder.Append(tag.Value);
tagsBuilder.Append(' ');
}

var tags = tagsBuilder.ToString().TrimEnd();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ internal static OtlpMetrics.Metric ToOtlpMetric(this Metric metric)
TimeUnixNano = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(),
};

AddAttributes(metricPoint.Keys, metricPoint.Values, dataPoint.Attributes);
AddAttributes(metricPoint.Tags, dataPoint.Attributes);

dataPoint.AsInt = metricPoint.LongValue;
sum.DataPoints.Add(dataPoint);
Expand All @@ -180,7 +180,7 @@ internal static OtlpMetrics.Metric ToOtlpMetric(this Metric metric)
TimeUnixNano = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(),
};

AddAttributes(metricPoint.Keys, metricPoint.Values, dataPoint.Attributes);
AddAttributes(metricPoint.Tags, dataPoint.Attributes);

dataPoint.AsDouble = metricPoint.DoubleValue;
sum.DataPoints.Add(dataPoint);
Expand All @@ -201,7 +201,7 @@ internal static OtlpMetrics.Metric ToOtlpMetric(this Metric metric)
TimeUnixNano = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(),
};

AddAttributes(metricPoint.Keys, metricPoint.Values, dataPoint.Attributes);
AddAttributes(metricPoint.Tags, dataPoint.Attributes);

dataPoint.AsInt = metricPoint.LongValue;
gauge.DataPoints.Add(dataPoint);
Expand All @@ -222,7 +222,7 @@ internal static OtlpMetrics.Metric ToOtlpMetric(this Metric metric)
TimeUnixNano = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(),
};

AddAttributes(metricPoint.Keys, metricPoint.Values, dataPoint.Attributes);
AddAttributes(metricPoint.Tags, dataPoint.Attributes);

dataPoint.AsDouble = metricPoint.DoubleValue;
gauge.DataPoints.Add(dataPoint);
Expand All @@ -245,7 +245,7 @@ internal static OtlpMetrics.Metric ToOtlpMetric(this Metric metric)
TimeUnixNano = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(),
};

AddAttributes(metricPoint.Keys, metricPoint.Values, dataPoint.Attributes);
AddAttributes(metricPoint.Tags, dataPoint.Attributes);
dataPoint.Count = (ulong)metricPoint.LongValue;
dataPoint.Sum = metricPoint.DoubleValue;

Expand All @@ -272,15 +272,11 @@ internal static OtlpMetrics.Metric ToOtlpMetric(this Metric metric)
return otlpMetric;
}

private static void AddAttributes(string[] keys, object[] values, RepeatedField<OtlpCommon.KeyValue> attributes)
private static void AddAttributes(ReadOnlyTagCollection tags, RepeatedField<OtlpCommon.KeyValue> attributes)
{
if (keys != null)
foreach (var tag in tags)
{
for (int i = 0; i < keys.Length; i++)
{
KeyValuePair<string, object> tag = new KeyValuePair<string, object>(keys[i], values[i]);
attributes.Add(tag.ToOtlpAttribute());
}
attributes.Add(tag.ToOtlpAttribute());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,25 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric)
{
foreach (ref var metricPoint in metric.GetMetricPoints())
{
var keys = metricPoint.Keys;
var values = metricPoint.Values;
var tags = metricPoint.Tags;
var timestamp = metricPoint.EndTime.ToUnixTimeMilliseconds();

// Counter and Gauge
cursor = WriteMetricName(buffer, cursor, metric.Name, metric.Unit);

if (keys != null && keys.Length > 0)
if (tags.Count > 0)
{
buffer[cursor++] = unchecked((byte)'{');

for (var i = 0; i < keys.Length; i++)
int i = 0;
foreach (var tag in tags)
{
if (i > 0)
if (i++ > 0)
{
buffer[cursor++] = unchecked((byte)',');
}

cursor = WriteLabel(buffer, cursor, keys[i], values[i]);
cursor = WriteLabel(buffer, cursor, tag.Key, tag.Value);
}

buffer[cursor++] = unchecked((byte)'}');
Expand Down Expand Up @@ -85,8 +85,7 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric)
{
foreach (ref var metricPoint in metric.GetMetricPoints())
{
var keys = metricPoint.Keys;
var values = metricPoint.Values;
var tags = metricPoint.Tags;
var timestamp = metricPoint.EndTime.ToUnixTimeMilliseconds();

// Histogram buckets
Expand All @@ -100,13 +99,10 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric)
cursor = WriteMetricName(buffer, cursor, metric.Name, metric.Unit);
cursor = WriteAsciiStringNoEscape(buffer, cursor, "_bucket{");

if (keys != null)
foreach (var tag in tags)
{
for (var i = 0; i < keys.Length; i++)
{
cursor = WriteLabel(buffer, cursor, keys[i], values[i]);
buffer[cursor++] = unchecked((byte)',');
}
cursor = WriteLabel(buffer, cursor, tag.Key, tag.Value);
buffer[cursor++] = unchecked((byte)',');
}

cursor = WriteAsciiStringNoEscape(buffer, cursor, "le=\"");
Expand Down Expand Up @@ -134,18 +130,19 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric)
cursor = WriteMetricName(buffer, cursor, metric.Name, metric.Unit);
cursor = WriteAsciiStringNoEscape(buffer, cursor, "_sum");

if (keys != null && keys.Length > 0)
if (tags.Count > 0)
{
buffer[cursor++] = unchecked((byte)'{');

for (var i = 0; i < keys.Length; i++)
int i = 0;
foreach (var tag in tags)
{
if (i > 0)
if (i++ > 0)
{
buffer[cursor++] = unchecked((byte)',');
}

cursor = WriteLabel(buffer, cursor, keys[i], values[i]);
cursor = WriteLabel(buffer, cursor, tag.Key, tag.Value);
}

buffer[cursor++] = unchecked((byte)'}');
Expand All @@ -164,18 +161,19 @@ public static int WriteMetric(byte[] buffer, int cursor, Metric metric)
cursor = WriteMetricName(buffer, cursor, metric.Name, metric.Unit);
cursor = WriteAsciiStringNoEscape(buffer, cursor, "_count");

if (keys != null && keys.Length > 0)
if (tags.Count > 0)
{
buffer[cursor++] = unchecked((byte)'{');

for (var i = 0; i < keys.Length; i++)
int i = 0;
foreach (var tag in tags)
{
if (i > 0)
if (i++ > 0)
{
buffer[cursor++] = unchecked((byte)',');
}

cursor = WriteLabel(buffer, cursor, keys[i], values[i]);
cursor = WriteLabel(buffer, cursor, tag.Key, tag.Value);
}

buffer[cursor++] = unchecked((byte)'}');
Expand Down
11 changes: 9 additions & 2 deletions src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,10 @@ OpenTelemetry.Metrics.MetricPoint.BucketCounts.get -> long[]
OpenTelemetry.Metrics.MetricPoint.DoubleValue.get -> double
OpenTelemetry.Metrics.MetricPoint.EndTime.get -> System.DateTimeOffset
OpenTelemetry.Metrics.MetricPoint.ExplicitBounds.get -> double[]
OpenTelemetry.Metrics.MetricPoint.Keys.get -> string[]
OpenTelemetry.Metrics.MetricPoint.LongValue.get -> long
OpenTelemetry.Metrics.MetricPoint.MetricPoint() -> void
OpenTelemetry.Metrics.MetricPoint.StartTime.get -> System.DateTimeOffset
OpenTelemetry.Metrics.MetricPoint.Values.get -> object[]
OpenTelemetry.Metrics.MetricPoint.Tags.get -> OpenTelemetry.ReadOnlyTagCollection
OpenTelemetry.Metrics.MetricReader
OpenTelemetry.Metrics.MetricReader.Collect(int timeoutMilliseconds = -1) -> bool
OpenTelemetry.Metrics.MetricReader.Dispose() -> void
Expand Down Expand Up @@ -92,6 +91,14 @@ OpenTelemetry.Metrics.MetricType.LongSum = 26 -> OpenTelemetry.Metrics.MetricTyp
OpenTelemetry.Metrics.MetricTypeExtensions
OpenTelemetry.Metrics.PeriodicExportingMetricReader
OpenTelemetry.Metrics.PeriodicExportingMetricReader.PeriodicExportingMetricReader(OpenTelemetry.BaseExporter<OpenTelemetry.Metrics.Metric> exporter, int exportIntervalMilliseconds = 60000, int exportTimeoutMilliseconds = 30000) -> void
OpenTelemetry.ReadOnlyTagCollection
OpenTelemetry.ReadOnlyTagCollection.Count.get -> int
OpenTelemetry.ReadOnlyTagCollection.Enumerator
OpenTelemetry.ReadOnlyTagCollection.Enumerator.Current.get -> System.Collections.Generic.KeyValuePair<string, object>
OpenTelemetry.ReadOnlyTagCollection.Enumerator.Enumerator() -> void
OpenTelemetry.ReadOnlyTagCollection.Enumerator.MoveNext() -> bool
OpenTelemetry.ReadOnlyTagCollection.GetEnumerator() -> OpenTelemetry.ReadOnlyTagCollection.Enumerator
OpenTelemetry.ReadOnlyTagCollection.ReadOnlyTagCollection() -> void
OpenTelemetry.Trace.BatchExportActivityProcessorOptions
OpenTelemetry.Trace.BatchExportActivityProcessorOptions.BatchExportActivityProcessorOptions() -> void
override OpenTelemetry.BaseExportProcessor<T>.OnForceFlush(int timeoutMilliseconds) -> bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,10 @@ OpenTelemetry.Metrics.MetricPoint.BucketCounts.get -> long[]
OpenTelemetry.Metrics.MetricPoint.DoubleValue.get -> double
OpenTelemetry.Metrics.MetricPoint.EndTime.get -> System.DateTimeOffset
OpenTelemetry.Metrics.MetricPoint.ExplicitBounds.get -> double[]
OpenTelemetry.Metrics.MetricPoint.Keys.get -> string[]
OpenTelemetry.Metrics.MetricPoint.LongValue.get -> long
OpenTelemetry.Metrics.MetricPoint.MetricPoint() -> void
OpenTelemetry.Metrics.MetricPoint.StartTime.get -> System.DateTimeOffset
OpenTelemetry.Metrics.MetricPoint.Values.get -> object[]
OpenTelemetry.Metrics.MetricPoint.Tags.get -> OpenTelemetry.ReadOnlyTagCollection
OpenTelemetry.Metrics.MetricReader
OpenTelemetry.Metrics.MetricReader.Collect(int timeoutMilliseconds = -1) -> bool
OpenTelemetry.Metrics.MetricReader.Dispose() -> void
Expand Down Expand Up @@ -92,6 +91,14 @@ OpenTelemetry.Metrics.MetricType.LongSum = 26 -> OpenTelemetry.Metrics.MetricTyp
OpenTelemetry.Metrics.MetricTypeExtensions
OpenTelemetry.Metrics.PeriodicExportingMetricReader
OpenTelemetry.Metrics.PeriodicExportingMetricReader.PeriodicExportingMetricReader(OpenTelemetry.BaseExporter<OpenTelemetry.Metrics.Metric> exporter, int exportIntervalMilliseconds = 60000, int exportTimeoutMilliseconds = 30000) -> void
OpenTelemetry.ReadOnlyTagCollection
OpenTelemetry.ReadOnlyTagCollection.Count.get -> int
OpenTelemetry.ReadOnlyTagCollection.Enumerator
OpenTelemetry.ReadOnlyTagCollection.Enumerator.Current.get -> System.Collections.Generic.KeyValuePair<string, object>
OpenTelemetry.ReadOnlyTagCollection.Enumerator.Enumerator() -> void
OpenTelemetry.ReadOnlyTagCollection.Enumerator.MoveNext() -> bool
OpenTelemetry.ReadOnlyTagCollection.GetEnumerator() -> OpenTelemetry.ReadOnlyTagCollection.Enumerator
OpenTelemetry.ReadOnlyTagCollection.ReadOnlyTagCollection() -> void
OpenTelemetry.Trace.BatchExportActivityProcessorOptions
OpenTelemetry.Trace.BatchExportActivityProcessorOptions.BatchExportActivityProcessorOptions() -> void
override OpenTelemetry.BaseExportProcessor<T>.OnForceFlush(int timeoutMilliseconds) -> bool
Expand Down
4 changes: 4 additions & 0 deletions src/OpenTelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

* Added `ReadOnlyTagCollection` and expose `Tags` on `MetricPoint` instead of
`Keys`+`Values`
([#2642](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2642))

## 1.2.0-beta2

Released 2021-Nov-19
Expand Down
32 changes: 17 additions & 15 deletions src/OpenTelemetry/Metrics/MetricPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@
// </copyright>

using System;
using System.Diagnostics;
using System.Threading;

namespace OpenTelemetry.Metrics
{
public struct MetricPoint
{
private readonly AggregationType aggType;
private readonly object lockObject;
private readonly long[] bucketCounts;
private long longVal;
private long lastLongSum;
private double doubleVal;
private double lastDoubleSum;
private object lockObject;
private long[] bucketCounts;

internal MetricPoint(
AggregationType aggType,
Expand All @@ -35,10 +37,11 @@ internal MetricPoint(
object[] values,
double[] histogramBounds)
{
this.AggType = aggType;
Debug.Assert((keys?.Length ?? 0) == (values?.Length ?? 0), "Key and value array lengths did not match.");

this.aggType = aggType;
this.StartTime = startTime;
this.Keys = keys;
this.Values = values;
this.Tags = new ReadOnlyTagCollection(keys, values);
this.EndTime = default;
this.LongValue = default;
this.longVal = default;
Expand All @@ -48,14 +51,14 @@ internal MetricPoint(
this.lastDoubleSum = default;
this.MetricPointStatus = MetricPointStatus.NoCollectPending;

if (this.AggType == AggregationType.Histogram)
if (this.aggType == AggregationType.Histogram)
{
this.ExplicitBounds = histogramBounds;
this.BucketCounts = new long[this.ExplicitBounds.Length + 1];
this.bucketCounts = new long[this.ExplicitBounds.Length + 1];
this.lockObject = new object();
}
else if (this.AggType == AggregationType.HistogramSumCount)
else if (this.aggType == AggregationType.HistogramSumCount)
{
this.ExplicitBounds = null;
this.BucketCounts = null;
Expand All @@ -71,9 +74,10 @@ internal MetricPoint(
}
}

public string[] Keys { get; internal set; }

public object[] Values { get; internal set; }
/// <summary>
/// Gets the tags associated with the metric point.
/// </summary>
public ReadOnlyTagCollection Tags { get; }

public DateTimeOffset StartTime { get; internal set; }

Expand All @@ -89,11 +93,9 @@ internal MetricPoint(

internal MetricPointStatus MetricPointStatus { get; private set; }

private readonly AggregationType AggType { get; }

internal void Update(long number)
{
switch (this.AggType)
switch (this.aggType)
{
case AggregationType.LongSumIncomingDelta:
{
Expand Down Expand Up @@ -137,7 +139,7 @@ internal void Update(long number)

internal void Update(double number)
{
switch (this.AggType)
switch (this.aggType)
{
case AggregationType.DoubleSumIncomingDelta:
{
Expand Down Expand Up @@ -213,7 +215,7 @@ internal void Update(double number)

internal void TakeSnapshot(bool outputDelta)
{
switch (this.AggType)
switch (this.aggType)
{
case AggregationType.LongSumIncomingDelta:
case AggregationType.LongSumIncomingCumulative:
Expand Down
Loading