Support UpDownCounter and ObservableUpDownCounter (#3606)
This commit is contained in:
parent
a37198c6d0
commit
c2f5e80b0d
|
|
@ -143,10 +143,11 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation
|
||||||
switch (metric.MetricType)
|
switch (metric.MetricType)
|
||||||
{
|
{
|
||||||
case MetricType.LongSum:
|
case MetricType.LongSum:
|
||||||
|
case MetricType.LongSumNonMonotonic:
|
||||||
{
|
{
|
||||||
var sum = new OtlpMetrics.Sum
|
var sum = new OtlpMetrics.Sum
|
||||||
{
|
{
|
||||||
IsMonotonic = true,
|
IsMonotonic = metric.MetricType == MetricType.LongSum,
|
||||||
AggregationTemporality = temporality,
|
AggregationTemporality = temporality,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -169,10 +170,11 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
case MetricType.DoubleSum:
|
case MetricType.DoubleSum:
|
||||||
|
case MetricType.DoubleSumNonMonotonic:
|
||||||
{
|
{
|
||||||
var sum = new OtlpMetrics.Sum
|
var sum = new OtlpMetrics.Sum
|
||||||
{
|
{
|
||||||
IsMonotonic = true,
|
IsMonotonic = metric.MetricType == MetricType.DoubleSum,
|
||||||
AggregationTemporality = temporality,
|
AggregationTemporality = temporality,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ namespace OpenTelemetry.Exporter.Prometheus
|
||||||
{
|
{
|
||||||
private static readonly string[] MetricTypes = new string[]
|
private static readonly string[] MetricTypes = new string[]
|
||||||
{
|
{
|
||||||
"untyped", "counter", "gauge", "summary", "histogram", "histogram", "histogram", "histogram", "untyped",
|
"untyped", "counter", "gauge", "summary", "histogram", "histogram", "histogram", "histogram", "gauge",
|
||||||
};
|
};
|
||||||
|
|
||||||
public static int WriteMetric(byte[] buffer, int cursor, Metric metric)
|
public static int WriteMetric(byte[] buffer, int cursor, Metric metric)
|
||||||
|
|
|
||||||
|
|
@ -48,3 +48,5 @@ static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceColl
|
||||||
static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
||||||
~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder> configure) -> OpenTelemetry.Metrics.MeterProviderBuilder
|
~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder> configure) -> OpenTelemetry.Metrics.MeterProviderBuilder
|
||||||
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder!>! configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
|
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder!>! configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
|
||||||
|
OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType
|
||||||
|
OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType
|
||||||
|
|
|
||||||
|
|
@ -48,3 +48,5 @@ static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceColl
|
||||||
static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
||||||
~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder> configure) -> OpenTelemetry.Metrics.MeterProviderBuilder
|
~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder> configure) -> OpenTelemetry.Metrics.MeterProviderBuilder
|
||||||
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder!>! configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
|
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder!>! configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
|
||||||
|
OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType
|
||||||
|
OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType
|
||||||
|
|
|
||||||
|
|
@ -48,3 +48,5 @@ static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceColl
|
||||||
static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
||||||
~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder> configure) -> OpenTelemetry.Metrics.MeterProviderBuilder
|
~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder> configure) -> OpenTelemetry.Metrics.MeterProviderBuilder
|
||||||
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder!>! configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
|
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder!>! configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
|
||||||
|
OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType
|
||||||
|
OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType
|
||||||
|
|
|
||||||
|
|
@ -48,3 +48,5 @@ static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceColl
|
||||||
static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
||||||
~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder> configure) -> OpenTelemetry.Metrics.MeterProviderBuilder
|
~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder> configure) -> OpenTelemetry.Metrics.MeterProviderBuilder
|
||||||
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder!>! configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
|
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action<OpenTelemetry.Resources.ResourceBuilder!>! configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
|
||||||
|
OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType
|
||||||
|
OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@
|
||||||
* Allows samplers the ability to modify tracestate if desired.
|
* Allows samplers the ability to modify tracestate if desired.
|
||||||
([#3610](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3610))
|
([#3610](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3610))
|
||||||
|
|
||||||
|
* Added support for `UpDownCounter` and `ObservableUpDownCounter` instruments.
|
||||||
|
([#3606](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3606))
|
||||||
|
|
||||||
## 1.4.0-alpha.2
|
## 1.4.0-alpha.2
|
||||||
|
|
||||||
Released 2022-Aug-18
|
Released 2022-Aug-18
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,34 @@ namespace OpenTelemetry.Metrics
|
||||||
aggType = AggregationType.DoubleSumIncomingCumulative;
|
aggType = AggregationType.DoubleSumIncomingCumulative;
|
||||||
this.MetricType = MetricType.DoubleSum;
|
this.MetricType = MetricType.DoubleSum;
|
||||||
}
|
}
|
||||||
|
else if (instrumentIdentity.InstrumentType == typeof(ObservableUpDownCounter<long>)
|
||||||
|
|| instrumentIdentity.InstrumentType == typeof(ObservableUpDownCounter<int>)
|
||||||
|
|| instrumentIdentity.InstrumentType == typeof(ObservableUpDownCounter<short>)
|
||||||
|
|| instrumentIdentity.InstrumentType == typeof(ObservableUpDownCounter<byte>))
|
||||||
|
{
|
||||||
|
aggType = AggregationType.LongSumIncomingCumulative;
|
||||||
|
this.MetricType = MetricType.LongSumNonMonotonic;
|
||||||
|
}
|
||||||
|
else if (instrumentIdentity.InstrumentType == typeof(UpDownCounter<long>)
|
||||||
|
|| instrumentIdentity.InstrumentType == typeof(UpDownCounter<int>)
|
||||||
|
|| instrumentIdentity.InstrumentType == typeof(UpDownCounter<short>)
|
||||||
|
|| instrumentIdentity.InstrumentType == typeof(UpDownCounter<byte>))
|
||||||
|
{
|
||||||
|
aggType = AggregationType.LongSumIncomingDelta;
|
||||||
|
this.MetricType = MetricType.LongSumNonMonotonic;
|
||||||
|
}
|
||||||
|
else if (instrumentIdentity.InstrumentType == typeof(UpDownCounter<double>)
|
||||||
|
|| instrumentIdentity.InstrumentType == typeof(UpDownCounter<float>))
|
||||||
|
{
|
||||||
|
aggType = AggregationType.DoubleSumIncomingDelta;
|
||||||
|
this.MetricType = MetricType.DoubleSumNonMonotonic;
|
||||||
|
}
|
||||||
|
else if (instrumentIdentity.InstrumentType == typeof(ObservableUpDownCounter<double>)
|
||||||
|
|| instrumentIdentity.InstrumentType == typeof(ObservableUpDownCounter<float>))
|
||||||
|
{
|
||||||
|
aggType = AggregationType.DoubleSumIncomingCumulative;
|
||||||
|
this.MetricType = MetricType.DoubleSumNonMonotonic;
|
||||||
|
}
|
||||||
else if (instrumentIdentity.InstrumentType == typeof(ObservableGauge<double>)
|
else if (instrumentIdentity.InstrumentType == typeof(ObservableGauge<double>)
|
||||||
|| instrumentIdentity.InstrumentType == typeof(ObservableGauge<float>))
|
|| instrumentIdentity.InstrumentType == typeof(ObservableGauge<float>))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,8 @@ namespace OpenTelemetry.Metrics
|
||||||
// Temporatlity is not defined for gauges, so this does not really affect anything.
|
// Temporatlity is not defined for gauges, so this does not really affect anything.
|
||||||
var type when type == typeof(ObservableGauge<>) => AggregationTemporality.Delta,
|
var type when type == typeof(ObservableGauge<>) => AggregationTemporality.Delta,
|
||||||
|
|
||||||
// With .NET 7 the OpenTelemetry .NET SDK will support UpDownCounters.
|
var type when type == typeof(UpDownCounter<>) => AggregationTemporality.Cumulative,
|
||||||
// These will be aggregated using Cumulative temporatlity.
|
var type when type == typeof(ObservableUpDownCounter<>) => AggregationTemporality.Cumulative,
|
||||||
// See:
|
|
||||||
// https://docs.microsoft.com/dotnet/api/system.diagnostics.metrics.updowncounter-1
|
|
||||||
// https://docs.microsoft.com/dotnet/api/system.diagnostics.metrics.observableupdowncounter-1
|
|
||||||
// var type when type == typeof(UpDownCounter<>) => AggregationTemporality.Cumulative,
|
|
||||||
// var type when type == typeof(ObservableUpDownCounter<>) => AggregationTemporality.Cumulative,
|
|
||||||
|
|
||||||
// TODO: Consider logging here because we should not fall through to this case.
|
// TODO: Consider logging here because we should not fall through to this case.
|
||||||
_ => AggregationTemporality.Delta,
|
_ => AggregationTemporality.Delta,
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ namespace OpenTelemetry.Metrics
|
||||||
0x50: HistogramWithMinMax (reserved)
|
0x50: HistogramWithMinMax (reserved)
|
||||||
0x60: ExponentialHistogram (reserved)
|
0x60: ExponentialHistogram (reserved)
|
||||||
0x70: ExponentialHistogramWithMinMax (reserved)
|
0x70: ExponentialHistogramWithMinMax (reserved)
|
||||||
0x80: Reserved
|
0x80: SumNonMonotonic
|
||||||
|
|
||||||
Point kind:
|
Point kind:
|
||||||
0x04: I1 (signed 1-byte integer)
|
0x04: I1 (signed 1-byte integer)
|
||||||
|
|
@ -69,5 +69,15 @@ namespace OpenTelemetry.Metrics
|
||||||
/// Histogram.
|
/// Histogram.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Histogram = 0x40,
|
Histogram = 0x40,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Non-monotonic Sum of Long type.
|
||||||
|
/// </summary>
|
||||||
|
LongSumNonMonotonic = 0x8a,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Non-monotonic Sum of Double type.
|
||||||
|
/// </summary>
|
||||||
|
DoubleSumNonMonotonic = 0x8d,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,11 @@ namespace OpenTelemetry.Metrics
|
||||||
|
|
||||||
internal const MetricType METRIC_TYPE_MASK = (MetricType)0xf0;
|
internal const MetricType METRIC_TYPE_MASK = (MetricType)0xf0;
|
||||||
|
|
||||||
internal const MetricType METRIC_TYPE_SUM = (MetricType)0x10;
|
internal const MetricType METRIC_TYPE_MONOTONIC_SUM = (MetricType)0x10;
|
||||||
internal const MetricType METRIC_TYPE_GAUGE = (MetricType)0x20;
|
internal const MetricType METRIC_TYPE_GAUGE = (MetricType)0x20;
|
||||||
/* internal const byte METRIC_TYPE_SUMMARY = 0x30; // not used */
|
/* internal const byte METRIC_TYPE_SUMMARY = 0x30; // not used */
|
||||||
internal const MetricType METRIC_TYPE_HISTOGRAM = (MetricType)0x40;
|
internal const MetricType METRIC_TYPE_HISTOGRAM = (MetricType)0x40;
|
||||||
|
internal const MetricType METRIC_TYPE_NON_MONOTONIC_SUM = (MetricType)0x80;
|
||||||
|
|
||||||
internal const MetricType POINT_KIND_MASK = (MetricType)0x0f;
|
internal const MetricType POINT_KIND_MASK = (MetricType)0x0f;
|
||||||
|
|
||||||
|
|
@ -47,7 +48,8 @@ namespace OpenTelemetry.Metrics
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool IsSum(this MetricType self)
|
public static bool IsSum(this MetricType self)
|
||||||
{
|
{
|
||||||
return (self & METRIC_TYPE_MASK) == METRIC_TYPE_SUM;
|
var type = self & METRIC_TYPE_MASK;
|
||||||
|
return type == METRIC_TYPE_MONOTONIC_SUM || type == METRIC_TYPE_NON_MONOTONIC_SUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|
|
||||||
|
|
@ -271,12 +271,12 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Cumulative, true)]
|
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Cumulative)]
|
||||||
[InlineData("test_counter", null, null, null, 123.45, MetricReaderTemporalityPreference.Cumulative, true)]
|
[InlineData("test_counter", null, null, null, 123.45, MetricReaderTemporalityPreference.Cumulative)]
|
||||||
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, true)]
|
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta)]
|
||||||
[InlineData("test_counter", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative, true)]
|
[InlineData("test_counter", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative)]
|
||||||
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, true, "key1", "value1", "key2", 123)]
|
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, "key1", "value1", "key2", 123)]
|
||||||
public void TestCounterToOtlpMetric(string name, string description, string unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool isMonotonic, params object[] keysValues)
|
public void TestCounterToOtlpMetric(string name, string description, string unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, params object[] keysValues)
|
||||||
{
|
{
|
||||||
var metrics = new List<Metric>();
|
var metrics = new List<Metric>();
|
||||||
|
|
||||||
|
|
@ -324,7 +324,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests
|
||||||
Assert.Null(actual.ExponentialHistogram);
|
Assert.Null(actual.ExponentialHistogram);
|
||||||
Assert.Null(actual.Summary);
|
Assert.Null(actual.Summary);
|
||||||
|
|
||||||
Assert.Equal(isMonotonic, actual.Sum.IsMonotonic);
|
Assert.True(actual.Sum.IsMonotonic);
|
||||||
|
|
||||||
var otlpAggregationTemporality = aggregationTemporality == MetricReaderTemporalityPreference.Cumulative
|
var otlpAggregationTemporality = aggregationTemporality == MetricReaderTemporalityPreference.Cumulative
|
||||||
? OtlpMetrics.AggregationTemporality.Cumulative
|
? OtlpMetrics.AggregationTemporality.Cumulative
|
||||||
|
|
@ -359,6 +359,95 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests
|
||||||
Assert.Empty(dataPoint.Exemplars);
|
Assert.Empty(dataPoint.Exemplars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Cumulative)]
|
||||||
|
[InlineData("test_counter", null, null, null, 123.45, MetricReaderTemporalityPreference.Cumulative)]
|
||||||
|
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta)]
|
||||||
|
[InlineData("test_counter", "description", "unit", 123L, null, MetricReaderTemporalityPreference.Cumulative)]
|
||||||
|
[InlineData("test_counter", null, null, 123L, null, MetricReaderTemporalityPreference.Delta, "key1", "value1", "key2", 123)]
|
||||||
|
public void TestUpDownCounterToOtlpMetric(string name, string description, string unit, long? longValue, double? doubleValue, MetricReaderTemporalityPreference aggregationTemporality, params object[] keysValues)
|
||||||
|
{
|
||||||
|
var metrics = new List<Metric>();
|
||||||
|
|
||||||
|
using var meter = new Meter(Utils.GetCurrentMethodName());
|
||||||
|
using var provider = Sdk.CreateMeterProviderBuilder()
|
||||||
|
.AddMeter(meter.Name)
|
||||||
|
.AddInMemoryExporter(metrics, metricReaderOptions =>
|
||||||
|
{
|
||||||
|
metricReaderOptions.TemporalityPreference = aggregationTemporality;
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var attributes = ToAttributes(keysValues).ToArray();
|
||||||
|
if (longValue.HasValue)
|
||||||
|
{
|
||||||
|
var counter = meter.CreateUpDownCounter<long>(name, unit, description);
|
||||||
|
counter.Add(longValue.Value, attributes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var counter = meter.CreateUpDownCounter<double>(name, unit, description);
|
||||||
|
counter.Add(doubleValue.Value, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
provider.ForceFlush();
|
||||||
|
|
||||||
|
var batch = new Batch<Metric>(metrics.ToArray(), metrics.Count);
|
||||||
|
|
||||||
|
var request = new OtlpCollector.ExportMetricsServiceRequest();
|
||||||
|
request.AddMetrics(ResourceBuilder.CreateEmpty().Build().ToOtlpResource(), batch);
|
||||||
|
|
||||||
|
var resourceMetric = request.ResourceMetrics.Single();
|
||||||
|
var scopeMetrics = resourceMetric.ScopeMetrics.Single();
|
||||||
|
var actual = scopeMetrics.Metrics.Single();
|
||||||
|
|
||||||
|
Assert.Equal(name, actual.Name);
|
||||||
|
Assert.Equal(description ?? string.Empty, actual.Description);
|
||||||
|
Assert.Equal(unit ?? string.Empty, actual.Unit);
|
||||||
|
|
||||||
|
Assert.Equal(OtlpMetrics.Metric.DataOneofCase.Sum, actual.DataCase);
|
||||||
|
|
||||||
|
Assert.Null(actual.Gauge);
|
||||||
|
Assert.NotNull(actual.Sum);
|
||||||
|
Assert.Null(actual.Histogram);
|
||||||
|
Assert.Null(actual.ExponentialHistogram);
|
||||||
|
Assert.Null(actual.Summary);
|
||||||
|
|
||||||
|
Assert.False(actual.Sum.IsMonotonic);
|
||||||
|
|
||||||
|
var otlpAggregationTemporality = aggregationTemporality == MetricReaderTemporalityPreference.Cumulative
|
||||||
|
? OtlpMetrics.AggregationTemporality.Cumulative
|
||||||
|
: OtlpMetrics.AggregationTemporality.Cumulative;
|
||||||
|
Assert.Equal(otlpAggregationTemporality, actual.Sum.AggregationTemporality);
|
||||||
|
|
||||||
|
Assert.Single(actual.Sum.DataPoints);
|
||||||
|
var dataPoint = actual.Sum.DataPoints.First();
|
||||||
|
Assert.True(dataPoint.StartTimeUnixNano > 0);
|
||||||
|
Assert.True(dataPoint.TimeUnixNano > 0);
|
||||||
|
|
||||||
|
if (longValue.HasValue)
|
||||||
|
{
|
||||||
|
Assert.Equal(OtlpMetrics.NumberDataPoint.ValueOneofCase.AsInt, dataPoint.ValueCase);
|
||||||
|
Assert.Equal(longValue, dataPoint.AsInt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal(OtlpMetrics.NumberDataPoint.ValueOneofCase.AsDouble, dataPoint.ValueCase);
|
||||||
|
Assert.Equal(doubleValue, dataPoint.AsDouble);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributes.Length > 0)
|
||||||
|
{
|
||||||
|
OtlpTestHelpers.AssertOtlpAttributes(attributes, dataPoint.Attributes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Empty(dataPoint.Attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Empty(dataPoint.Exemplars);
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Cumulative)]
|
[InlineData("test_histogram", null, null, 123L, null, MetricReaderTemporalityPreference.Cumulative)]
|
||||||
[InlineData("test_histogram", null, null, null, 123.45, MetricReaderTemporalityPreference.Cumulative)]
|
[InlineData("test_histogram", null, null, null, 123.45, MetricReaderTemporalityPreference.Cumulative)]
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,33 @@ namespace OpenTelemetry.Exporter.Prometheus.Tests
|
||||||
Encoding.UTF8.GetString(buffer, 0, cursor));
|
Encoding.UTF8.GetString(buffer, 0, cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SumNonMonotonicDouble()
|
||||||
|
{
|
||||||
|
var buffer = new byte[85000];
|
||||||
|
var metrics = new List<Metric>();
|
||||||
|
|
||||||
|
using var meter = new Meter(Utils.GetCurrentMethodName());
|
||||||
|
using var provider = Sdk.CreateMeterProviderBuilder()
|
||||||
|
.AddMeter(meter.Name)
|
||||||
|
.AddInMemoryExporter(metrics)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var counter = meter.CreateUpDownCounter<double>("test_updown_counter");
|
||||||
|
counter.Add(10);
|
||||||
|
counter.Add(-11);
|
||||||
|
|
||||||
|
provider.ForceFlush();
|
||||||
|
|
||||||
|
var cursor = PrometheusSerializer.WriteMetric(buffer, 0, metrics[0]);
|
||||||
|
Assert.Matches(
|
||||||
|
("^"
|
||||||
|
+ "# TYPE test_updown_counter gauge\n"
|
||||||
|
+ "test_updown_counter -1 \\d+\n"
|
||||||
|
+ "$").Replace('\'', '"'),
|
||||||
|
Encoding.UTF8.GetString(buffer, 0, cursor));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HistogramZeroDimension()
|
public void HistogramZeroDimension()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -586,7 +586,7 @@ namespace OpenTelemetry.Metrics.Tests
|
||||||
exportedItems.Clear();
|
exportedItems.Clear();
|
||||||
|
|
||||||
#if NETFRAMEWORK
|
#if NETFRAMEWORK
|
||||||
Thread.Sleep(5000); // Compensates for low resolution timing in netfx.
|
Thread.Sleep(10); // Compensates for low resolution timing in netfx.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
counterLong.Add(10);
|
counterLong.Add(10);
|
||||||
|
|
@ -864,6 +864,224 @@ namespace OpenTelemetry.Metrics.Tests
|
||||||
Assert.Equal(30, metricPoint1.GetSumLong());
|
Assert.Equal(30, metricPoint1.GetSumLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(true)]
|
||||||
|
[InlineData(false)]
|
||||||
|
public void UpDownCounterAggregationTest(bool exportDelta)
|
||||||
|
{
|
||||||
|
DateTime testStartTime = DateTime.UtcNow;
|
||||||
|
|
||||||
|
var exportedItems = new List<Metric>();
|
||||||
|
|
||||||
|
using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{exportDelta}");
|
||||||
|
var counterLong = meter.CreateUpDownCounter<long>("mycounter");
|
||||||
|
using var meterProvider = Sdk.CreateMeterProviderBuilder()
|
||||||
|
.AddMeter(meter.Name)
|
||||||
|
.AddInMemoryExporter(exportedItems, metricReaderOptions =>
|
||||||
|
{
|
||||||
|
metricReaderOptions.TemporalityPreference = exportDelta ? MetricReaderTemporalityPreference.Delta : MetricReaderTemporalityPreference.Cumulative;
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
counterLong.Add(10);
|
||||||
|
counterLong.Add(-5);
|
||||||
|
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||||
|
long sumReceived = GetLongSum(exportedItems);
|
||||||
|
Assert.Equal(5, sumReceived);
|
||||||
|
|
||||||
|
var metricPoint = GetFirstMetricPoint(exportedItems);
|
||||||
|
Assert.NotNull(metricPoint);
|
||||||
|
Assert.True(metricPoint.Value.StartTime >= testStartTime);
|
||||||
|
Assert.True(metricPoint.Value.EndTime != default);
|
||||||
|
|
||||||
|
DateTimeOffset firstRunStartTime = metricPoint.Value.StartTime;
|
||||||
|
DateTimeOffset firstRunEndTime = metricPoint.Value.EndTime;
|
||||||
|
|
||||||
|
exportedItems.Clear();
|
||||||
|
|
||||||
|
#if NETFRAMEWORK
|
||||||
|
Thread.Sleep(10); // Compensates for low resolution timing in netfx.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
counterLong.Add(10);
|
||||||
|
counterLong.Add(-5);
|
||||||
|
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||||
|
sumReceived = GetLongSum(exportedItems);
|
||||||
|
|
||||||
|
// Same for both cumulative and delta. MetricReaderTemporalityPreference.Delta implies cumulative for UpDownCounters.
|
||||||
|
Assert.Equal(10, sumReceived);
|
||||||
|
|
||||||
|
metricPoint = GetFirstMetricPoint(exportedItems);
|
||||||
|
Assert.NotNull(metricPoint);
|
||||||
|
Assert.True(metricPoint.Value.StartTime >= testStartTime);
|
||||||
|
Assert.True(metricPoint.Value.EndTime != default);
|
||||||
|
|
||||||
|
// Same for both cumulative and delta. MetricReaderTemporalityPreference.Delta implies cumulative for UpDownCounters.
|
||||||
|
Assert.Equal(firstRunStartTime, metricPoint.Value.StartTime);
|
||||||
|
|
||||||
|
Assert.True(metricPoint.Value.EndTime > firstRunEndTime);
|
||||||
|
|
||||||
|
exportedItems.Clear();
|
||||||
|
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||||
|
sumReceived = GetLongSum(exportedItems);
|
||||||
|
|
||||||
|
// Same for both cumulative and delta. MetricReaderTemporalityPreference.Delta implies cumulative for UpDownCounters.
|
||||||
|
Assert.Equal(10, sumReceived);
|
||||||
|
|
||||||
|
exportedItems.Clear();
|
||||||
|
counterLong.Add(40);
|
||||||
|
counterLong.Add(-20);
|
||||||
|
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||||
|
sumReceived = GetLongSum(exportedItems);
|
||||||
|
|
||||||
|
// Same for both cumulative and delta. MetricReaderTemporalityPreference.Delta implies cumulative for UpDownCounters.
|
||||||
|
Assert.Equal(30, sumReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(true)]
|
||||||
|
[InlineData(false)]
|
||||||
|
public void ObservableUpDownCounterAggregationTest(bool exportDelta)
|
||||||
|
{
|
||||||
|
var exportedItems = new List<Metric>();
|
||||||
|
|
||||||
|
using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{exportDelta}");
|
||||||
|
int i = 1;
|
||||||
|
var counterLong = meter.CreateObservableUpDownCounter(
|
||||||
|
"observable-counter",
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
return new List<Measurement<long>>()
|
||||||
|
{
|
||||||
|
new Measurement<long>(i++ * 10),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
using var meterProvider = Sdk.CreateMeterProviderBuilder()
|
||||||
|
.AddMeter(meter.Name)
|
||||||
|
.AddInMemoryExporter(exportedItems, metricReaderOptions =>
|
||||||
|
{
|
||||||
|
metricReaderOptions.TemporalityPreference = exportDelta ? MetricReaderTemporalityPreference.Delta : MetricReaderTemporalityPreference.Cumulative;
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||||
|
long sumReceived = GetLongSum(exportedItems);
|
||||||
|
Assert.Equal(10, sumReceived);
|
||||||
|
|
||||||
|
exportedItems.Clear();
|
||||||
|
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||||
|
sumReceived = GetLongSum(exportedItems);
|
||||||
|
|
||||||
|
// Same for both cumulative and delta. MetricReaderTemporalityPreference.Delta implies cumulative for UpDownCounters.
|
||||||
|
Assert.Equal(20, sumReceived);
|
||||||
|
|
||||||
|
exportedItems.Clear();
|
||||||
|
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||||
|
sumReceived = GetLongSum(exportedItems);
|
||||||
|
|
||||||
|
// Same for both cumulative and delta. MetricReaderTemporalityPreference.Delta implies cumulative for UpDownCounters.
|
||||||
|
Assert.Equal(30, sumReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(true)]
|
||||||
|
[InlineData(false)]
|
||||||
|
public void ObservableUpDownCounterWithTagsAggregationTest(bool exportDelta)
|
||||||
|
{
|
||||||
|
var exportedItems = new List<Metric>();
|
||||||
|
var tags1 = new List<KeyValuePair<string, object>>
|
||||||
|
{
|
||||||
|
new("statusCode", 200),
|
||||||
|
new("verb", "get"),
|
||||||
|
};
|
||||||
|
|
||||||
|
var tags2 = new List<KeyValuePair<string, object>>
|
||||||
|
{
|
||||||
|
new("statusCode", 200),
|
||||||
|
new("verb", "post"),
|
||||||
|
};
|
||||||
|
|
||||||
|
var tags3 = new List<KeyValuePair<string, object>>
|
||||||
|
{
|
||||||
|
new("statusCode", 500),
|
||||||
|
new("verb", "get"),
|
||||||
|
};
|
||||||
|
|
||||||
|
using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{exportDelta}");
|
||||||
|
var counterLong = meter.CreateObservableUpDownCounter(
|
||||||
|
"observable-counter",
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
return new List<Measurement<long>>()
|
||||||
|
{
|
||||||
|
new Measurement<long>(10, tags1),
|
||||||
|
new Measurement<long>(10, tags2),
|
||||||
|
new Measurement<long>(10, tags3),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
using var meterProvider = Sdk.CreateMeterProviderBuilder()
|
||||||
|
.AddMeter(meter.Name)
|
||||||
|
.AddInMemoryExporter(exportedItems, metricReaderOptions =>
|
||||||
|
{
|
||||||
|
metricReaderOptions.TemporalityPreference = exportDelta ? MetricReaderTemporalityPreference.Delta : MetricReaderTemporalityPreference.Cumulative;
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
// Export 1
|
||||||
|
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||||
|
Assert.Single(exportedItems);
|
||||||
|
var metric = exportedItems[0];
|
||||||
|
Assert.Equal("observable-counter", metric.Name);
|
||||||
|
List<MetricPoint> metricPoints = new List<MetricPoint>();
|
||||||
|
foreach (ref readonly var mp in metric.GetMetricPoints())
|
||||||
|
{
|
||||||
|
metricPoints.Add(mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Equal(3, metricPoints.Count);
|
||||||
|
|
||||||
|
var metricPoint1 = metricPoints[0];
|
||||||
|
Assert.Equal(10, metricPoint1.GetSumLong());
|
||||||
|
ValidateMetricPointTags(tags1, metricPoint1.Tags);
|
||||||
|
|
||||||
|
var metricPoint2 = metricPoints[1];
|
||||||
|
Assert.Equal(10, metricPoint2.GetSumLong());
|
||||||
|
ValidateMetricPointTags(tags2, metricPoint2.Tags);
|
||||||
|
|
||||||
|
var metricPoint3 = metricPoints[2];
|
||||||
|
Assert.Equal(10, metricPoint3.GetSumLong());
|
||||||
|
ValidateMetricPointTags(tags3, metricPoint3.Tags);
|
||||||
|
|
||||||
|
// Export 2
|
||||||
|
exportedItems.Clear();
|
||||||
|
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||||
|
Assert.Single(exportedItems);
|
||||||
|
metric = exportedItems[0];
|
||||||
|
Assert.Equal("observable-counter", metric.Name);
|
||||||
|
metricPoints.Clear();
|
||||||
|
foreach (ref readonly var mp in metric.GetMetricPoints())
|
||||||
|
{
|
||||||
|
metricPoints.Add(mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Equal(3, metricPoints.Count);
|
||||||
|
|
||||||
|
// Same for both cumulative and delta. MetricReaderTemporalityPreference.Delta implies cumulative for UpDownCounters.
|
||||||
|
metricPoint1 = metricPoints[0];
|
||||||
|
Assert.Equal(10, metricPoint1.GetSumLong());
|
||||||
|
ValidateMetricPointTags(tags1, metricPoint1.Tags);
|
||||||
|
|
||||||
|
metricPoint2 = metricPoints[1];
|
||||||
|
Assert.Equal(10, metricPoint2.GetSumLong());
|
||||||
|
ValidateMetricPointTags(tags2, metricPoint2.Tags);
|
||||||
|
|
||||||
|
metricPoint3 = metricPoints[2];
|
||||||
|
Assert.Equal(10, metricPoint3.GetSumLong());
|
||||||
|
ValidateMetricPointTags(tags3, metricPoint3.Tags);
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(true)]
|
[InlineData(true)]
|
||||||
[InlineData(false)]
|
[InlineData(false)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue