From 8cd00cca14f87c1be03786754ec4143ae5f33cf7 Mon Sep 17 00:00:00 2001 From: Martin Tomka Date: Tue, 4 Jul 2023 10:30:26 +0200 Subject: [PATCH] Introduce `TelemetryOptions.OnTelemetryEvent` --- .../Telemetry/ResilienceTelemetrySource.cs | 3 --- .../Telemetry/TelemetryEventArguments.cs | 3 --- .../ResilienceTelemetryDiagnosticSource.cs | 4 ++++ .../Telemetry/TelemetryOptions.cs | 9 ++++++++ ...esilienceTelemetryDiagnosticSourceTests.cs | 22 ++++++++++++++++++- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/Polly.Core/Telemetry/ResilienceTelemetrySource.cs b/src/Polly.Core/Telemetry/ResilienceTelemetrySource.cs index f0139da3e32..0a2fbda10eb 100644 --- a/src/Polly.Core/Telemetry/ResilienceTelemetrySource.cs +++ b/src/Polly.Core/Telemetry/ResilienceTelemetrySource.cs @@ -1,5 +1,3 @@ -using System.ComponentModel; - namespace Polly.Telemetry; /// @@ -12,7 +10,6 @@ namespace Polly.Telemetry; /// /// This class is used by the telemetry infrastructure and should not be used directly by user code. /// -[EditorBrowsable(EditorBrowsableState.Never)] public sealed record class ResilienceTelemetrySource( string? BuilderName, ResilienceProperties BuilderProperties, diff --git a/src/Polly.Core/Telemetry/TelemetryEventArguments.cs b/src/Polly.Core/Telemetry/TelemetryEventArguments.cs index d3c66c51aae..f8c592dd7ed 100644 --- a/src/Polly.Core/Telemetry/TelemetryEventArguments.cs +++ b/src/Polly.Core/Telemetry/TelemetryEventArguments.cs @@ -1,11 +1,8 @@ -using System.ComponentModel; - namespace Polly.Telemetry; /// /// The arguments of the telemetry event. /// -[EditorBrowsable(EditorBrowsableState.Never)] public sealed partial record class TelemetryEventArguments { private TelemetryEventArguments() diff --git a/src/Polly.Extensions/Telemetry/ResilienceTelemetryDiagnosticSource.cs b/src/Polly.Extensions/Telemetry/ResilienceTelemetryDiagnosticSource.cs index 630227d6dd6..fa7de3d0910 100644 --- a/src/Polly.Extensions/Telemetry/ResilienceTelemetryDiagnosticSource.cs +++ b/src/Polly.Extensions/Telemetry/ResilienceTelemetryDiagnosticSource.cs @@ -10,6 +10,7 @@ internal class ResilienceTelemetryDiagnosticSource : DiagnosticSource private readonly ILogger _logger; private readonly Func _resultFormatter; + private readonly Action? _onEvent; private readonly List> _enrichers; public ResilienceTelemetryDiagnosticSource(TelemetryOptions options) @@ -17,6 +18,7 @@ public ResilienceTelemetryDiagnosticSource(TelemetryOptions options) _enrichers = options.Enrichers.ToList(); _logger = options.LoggerFactory.CreateLogger(TelemetryUtil.PollyDiagnosticSource); _resultFormatter = options.ResultFormatter; + _onEvent = options.OnTelemetryEvent; Counter = Meter.CreateCounter( "resilience-events", @@ -41,6 +43,8 @@ public override void Write(string name, object? value) return; } + _onEvent?.Invoke(args); + LogEvent(args); MeterEvent(args); } diff --git a/src/Polly.Extensions/Telemetry/TelemetryOptions.cs b/src/Polly.Extensions/Telemetry/TelemetryOptions.cs index 3b23c354be9..a44c2abb08f 100644 --- a/src/Polly.Extensions/Telemetry/TelemetryOptions.cs +++ b/src/Polly.Extensions/Telemetry/TelemetryOptions.cs @@ -2,6 +2,7 @@ using System.Net.Http; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Polly.Telemetry; namespace Polly.Extensions.Telemetry; @@ -10,6 +11,14 @@ namespace Polly.Extensions.Telemetry; /// public class TelemetryOptions { + /// + /// Gets or sets the callback that is raised when is received from Polly. + /// + /// + /// Defaults to . + /// + public Action? OnTelemetryEvent { get; set; } + /// /// Gets or sets the logger factory. /// diff --git a/test/Polly.Extensions.Tests/Telemetry/ResilienceTelemetryDiagnosticSourceTests.cs b/test/Polly.Extensions.Tests/Telemetry/ResilienceTelemetryDiagnosticSourceTests.cs index e181d708f68..555d12d47e3 100644 --- a/test/Polly.Extensions.Tests/Telemetry/ResilienceTelemetryDiagnosticSourceTests.cs +++ b/test/Polly.Extensions.Tests/Telemetry/ResilienceTelemetryDiagnosticSourceTests.cs @@ -14,6 +14,7 @@ public class ResilienceTelemetryDiagnosticSourceTests : IDisposable private readonly ILoggerFactory _loggerFactory; private readonly List _events = new(); private readonly IDisposable _metering; + private Action? _onEvent; public ResilienceTelemetryDiagnosticSourceTests() { @@ -319,13 +320,32 @@ public void WriteEvent_MeteringWithoutStrategyKey_Ok() var events = GetEvents("resilience-events")[0]["strategy-key"].Should().BeNull(); } + [InlineData(true)] + [InlineData(false)] + [Theory] + public void OnTelemetryEvent_Ok(bool hasCallback) + { + var called = false; + + if (hasCallback) + { + _onEvent = e => called = true; + } + + var telemetry = Create(); + ReportEvent(telemetry, null, strategyKey: null); + + called.Should().Be(hasCallback); + } + private List> GetEvents(string eventName) => _events.Where(e => e.Name == eventName).Select(v => v.Tags).ToList(); private ResilienceTelemetryDiagnosticSource Create(Action>>? configureEnrichers = null) { var options = new TelemetryOptions { - LoggerFactory = _loggerFactory + LoggerFactory = _loggerFactory, + OnTelemetryEvent = _onEvent }; configureEnrichers?.Invoke(options.Enrichers);