Skip to content

Commit

Permalink
[sdk-metrics] Expose ExemplarReservoir and support configuration via …
Browse files Browse the repository at this point in the history
…views (#5542)
  • Loading branch information
CodeBlanch authored Apr 17, 2024
1 parent bf423cc commit 89aa7a4
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
abstract OpenTelemetry.Metrics.ExemplarReservoir.Collect() -> OpenTelemetry.Metrics.ReadOnlyExemplarCollection
abstract OpenTelemetry.Metrics.ExemplarReservoir.Offer(in OpenTelemetry.Metrics.ExemplarMeasurement<double> measurement) -> void
abstract OpenTelemetry.Metrics.ExemplarReservoir.Offer(in OpenTelemetry.Metrics.ExemplarMeasurement<long> measurement) -> void
OpenTelemetry.Logs.LoggerProviderBuilderExtensions
OpenTelemetry.Logs.LoggerProviderExtensions
OpenTelemetry.Logs.LogRecord.Logger.get -> OpenTelemetry.Logs.Logger!
Expand All @@ -21,9 +24,14 @@ OpenTelemetry.Metrics.ExemplarMeasurement<T>
OpenTelemetry.Metrics.ExemplarMeasurement<T>.ExemplarMeasurement() -> void
OpenTelemetry.Metrics.ExemplarMeasurement<T>.Tags.get -> System.ReadOnlySpan<System.Collections.Generic.KeyValuePair<string!, object?>>
OpenTelemetry.Metrics.ExemplarMeasurement<T>.Value.get -> T
OpenTelemetry.Metrics.ExemplarReservoir
OpenTelemetry.Metrics.ExemplarReservoir.ExemplarReservoir() -> void
OpenTelemetry.Metrics.ExemplarReservoir.ResetOnCollect.get -> bool
OpenTelemetry.Metrics.MetricPoint.TryGetExemplars(out OpenTelemetry.Metrics.ReadOnlyExemplarCollection exemplars) -> bool
OpenTelemetry.Metrics.MetricStreamConfiguration.CardinalityLimit.get -> int?
OpenTelemetry.Metrics.MetricStreamConfiguration.CardinalityLimit.set -> void
OpenTelemetry.Metrics.MetricStreamConfiguration.ExemplarReservoirFactory.get -> System.Func<OpenTelemetry.Metrics.ExemplarReservoir?>?
OpenTelemetry.Metrics.MetricStreamConfiguration.ExemplarReservoirFactory.set -> void
OpenTelemetry.Metrics.ReadOnlyExemplarCollection
OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator
OpenTelemetry.Metrics.ReadOnlyExemplarCollection.Enumerator.Current.get -> OpenTelemetry.Metrics.Exemplar
Expand Down
5 changes: 5 additions & 0 deletions src/OpenTelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
during configuration reload.
([#5514](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5514))

* **Experimental (pre-release builds only):** Exposed `ExemplarReservoir` as a
public API and added support for setting an `ExemplarReservoir` factory
function when configuring a view (applies to individual metrics).
([#5542](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5542))

## 1.8.0

Released 2024-Apr-02
Expand Down
15 changes: 15 additions & 0 deletions src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ public void LoggerProcessStateSkipped<TState>()
}
}

[NonEvent]
public void MetricViewException(string source, Exception ex)
{
if (this.IsEnabled(EventLevel.Error, EventKeywords.All))
{
this.MetricViewException(source, ex.ToInvariantString());
}
}

[Event(4, Message = "Unknown error in SpanProcessor event '{0}': '{1}'.", Level = EventLevel.Error)]
public void SpanProcessorException(string evnt, string ex)
{
Expand Down Expand Up @@ -359,6 +368,12 @@ public void TracesSamplerArgConfigInvalid(string configValue)
this.WriteEvent(55, configValue);
}

[Event(56, Message = "Exception thrown by user code supplied on metric view ('{0}'): '{1}'.", Level = EventLevel.Error)]
public void MetricViewException(string source, string ex)
{
this.WriteEvent(56, source, ex);
}

void IConfigurationExtensionsLogger.LogInvalidConfigurationValue(string key, string value)
{
this.InvalidConfigurationValue(key, value);
Expand Down
16 changes: 15 additions & 1 deletion src/OpenTelemetry/Metrics/Exemplar/ExemplarReservoir.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#if EXPOSE_EXPERIMENTAL_FEATURES && NET8_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
using OpenTelemetry.Internal;
#endif

namespace OpenTelemetry.Metrics;

#if EXPOSE_EXPERIMENTAL_FEATURES
/// <summary>
/// ExemplarReservoir base implementation and contract.
/// </summary>
/// <remarks>
/// <remarks><inheritdoc cref="Exemplar" path="/remarks/para[@experimental-warning='true']"/></remarks>
/// Specification: <see
/// href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplarreservoir"/>.
/// </remarks>
internal abstract class ExemplarReservoir
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.ExemplarExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public
#else
internal
#endif
abstract class ExemplarReservoir
{
/// <summary>
/// Gets a value indicating whether or not the <see
Expand Down
8 changes: 5 additions & 3 deletions src/OpenTelemetry/Metrics/MetricPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ internal MetricPoint(
ExemplarReservoir? reservoir;
try
{
reservoir = aggregatorStore.ExemplarReservoirFactory?.Invoke();
reservoir = isExemplarEnabled
? aggregatorStore.ExemplarReservoirFactory?.Invoke()
: null;
}
catch
catch (Exception ex)
{
// TODO : Log that the factory on view threw an exception, once view exposes that capability
OpenTelemetrySdkEventSource.Log.MetricViewException("ExemplarReservoirFactory", ex);
reservoir = null;
}

Expand Down
22 changes: 20 additions & 2 deletions src/OpenTelemetry/Metrics/MetricStreamConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,27 @@ 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
#if EXPOSE_EXPERIMENTAL_FEATURES
/// <summary>
/// Gets or sets a factory function used to generate an <see
/// cref="ExemplarReservoir"/> for the metric managed by the view to use
/// when storing <see cref="Exemplar"/>s.
/// </summary>
/// <remarks>
/// <remarks><inheritdoc cref="Exemplar" path="/remarks/para[@experimental-warning='true']"/></remarks>
/// <para>Note: Returning <see langword="null"/> from the factory function will
/// result in the default <see cref="ExemplarReservoir"/> being chosen by
/// the SDK based on the type of metric.</para>
/// Specification: <see
/// href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#stream-configuration"/>.
/// </remarks>
#if NET8_0_OR_GREATER
[Experimental(DiagnosticDefinitions.ExemplarExperimentalApi, UrlFormat = DiagnosticDefinitions.ExperimentalApiUrlFormat)]
#endif
public Func<ExemplarReservoir?>? ExemplarReservoirFactory { get; set; }
#else
internal Func<ExemplarReservoir?>? ExemplarReservoirFactory { get; set; }
#endif

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

Expand Down

0 comments on commit 89aa7a4

Please sign in to comment.