Skip to content

Commit

Permalink
[sdk-metrics] Improve exemplar tests (#5393)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeBlanch authored Feb 27, 2024
1 parent 4443223 commit e7cbbbb
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 55 deletions.
5 changes: 4 additions & 1 deletion src/OpenTelemetry/Metrics/AggregatorStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ internal sealed class AggregatorStore
internal readonly int CardinalityLimit;
internal readonly bool EmitOverflowAttribute;
internal readonly ConcurrentDictionary<Tags, LookupData>? TagsToMetricPointIndexDictionaryDelta;
internal readonly Func<ExemplarReservoir?>? ExemplarReservoirFactory;
internal long DroppedMeasurements = 0;

private static readonly string MetricPointCapHitFixMessage = "Consider opting in for the experimental SDK feature to emit all the throttled metrics under the overflow attribute by setting env variable OTEL_DOTNET_EXPERIMENTAL_METRICS_EMIT_OVERFLOW_ATTRIBUTE = true. You could also modify instrumentation to reduce the number of unique key/value pair combinations. Or use Views to drop unwanted tags. Or use MeterProviderBuilder.SetMaxMetricPointsPerMetricStream to set higher limit.";
Expand Down Expand Up @@ -59,7 +60,8 @@ internal AggregatorStore(
int cardinalityLimit,
bool emitOverflowAttribute,
bool shouldReclaimUnusedMetricPoints,
ExemplarFilter? exemplarFilter = null)
ExemplarFilter? exemplarFilter = null,
Func<ExemplarReservoir?>? exemplarReservoirFactory = null)
{
this.name = metricStreamIdentity.InstrumentName;
this.CardinalityLimit = cardinalityLimit;
Expand All @@ -74,6 +76,7 @@ internal AggregatorStore(
this.exponentialHistogramMaxScale = metricStreamIdentity.ExponentialHistogramMaxScale;
this.StartTimeExclusive = DateTimeOffset.UtcNow;
this.exemplarFilter = exemplarFilter ?? DefaultExemplarFilter;
this.ExemplarReservoirFactory = exemplarReservoirFactory;
if (metricStreamIdentity.TagKeys == null)
{
this.updateLongCallback = this.UpdateLong;
Expand Down
13 changes: 11 additions & 2 deletions src/OpenTelemetry/Metrics/Metric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ internal Metric(
int cardinalityLimit,
bool emitOverflowAttribute,
bool shouldReclaimUnusedMetricPoints,
ExemplarFilter? exemplarFilter = null)
ExemplarFilter? exemplarFilter = null,
Func<ExemplarReservoir?>? exemplarReservoirFactory = null)
{
this.InstrumentIdentity = instrumentIdentity;

Expand Down Expand Up @@ -155,7 +156,15 @@ internal Metric(
throw new NotSupportedException($"Unsupported Instrument Type: {instrumentIdentity.InstrumentType.FullName}");
}

this.AggregatorStore = new AggregatorStore(instrumentIdentity, aggType, temporality, cardinalityLimit, emitOverflowAttribute, shouldReclaimUnusedMetricPoints, exemplarFilter);
this.AggregatorStore = new AggregatorStore(
instrumentIdentity,
aggType,
temporality,
cardinalityLimit,
emitOverflowAttribute,
shouldReclaimUnusedMetricPoints,
exemplarFilter,
exemplarReservoirFactory);
this.Temporality = temporality;
}

Expand Down
18 changes: 15 additions & 3 deletions src/OpenTelemetry/Metrics/MetricPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,25 @@ internal MetricPoint(
this.ReferenceCount = 1;
this.LookupData = lookupData;

ExemplarReservoir? reservoir = null;
var isExemplarEnabled = aggregatorStore!.IsExemplarEnabled();

ExemplarReservoir? reservoir;
try
{
reservoir = aggregatorStore.ExemplarReservoirFactory?.Invoke();
}
catch
{
// TODO : Log that the factory on view threw an exception, once view exposes that capability
reservoir = null;
}

if (this.aggType == AggregationType.HistogramWithBuckets ||
this.aggType == AggregationType.HistogramWithMinMaxBuckets)
{
this.mpComponents = new MetricPointOptionalComponents();
this.mpComponents.HistogramBuckets = new HistogramBuckets(histogramExplicitBounds);
if (aggregatorStore!.IsExemplarEnabled())
if (isExemplarEnabled && reservoir == null)
{
reservoir = new AlignedHistogramBucketExemplarReservoir(histogramExplicitBounds!.Length);
}
Expand All @@ -91,7 +103,7 @@ internal MetricPoint(
this.mpComponents = null;
}

if (aggregatorStore!.IsExemplarEnabled() && reservoir == null)
if (isExemplarEnabled && reservoir == null)
{
reservoir = new SimpleFixedSizeExemplarReservoir(DefaultSimpleReservoirPoolSize);
}
Expand Down
16 changes: 8 additions & 8 deletions src/OpenTelemetry/Metrics/MetricReaderExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,14 @@ internal virtual List<Metric> AddMetricWithViews(Instrument instrument, List<Met
{
bool shouldReclaimUnusedMetricPoints = this.parentProvider is MeterProviderSdk meterProviderSdk && meterProviderSdk.ShouldReclaimUnusedMetricPoints;

var cardinalityLimit = this.cardinalityLimit;

if (metricStreamConfig != null && metricStreamConfig.CardinalityLimit != null)
{
cardinalityLimit = metricStreamConfig.CardinalityLimit.Value;
}

Metric metric = new(metricStreamIdentity, this.GetAggregationTemporality(metricStreamIdentity.InstrumentType), cardinalityLimit, this.emitOverflowAttribute, shouldReclaimUnusedMetricPoints, this.exemplarFilter);
Metric metric = new(
metricStreamIdentity,
this.GetAggregationTemporality(metricStreamIdentity.InstrumentType),
metricStreamConfig?.CardinalityLimit ?? this.cardinalityLimit,
this.emitOverflowAttribute,
shouldReclaimUnusedMetricPoints,
this.exemplarFilter,
metricStreamConfig?.ExemplarReservoirFactory);

this.instrumentIdentityToMetric[metricStreamIdentity] = metric;
this.metrics![index] = metric;
Expand Down
4 changes: 4 additions & 0 deletions src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ public string[]? TagKeys
}
}

// TODO: Expose this to be complaint with the spec:
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#stream-configuration
internal Func<ExemplarReservoir?>? ExemplarReservoirFactory { get; set; }

internal string[]? CopiedTagKeys { get; private set; }

internal int? ViewId { get; set; }
Expand Down
Loading

0 comments on commit e7cbbbb

Please sign in to comment.