diff --git a/src/Polly.Core/PublicAPI.Unshipped.txt b/src/Polly.Core/PublicAPI.Unshipped.txt index 3c0a29a56b2..616816d64f1 100644 --- a/src/Polly.Core/PublicAPI.Unshipped.txt +++ b/src/Polly.Core/PublicAPI.Unshipped.txt @@ -9,8 +9,6 @@ abstract Polly.Telemetry.TelemetryListener.Write(in Polly.Teleme override Polly.Outcome.ToString() -> string! override Polly.Registry.ResiliencePipelineRegistry.TryGetPipeline(TKey key, out Polly.ResiliencePipeline? pipeline) -> bool override Polly.Registry.ResiliencePipelineRegistry.TryGetPipeline(TKey key, out Polly.ResiliencePipeline? pipeline) -> bool -override Polly.ResiliencePropertyKey.Equals(object? obj) -> bool -override Polly.ResiliencePropertyKey.GetHashCode() -> int override Polly.ResiliencePropertyKey.ToString() -> string! override Polly.Telemetry.ResilienceEvent.ToString() -> string! Polly.CircuitBreaker.BrokenCircuitException @@ -166,8 +164,6 @@ Polly.PredicateBuilder.HandleResult(TResult result, System.Collections. Polly.PredicateBuilder.PredicateBuilder() -> void Polly.PredicateResult Polly.Registry.ConfigureBuilderContext -Polly.Registry.ConfigureBuilderContext.BuilderInstanceName.get -> string? -Polly.Registry.ConfigureBuilderContext.BuilderName.get -> string! Polly.Registry.ConfigureBuilderContext.EnableReloads(System.Func!>! tokenProducerFactory) -> void Polly.Registry.ConfigureBuilderContext.PipelineKey.get -> TKey Polly.Registry.ResiliencePipelineProvider @@ -206,11 +202,9 @@ Polly.ResilienceContext.CancellationToken.get -> System.Threading.CancellationTo Polly.ResilienceContext.ContinueOnCapturedContext.get -> bool Polly.ResilienceContext.ContinueOnCapturedContext.set -> void Polly.ResilienceContext.IsSynchronous.get -> bool -Polly.ResilienceContext.IsVoid.get -> bool Polly.ResilienceContext.OperationKey.get -> string? Polly.ResilienceContext.Properties.get -> Polly.ResilienceProperties! Polly.ResilienceContext.ResilienceEvents.get -> System.Collections.Generic.IReadOnlyList! -Polly.ResilienceContext.ResultType.get -> System.Type! Polly.ResilienceContextPool Polly.ResilienceContextPool.Get(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Polly.ResilienceContext! Polly.ResilienceContextPool.ResilienceContextPool() -> void @@ -268,7 +262,6 @@ Polly.ResilienceProperties.ResilienceProperties() -> void Polly.ResilienceProperties.Set(Polly.ResiliencePropertyKey key, TValue value) -> void Polly.ResilienceProperties.TryGetValue(Polly.ResiliencePropertyKey key, out TValue value) -> bool Polly.ResiliencePropertyKey -Polly.ResiliencePropertyKey.Equals(Polly.ResiliencePropertyKey other) -> bool Polly.ResiliencePropertyKey.Key.get -> string! Polly.ResiliencePropertyKey.ResiliencePropertyKey() -> void Polly.ResiliencePropertyKey.ResiliencePropertyKey(string! key) -> void @@ -321,9 +314,6 @@ Polly.Retry.RetryStrategyOptions.UseJitter.get -> bool Polly.Retry.RetryStrategyOptions.UseJitter.set -> void Polly.RetryResiliencePipelineBuilderExtensions Polly.StrategyBuilderContext -Polly.StrategyBuilderContext.BuilderInstanceName.get -> string? -Polly.StrategyBuilderContext.BuilderName.get -> string? -Polly.StrategyBuilderContext.StrategyName.get -> string? Polly.StrategyBuilderContext.Telemetry.get -> Polly.Telemetry.ResilienceStrategyTelemetry! Polly.Telemetry.ExecutionAttemptArguments Polly.Telemetry.ExecutionAttemptArguments.AttemptNumber.get -> int @@ -414,8 +404,6 @@ static Polly.ResiliencePipelineBuilderExtensions.AddPipeline(this Polly static Polly.ResiliencePipelineBuilderExtensions.AddStrategy(this Polly.ResiliencePipelineBuilder! builder, System.Func!>! factory, Polly.ResilienceStrategyOptions! options) -> Polly.ResiliencePipelineBuilder! static Polly.ResiliencePipelineBuilderExtensions.AddStrategy(this TBuilder! builder, System.Func! factory, Polly.ResilienceStrategyOptions! options) -> TBuilder! static Polly.ResiliencePipelineBuilderExtensions.AddStrategy(this Polly.ResiliencePipelineBuilder! builder, System.Func!>! factory, Polly.ResilienceStrategyOptions! options) -> Polly.ResiliencePipelineBuilder! -static Polly.ResiliencePropertyKey.operator !=(Polly.ResiliencePropertyKey left, Polly.ResiliencePropertyKey right) -> bool -static Polly.ResiliencePropertyKey.operator ==(Polly.ResiliencePropertyKey left, Polly.ResiliencePropertyKey right) -> bool static Polly.RetryResiliencePipelineBuilderExtensions.AddRetry(this Polly.ResiliencePipelineBuilder! builder, Polly.Retry.RetryStrategyOptions! options) -> Polly.ResiliencePipelineBuilder! static Polly.RetryResiliencePipelineBuilderExtensions.AddRetry(this Polly.ResiliencePipelineBuilder! builder, Polly.Retry.RetryStrategyOptions! options) -> Polly.ResiliencePipelineBuilder! static Polly.TimeoutResiliencePipelineBuilderExtensions.AddTimeout(this TBuilder! builder, Polly.Timeout.TimeoutStrategyOptions! options) -> TBuilder! diff --git a/src/Polly.Core/README.md b/src/Polly.Core/README.md index 1b8400d2ceb..867d5e2f828 100644 --- a/src/Polly.Core/README.md +++ b/src/Polly.Core/README.md @@ -156,7 +156,7 @@ Pipeline with a single strategy: var ResiliencePipeline = new ResiliencePipelineBuilder().AddRetry(new()).Build(); ``` -Pipeline wiht multiple strategies: +Pipeline with multiple strategies: ``` csharp var ResiliencePipeline = new ResiliencePipelineBuilder() @@ -257,7 +257,7 @@ When setting the delegates, ensure to respect the `ResilienceContext.IsSynchrono ## Telemetry -Each individual resilience strategy can emit telemetry by using the [`ResiliencePipelineTelemetry`](Telemetry/ResiliencePipelineTelemetry.cs) API. Polly wraps the arguments as [`TelemetryEventArguments`](Telemetry/TelemetryEventArguments.cs) and emits them using `DiagnosticSource`. -To consume the telemetry, Polly adopters needs to assign an instance of `DiagnosticSource` to `ResiliencePipelineBuilder.DiagnosticSource` and consume `TelemetryEventArguments`. +Each individual resilience strategy can emit telemetry by using the [`ResiliencePipelineTelemetry`](Telemetry/ResiliencePipelineTelemetry.cs) API. Polly wraps the arguments as [`TelemetryEventArguments`](Telemetry/TelemetryEventArguments.cs) and emits them using `TelemetryListener`. +To consume the telemetry, Polly adopters needs to assign an instance of `TelemetryListener` to `ResiliencePipelineBuilder.DiagnosticSource` and consume `TelemetryEventArguments`. For common use-cases, it is anticipated that Polly users would leverage `Polly.Extensions`. This allows all of the aforementioned functionalities by invoking the `ResiliencePipelineBuilder.ConfigureTelemetry(...)` extension method. `ConfigureTelemetry` processes `TelemetryEventArguments` and generates logs and metrics from it. diff --git a/src/Polly.Core/Registry/ConfigureBuilderContext.cs b/src/Polly.Core/Registry/ConfigureBuilderContext.cs index 323e65d0816..6084c2e2160 100644 --- a/src/Polly.Core/Registry/ConfigureBuilderContext.cs +++ b/src/Polly.Core/Registry/ConfigureBuilderContext.cs @@ -24,12 +24,12 @@ internal ConfigureBuilderContext(TKey strategyKey, string builderName, string? b /// /// Gets the builder name for the builder being used to create the strategy. /// - public string BuilderName { get; } + internal string BuilderName { get; } /// /// Gets the instance name for the builder being used to create the strategy. /// - public string? BuilderInstanceName { get; } + internal string? BuilderInstanceName { get; } internal Func>? ReloadTokenProducer { get; private set; } @@ -39,7 +39,7 @@ internal ConfigureBuilderContext(TKey strategyKey, string builderName, string? b /// The producer of that is triggered when change occurs. /// /// The should always return function that returns a new instance when invoked otherwise - /// the reload infrastructure will stop listening for changes. The is called only once for each streategy. + /// the reload infrastructure will stop listening for changes. The is called only once for each strategy. /// [EditorBrowsable(EditorBrowsableState.Never)] public void EnableReloads(Func> tokenProducerFactory) diff --git a/src/Polly.Core/Registry/ResiliencePipelineRegistry.cs b/src/Polly.Core/Registry/ResiliencePipelineRegistry.cs index 09da82441be..3512dcb6765 100644 --- a/src/Polly.Core/Registry/ResiliencePipelineRegistry.cs +++ b/src/Polly.Core/Registry/ResiliencePipelineRegistry.cs @@ -282,22 +282,16 @@ private static ResiliencePipeline CreatePipeline( var builder = factory(); var pipeline = builder.BuildPipeline(); - var diagnosticSource = builder.TelemetryListener; + var telemetry = new ResilienceStrategyTelemetry( + new ResilienceTelemetrySource(context.BuilderName, context.BuilderInstanceName, null), + builder.TelemetryListener); if (context.ReloadTokenProducer is null) { return pipeline; } - return new ReloadableResiliencePipeline( - pipeline, - context.ReloadTokenProducer(), - () => factory().BuildPipeline(), - TelemetryUtil.CreateTelemetry( - diagnosticSource, - context.BuilderName, - context.BuilderInstanceName, - null)); + return new ReloadableResiliencePipeline(pipeline, context.ReloadTokenProducer(), () => factory().BuildPipeline(), telemetry); } private GenericRegistry GetGenericRegistry() diff --git a/src/Polly.Core/Registry/ResiliencePipelineRegistryOptions.cs b/src/Polly.Core/Registry/ResiliencePipelineRegistryOptions.cs index 1f54f2a08c8..2d08bc7e725 100644 --- a/src/Polly.Core/Registry/ResiliencePipelineRegistryOptions.cs +++ b/src/Polly.Core/Registry/ResiliencePipelineRegistryOptions.cs @@ -54,7 +54,7 @@ public class ResiliencePipelineRegistryOptions /// /// /// Use custom formatter for composite keys in case you want to have different metric values for a builder and strategy key. - /// In general, pipelines can have the same builder name and different pippeline keys. + /// In general, pipelines can have the same builder name and different pipeline keys. /// /// /// The default value is a formatter that formats the keys using the method. diff --git a/src/Polly.Core/ResilienceContext.cs b/src/Polly.Core/ResilienceContext.cs index 49acc2aea86..ac7ca5473ce 100644 --- a/src/Polly.Core/ResilienceContext.cs +++ b/src/Polly.Core/ResilienceContext.cs @@ -46,12 +46,12 @@ internal ResilienceContext() /// /// Gets the type of the result associated with the execution. /// - public Type ResultType { get; private set; } = typeof(UnknownResult); + internal Type ResultType { get; private set; } = typeof(UnknownResult); /// /// Gets a value indicating whether the execution represents a void result. /// - public bool IsVoid => ResultType == typeof(VoidResult); + internal bool IsVoid => ResultType == typeof(VoidResult); /// /// Gets or sets a value indicating whether the execution should continue on the captured context. diff --git a/src/Polly.Core/ResiliencePipelineBuilderBase.cs b/src/Polly.Core/ResiliencePipelineBuilderBase.cs index 125bc138fb3..7267b891c8f 100644 --- a/src/Polly.Core/ResiliencePipelineBuilderBase.cs +++ b/src/Polly.Core/ResiliencePipelineBuilderBase.cs @@ -116,20 +116,18 @@ internal ResiliencePipeline BuildPipeline() return NullResiliencePipeline.Instance; } + var source = new ResilienceTelemetrySource(Name, InstanceName, null); + return CompositeResiliencePipeline.Create( strategies, - TelemetryUtil.CreateTelemetry(TelemetryListener, Name, InstanceName, null), + new ResilienceStrategyTelemetry(source, TelemetryListener), TimeProvider); } private ResiliencePipeline CreateResiliencePipeline(Entry entry) { - var context = new StrategyBuilderContext( - builderName: Name, - builderInstanceName: InstanceName, - strategyName: entry.Options.Name, - timeProvider: TimeProvider, - telemetryListener: TelemetryListener); + var source = new ResilienceTelemetrySource(Name, InstanceName, entry.Options.Name); + var context = new StrategyBuilderContext(new ResilienceStrategyTelemetry(source, TelemetryListener), TimeProvider); var strategy = entry.Factory(context); strategy.Options = entry.Options; diff --git a/src/Polly.Core/ResiliencePropertyKey.cs b/src/Polly.Core/ResiliencePropertyKey.cs index b01f2f05822..223671239f4 100644 --- a/src/Polly.Core/ResiliencePropertyKey.cs +++ b/src/Polly.Core/ResiliencePropertyKey.cs @@ -1,10 +1,12 @@ namespace Polly; +#pragma warning disable CA1815 // Override equals and operator equals on value types + /// /// Represents a key used by . /// /// The type of the value of the property. -public readonly struct ResiliencePropertyKey : IEquatable> +public readonly struct ResiliencePropertyKey { /// /// Initializes a new instance of the struct. @@ -24,30 +26,5 @@ public ResiliencePropertyKey(string key) /// public override string ToString() => Key; - - /// /// - public override bool Equals(object? obj) => obj is ResiliencePropertyKey other && Equals(other); - - /// - public bool Equals(ResiliencePropertyKey other) => StringComparer.Ordinal.Equals(Key, other.Key); - - /// - public override int GetHashCode() => (StringComparer.Ordinal.GetHashCode(Key), typeof(TValue)).GetHashCode(); - - /// - /// The operator to compare two instances of for equality. - /// - /// The left instance. - /// The right instance. - /// True if the instances are equal, false otherwise. - public static bool operator ==(ResiliencePropertyKey left, ResiliencePropertyKey right) => left.Equals(right); - - /// - /// The operator to compare two instances of for inequality. - /// - /// The left instance. - /// The right instance. - /// True if the instances are not equal, false otherwise. - public static bool operator !=(ResiliencePropertyKey left, ResiliencePropertyKey right) => !(left == right); } diff --git a/src/Polly.Core/StrategyBuilderContext.cs b/src/Polly.Core/StrategyBuilderContext.cs index 413aa700a6f..db1b3686088 100644 --- a/src/Polly.Core/StrategyBuilderContext.cs +++ b/src/Polly.Core/StrategyBuilderContext.cs @@ -7,35 +7,12 @@ namespace Polly; /// public sealed class StrategyBuilderContext { - internal StrategyBuilderContext( - string? builderName, - string? builderInstanceName, - string? strategyName, - TimeProvider timeProvider, - TelemetryListener? telemetryListener) + internal StrategyBuilderContext(ResilienceStrategyTelemetry telemetry, TimeProvider timeProvider) { - BuilderName = builderName; - BuilderInstanceName = builderInstanceName; - StrategyName = strategyName; TimeProvider = timeProvider; - Telemetry = TelemetryUtil.CreateTelemetry(telemetryListener, builderName, builderInstanceName, strategyName); + Telemetry = telemetry; } - /// - /// Gets the name of the builder. - /// - public string? BuilderName { get; } - - /// - /// Gets the instance name of the builder. - /// - public string? BuilderInstanceName { get; } - - /// - /// Gets the name of the strategy. - /// - public string? StrategyName { get; } - /// /// Gets the resilience telemetry used to report important events. /// diff --git a/src/Polly.Core/Telemetry/TelemetryUtil.cs b/src/Polly.Core/Telemetry/TelemetryUtil.cs index 3e3985ba63f..b3ffe8d4486 100644 --- a/src/Polly.Core/Telemetry/TelemetryUtil.cs +++ b/src/Polly.Core/Telemetry/TelemetryUtil.cs @@ -10,17 +10,6 @@ internal static class TelemetryUtil internal const string PipelineExecuted = "PipelineExecuted"; - public static ResilienceStrategyTelemetry CreateTelemetry( - TelemetryListener? listener, - string? builderName, - string? builderInstanceName, - string? strategyName) - { - var telemetrySource = new ResilienceTelemetrySource(builderName, builderInstanceName, strategyName); - - return new ResilienceStrategyTelemetry(telemetrySource, listener); - } - public static void ReportExecutionAttempt( ResilienceStrategyTelemetry telemetry, ResilienceContext context, diff --git a/src/Polly.Extensions/DependencyInjection/AddResiliencePipelineContext.cs b/src/Polly.Extensions/DependencyInjection/AddResiliencePipelineContext.cs index 0fe9503a487..f2fd5f4c480 100644 --- a/src/Polly.Extensions/DependencyInjection/AddResiliencePipelineContext.cs +++ b/src/Polly.Extensions/DependencyInjection/AddResiliencePipelineContext.cs @@ -16,19 +16,12 @@ internal AddResiliencePipelineContext(ConfigureBuilderContext registryCont { RegistryContext = registryContext; ServiceProvider = serviceProvider; - PipelineKey = registryContext.PipelineKey; - BuilderName = registryContext.BuilderName; } /// - /// Gets the strategy key for the strategy being created. + /// Gets the pipeline key for the pipeline being created. /// - public string BuilderName { get; } - - /// - /// Gets the strategy key for the strategy being created. - /// - public TKey PipelineKey { get; } + public TKey PipelineKey => RegistryContext.PipelineKey; /// /// Gets the that provides access to the dependency injection container. diff --git a/src/Polly.Extensions/PublicAPI.Unshipped.txt b/src/Polly.Extensions/PublicAPI.Unshipped.txt index 506c18d29dd..f33a3debed8 100644 --- a/src/Polly.Extensions/PublicAPI.Unshipped.txt +++ b/src/Polly.Extensions/PublicAPI.Unshipped.txt @@ -1,7 +1,6 @@ #nullable enable abstract Polly.Telemetry.MeteringEnricher.Enrich(in Polly.Telemetry.EnrichmentContext context) -> void Polly.DependencyInjection.AddResiliencePipelineContext -Polly.DependencyInjection.AddResiliencePipelineContext.BuilderName.get -> string! Polly.DependencyInjection.AddResiliencePipelineContext.EnableReloads(string? name = null) -> void Polly.DependencyInjection.AddResiliencePipelineContext.GetOptions(string? name = null) -> TOptions Polly.DependencyInjection.AddResiliencePipelineContext.PipelineKey.get -> TKey diff --git a/src/Polly.Extensions/README.md b/src/Polly.Extensions/README.md index 7e587f9d07f..82355384a7e 100644 --- a/src/Polly.Extensions/README.md +++ b/src/Polly.Extensions/README.md @@ -94,7 +94,6 @@ Dimensions: |`pipeline-instance`| The instance name of the pipeline corresponding to the resilience pipeline.| |`strategy-name`| The name of the strategy generating this event.| |`operation-key`| The operation key associated with the call site. | -|`result-type`| The result type (`string`, `HttpResponseMessage`). | |`exception-name`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). | #### execution-attempt-duration @@ -113,7 +112,6 @@ Dimensions: |`pipeline-instance`| The instance name of the pipeline corresponding to the resilience pipeline.| |`strategy-name`| The name of the strategy generating this event.| |`operation-key`| The operation key associated with the call site. | -|`result-type`| The result type (`string`, `HttpResponseMessage`). | |`exception-name`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). | |`attempt-number`| The execution attempt number, starting at 0 (0, 1, 2). | |`attempt-handled`| Indicates if the execution outcome was handled. A handled outcome indicates execution failure and the need for retry (`true`, `false`). | @@ -131,7 +129,6 @@ Dimensions: |`pipeline-name`| The name of the pipeline corresponding to the resilience pipeline.| |`pipeline-instance`| The instance name of the pipeline corresponding to the resilience pipeline.| |`operation-key`| The operation key associated with the call site. | -|`result-type`| The result type (`string`, `HttpResponseMessage`). | |`exception-name`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). | |`execution-health`| Indicates whether the execution was healthy or not (`Healthy`, `Unhealthy`). | @@ -141,14 +138,14 @@ Logs are registered under the `Polly` logger name. Here are some examples of the ``` text // This log is recorded whenever a resilience event occurs. EventId = 0 -Resilience event occurred. EventName: '{EventName}', Source: '{BuilderName}[{BuilderInstance}]/{StrategyType}[{StrategyName}]', Operation Key: '{OperationKey}', Result: '{Result}' +Resilience event occurred. EventName: '{EventName}', Source: '{PipelineName}/{PipelineInstance}/{StrategyName}', Operation Key: '{OperationKey}', Result: '{Result}' // This log is recorded when a resilience pipeline begins executing. EventId = 1 -Resilience pipeline executing. Source: '{BuilderName}[{BuilderInstance}]', Operation Key: '{OperationKey}', Result Type: '{ResultType}' +Resilience pipeline executing. Source: '{PipelineName}/{PipelineInstance}', Operation Key: '{OperationKey}' // This log is recorded when a resilience pipeline finishes execution. EventId = 2 -Resilience pipeline executed. Source: '{BuilderName}[{BuilderInstance}]', Operation Key: '{OperationKey}', Result Type: '{ResultType}', Result: '{Result}', Execution Health: '{ExecutionHealth}', Execution Time: {ExecutionTime}ms +Resilience pipeline executed. Source: '{PipelineName}/{PipelineInstance}', Operation Key: '{OperationKey}', Result: '{Result}', Execution Health: '{ExecutionHealth}', Execution Time: {ExecutionTime}ms // This log is recorded upon the completion of every execution attempt. EventId = 3 -Execution attempt. Source: '{BuilderName}[{BuilderInstance}]/{StrategyType}[{StrategyName}]', Operation Key: '{OperationKey}', Result: '{Result}', Handled: '{Handled}', Attempt: '{Attempt}', Execution Time: '{ExecutionTimeMs}' +Execution attempt. Source: '{PipelineName}/{PipelineInstance}/{StrategyName}', Operation Key: '{OperationKey}', Result: '{Result}', Handled: '{Handled}', Attempt: '{Attempt}', Execution Time: '{ExecutionTimeMs}' ``` diff --git a/src/Polly.Extensions/Telemetry/Log.cs b/src/Polly.Extensions/Telemetry/Log.cs index a81a951f127..1d2805c9849 100644 --- a/src/Polly.Extensions/Telemetry/Log.cs +++ b/src/Polly.Extensions/Telemetry/Log.cs @@ -32,22 +32,19 @@ public static partial void ResilienceEvent( LogLevel.Debug, "Resilience pipeline executing. " + "Source: '{PipelineName}/{PipelineInstance}', " + - "Operation Key: '{OperationKey}', " + - "Result Type: '{ResultType}'", + "Operation Key: '{OperationKey}'", EventName = "StrategyExecuting")] public static partial void PipelineExecuting( this ILogger logger, string pipelineName, string pipelineInstance, - string? operationKey, - string resultType); + string? operationKey); [LoggerMessage( EventId = 2, Message = "Resilience pipeline executed. " + "Source: '{PipelineName}/{PipelineInstance}', " + "Operation Key: '{OperationKey}', " + - "Result Type: '{ResultType}', " + "Result: '{Result}', " + "Execution Health: '{ExecutionHealth}', " + "Execution Time: {ExecutionTime}ms", @@ -58,7 +55,6 @@ public static partial void PipelineExecuted( string pipelineName, string pipelineInstance, string? operationKey, - string resultType, object? result, string executionHealth, double executionTime, diff --git a/src/Polly.Extensions/Telemetry/ResilienceContextExtensions.cs b/src/Polly.Extensions/Telemetry/ResilienceContextExtensions.cs index 3ffc0286a4e..60fc606efd2 100644 --- a/src/Polly.Extensions/Telemetry/ResilienceContextExtensions.cs +++ b/src/Polly.Extensions/Telemetry/ResilienceContextExtensions.cs @@ -1,11 +1,7 @@ -using System.Globalization; - namespace Polly.Telemetry; internal static class ResilienceContextExtensions { - public static string GetResultType(this ResilienceContext context) => context.IsVoid ? "void" : context.ResultType.Name.ToString(CultureInfo.InvariantCulture); - public static string GetExecutionHealth(this ResilienceContext context) => context.IsExecutionHealthy() ? "Healthy" : "Unhealthy"; public static bool IsExecutionHealthy(this ResilienceContext context) diff --git a/src/Polly.Extensions/Telemetry/ResilienceTelemetryTags.cs b/src/Polly.Extensions/Telemetry/ResilienceTelemetryTags.cs index 672e4ed1fae..acf901b0f1d 100644 --- a/src/Polly.Extensions/Telemetry/ResilienceTelemetryTags.cs +++ b/src/Polly.Extensions/Telemetry/ResilienceTelemetryTags.cs @@ -12,8 +12,6 @@ internal class ResilienceTelemetryTags public const string StrategyName = "strategy-name"; - public const string ResultType = "result-type"; - public const string OperationKey = "operation-key"; public const string ExceptionName = "exception-name"; diff --git a/src/Polly.Extensions/Telemetry/TelemetryListenerImpl.cs b/src/Polly.Extensions/Telemetry/TelemetryListenerImpl.cs index 8fd96714134..28bf79e0e8c 100644 --- a/src/Polly.Extensions/Telemetry/TelemetryListenerImpl.cs +++ b/src/Polly.Extensions/Telemetry/TelemetryListenerImpl.cs @@ -89,8 +89,6 @@ private static void AddCommonTags(in EnrichmentContext(in TelemetryEventArguments _logger.PipelineExecuting( args.Source.PipelineName.GetValueOrPlaceholder(), args.Source.PipelineInstanceName.GetValueOrPlaceholder(), - args.Context.OperationKey, - args.Context.GetResultType()); + args.Context.OperationKey); } else if (GetArgs(args.Arguments, out var pipelineExecuted)) { @@ -175,7 +172,6 @@ private void LogEvent(in TelemetryEventArguments args.Source.PipelineName.GetValueOrPlaceholder(), args.Source.PipelineInstanceName.GetValueOrPlaceholder(), args.Context.OperationKey, - args.Context.GetResultType(), GetResult(args.Context, args.Outcome), args.Context.GetExecutionHealth(), pipelineExecuted.Duration.TotalMilliseconds, diff --git a/test/Polly.Core.Tests/ResiliencePipelineBuilderTests.cs b/test/Polly.Core.Tests/ResiliencePipelineBuilderTests.cs index a8305cc2863..f7ae4cef685 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineBuilderTests.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineBuilderTests.cs @@ -297,8 +297,8 @@ public void Build_EnsureCorrectContext() builder.AddStrategy( context => { - context.BuilderName.Should().Be("builder-name"); - context.StrategyName.Should().Be("strategy-name"); + context.Telemetry.TelemetrySource.PipelineName.Should().Be("builder-name"); + context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy-name"); context.Telemetry.Should().NotBeNull(); context.TimeProvider.Should().Be(builder.TimeProvider); verified1 = true; @@ -310,8 +310,8 @@ public void Build_EnsureCorrectContext() builder.AddStrategy( context => { - context.BuilderName.Should().Be("builder-name"); - context.StrategyName.Should().Be("strategy-name-2"); + context.Telemetry.TelemetrySource.PipelineName.Should().Be("builder-name"); + context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy-name-2"); context.Telemetry.Should().NotBeNull(); context.TimeProvider.Should().Be(builder.TimeProvider); verified2 = true; diff --git a/test/Polly.Core.Tests/ResiliencePropertyKeyTests.cs b/test/Polly.Core.Tests/ResiliencePropertyKeyTests.cs index 57a5f0f040a..c008e49cfe4 100644 --- a/test/Polly.Core.Tests/ResiliencePropertyKeyTests.cs +++ b/test/Polly.Core.Tests/ResiliencePropertyKeyTests.cs @@ -16,32 +16,4 @@ public void Ctor_Null_Throws() { Assert.Throws(() => new ResiliencePropertyKey(null!)); } - - [Fact] - public void Equality_Ok() - { - var key1 = new ResiliencePropertyKey("dummy"); - var key2 = new ResiliencePropertyKey("dummy"); - - key1.Equals(key2).Should().BeTrue(); - key1.Equals(new ResiliencePropertyKey("dummy2")).Should().BeFalse(); - key1.Equals(new ResiliencePropertyKey("dummy")).Should().BeFalse(); - - key1.Equals((object)key2).Should().BeTrue(); - key1.Equals((object)new ResiliencePropertyKey("dummy2")).Should().BeFalse(); - - (key1 == key2).Should().BeTrue(); - (key1 != key2).Should().BeFalse(); - } - - [Fact] - public void GetHashCode_Ok() - { - var key1 = new ResiliencePropertyKey("dummy"); - var key2 = new ResiliencePropertyKey("dummy"); - - key1.GetHashCode().Should().Be(key2.GetHashCode()); - key1.GetHashCode().Should().NotBe(new ResiliencePropertyKey("dummy2").GetHashCode()); - key1.GetHashCode().Should().NotBe(new ResiliencePropertyKey("dummy").GetHashCode()); - } } diff --git a/test/Polly.Core.Tests/StrategyBuilderContextTests.cs b/test/Polly.Core.Tests/StrategyBuilderContextTests.cs index b493164744f..d8af13aac3c 100644 --- a/test/Polly.Core.Tests/StrategyBuilderContextTests.cs +++ b/test/Polly.Core.Tests/StrategyBuilderContextTests.cs @@ -10,11 +10,13 @@ public class StrategyBuilderContextTests public void Ctor_EnsureDefaults() { var timeProvider = new FakeTimeProvider(); - var context = new StrategyBuilderContext("builder-name", "instance", "strategy-name", timeProvider, Substitute.For()); + var context = new StrategyBuilderContext( + new ResilienceStrategyTelemetry(new ResilienceTelemetrySource("builder-name", "instance", "strategy-name"), + Substitute.For()), timeProvider); - context.BuilderName.Should().Be("builder-name"); - context.BuilderInstanceName.Should().Be("instance"); - context.StrategyName.Should().Be("strategy-name"); + context.Telemetry.TelemetrySource.PipelineName.Should().Be("builder-name"); + context.Telemetry.TelemetrySource.PipelineInstanceName.Should().Be("instance"); + context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy-name"); context.TimeProvider.Should().Be(timeProvider); context.Telemetry.Should().NotBeNull(); diff --git a/test/Polly.Core.Tests/Telemetry/TelemetryUtilTests.cs b/test/Polly.Core.Tests/Telemetry/TelemetryUtilTests.cs index ea8a6ee5ca7..0e837506901 100644 --- a/test/Polly.Core.Tests/Telemetry/TelemetryUtilTests.cs +++ b/test/Polly.Core.Tests/Telemetry/TelemetryUtilTests.cs @@ -4,17 +4,6 @@ namespace Polly.Core.Tests.Telemetry; public class TelemetryUtilTests { - [Fact] - public void CreateResilienceTelemetry_Ok() - { - var telemetry = TelemetryUtil.CreateTelemetry(null, "builder", "instance", "strategy-name"); - - telemetry.TelemetrySource.PipelineName.Should().Be("builder"); - telemetry.TelemetrySource.PipelineInstanceName.Should().Be("instance"); - telemetry.TelemetrySource.StrategyName.Should().Be("strategy-name"); - telemetry.Listener.Should().BeNull(); - } - [InlineData(true, ResilienceEventSeverity.Warning)] [InlineData(false, ResilienceEventSeverity.Information)] [Theory] diff --git a/test/Polly.Extensions.Tests/DependencyInjection/PollyServiceCollectionExtensionTests.cs b/test/Polly.Extensions.Tests/DependencyInjection/PollyServiceCollectionExtensionTests.cs index ba2b3f20b21..5187bf97fef 100644 --- a/test/Polly.Extensions.Tests/DependencyInjection/PollyServiceCollectionExtensionTests.cs +++ b/test/Polly.Extensions.Tests/DependencyInjection/PollyServiceCollectionExtensionTests.cs @@ -96,7 +96,7 @@ public void AddResiliencePipeline_EnsureContextFilled(bool generic) { context.RegistryContext.Should().NotBeNull(); context.PipelineKey.Should().Be(Key); - context.BuilderName.Should().Be(Key); + builder.Name.Should().Be(Key); builder.Should().NotBeNull(); context.ServiceProvider.Should().NotBeNull(); builder.AddStrategy(new TestStrategy()); diff --git a/test/Polly.Extensions.Tests/Telemetry/TelemetryListenerImplTests.cs b/test/Polly.Extensions.Tests/Telemetry/TelemetryListenerImplTests.cs index 01a353aae12..5ce67a3266c 100644 --- a/test/Polly.Extensions.Tests/Telemetry/TelemetryListenerImplTests.cs +++ b/test/Polly.Extensions.Tests/Telemetry/TelemetryListenerImplTests.cs @@ -193,11 +193,11 @@ public void WriteEvent_MeteringWithoutEnrichers_Ok(bool noOutcome, bool exceptio if (noOutcome && exception) { - ev.Count.Should().Be(8); + ev.Count.Should().Be(7); } else { - ev.Count.Should().Be(7); + ev.Count.Should().Be(6); } ev["event-name"].Should().Be("my-event"); @@ -206,7 +206,6 @@ public void WriteEvent_MeteringWithoutEnrichers_Ok(bool noOutcome, bool exceptio ev["pipeline-instance"].Should().Be("pipeline-instance"); ev["operation-key"].Should().Be("op-key"); ev["strategy-name"].Should().Be("my-strategy"); - ev["result-type"].Should().Be("Boolean"); if (outcome?.Exception is not null) { @@ -242,11 +241,11 @@ public void WriteExecutionAttemptEvent_Metering_Ok(bool noOutcome, bool exceptio if (noOutcome && exception) { - ev.Count.Should().Be(10); + ev.Count.Should().Be(9); } else { - ev.Count.Should().Be(9); + ev.Count.Should().Be(8); } ev["event-name"].Should().Be("my-event"); @@ -255,7 +254,6 @@ public void WriteExecutionAttemptEvent_Metering_Ok(bool noOutcome, bool exceptio ev["pipeline-instance"].Should().Be("pipeline-instance"); ev["operation-key"].Should().Be("op-key"); ev["pipeline-name"].Should().Be("my-pipeline"); - ev["result-type"].Should().Be("Boolean"); ev["attempt-number"].Should().Be(5); ev["attempt-handled"].Should().Be(true); @@ -291,7 +289,7 @@ public void WriteEvent_MeteringWithEnrichers_Ok(int count) { using var metering = TestUtilities.EnablePollyMetering(_events); - const int DefaultDimensions = 7; + const int DefaultDimensions = 6; var telemetry = Create(new[] { @@ -372,10 +370,10 @@ public void PipelineExecution_Logged(bool healthy, bool exception) var messages = _logger.GetRecords(new EventId(1, "StrategyExecuting")).ToList(); messages.Should().HaveCount(1); - messages[0].Message.Should().Be("Resilience pipeline executing. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result Type: 'Int32'"); + messages[0].Message.Should().Be("Resilience pipeline executing. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key'"); messages = _logger.GetRecords(new EventId(2, "StrategyExecuted")).ToList(); messages.Should().HaveCount(1); - messages[0].Message.Should().Match($"Resilience pipeline executed. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result Type: 'Int32', Result: '{result}', Execution Health: '{healthString}', Execution Time: 10000ms"); + messages[0].Message.Should().Match($"Resilience pipeline executed. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result: '{result}', Execution Health: '{healthString}', Execution Time: 10000ms"); messages[0].LogLevel.Should().Be(healthy ? LogLevel.Debug : LogLevel.Warning); } @@ -388,7 +386,7 @@ public void PipelineExecution_VoidResult_Ok() var messages = _logger.GetRecords(new EventId(1, "StrategyExecuting")).ToList(); messages.Should().HaveCount(1); - messages[0].Message.Should().Be("Resilience pipeline executing. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result Type: 'void'"); + messages[0].Message.Should().Be("Resilience pipeline executing. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key'"); } [Fact] @@ -400,7 +398,7 @@ public void PipelineExecution_NoOutcome_Logged() ReportEvent(telemetry, outcome: null, arg: new PipelineExecutedArguments(TimeSpan.FromSeconds(10)), context: context); var messages = _logger.GetRecords(new EventId(2, "StrategyExecuted")).ToList(); - messages[0].Message.Should().Match($"Resilience pipeline executed. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result Type: 'Int32', Result: '', Execution Health: 'Healthy', Execution Time: 10000ms"); + messages[0].Message.Should().Match($"Resilience pipeline executed. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result: '', Execution Health: 'Healthy', Execution Time: 10000ms"); } [InlineData(true, false)] @@ -439,11 +437,10 @@ public void PipelineExecution_Metered(bool healthy, bool exception) var ev = _events.Single(v => v.Name == "pipeline-execution-duration").Tags; - ev.Count.Should().Be(exception ? 10 : 9); + ev.Count.Should().Be(exception ? 9 : 8); ev["pipeline-instance"].Should().Be("pipeline-instance"); ev["operation-key"].Should().Be("op-key"); ev["pipeline-name"].Should().Be("my-pipeline"); - ev["result-type"].Should().Be("Int32"); ev["event-name"].Should().Be("my-event"); ev["event-severity"].Should().Be("Warning"); ev["pipeline-name"].Should().Be("my-pipeline"); diff --git a/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs b/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs index e1144c48e6f..8ceb9fc56cf 100644 --- a/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs +++ b/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs @@ -14,7 +14,6 @@ public class ResiliencePipelineConversionExtensionsTests private readonly ResiliencePipeline _genericStrategy; private bool _isSynchronous; private bool _isVoid; - private Type? _resultType; public ResiliencePipelineConversionExtensionsTests() { @@ -22,16 +21,11 @@ public ResiliencePipelineConversionExtensionsTests() { Before = (context, _) => { - context.IsVoid.Should().Be(_isVoid); + context.GetType().GetProperty("IsVoid", BindingFlags.Instance | BindingFlags.NonPublic)!.GetValue(context).Should().Be(_isVoid); context.IsSynchronous.Should().Be(_isSynchronous); context.Properties.Set(Outgoing, "outgoing-value"); context.Properties.GetValue(Incoming, string.Empty).Should().Be("incoming-value"); context.OperationKey.Should().Be("op-key"); - - if (_resultType != null) - { - context.ResultType.Should().Be(_resultType); - } } }; @@ -64,7 +58,6 @@ public void AsSyncPolicy_Generic_Ok() { _isVoid = false; _isSynchronous = true; - _resultType = typeof(string); var context = new Context("op-key") { [Incoming.Key] = "incoming-value" @@ -80,7 +73,6 @@ public void AsSyncPolicy_Result_Ok() { _isVoid = false; _isSynchronous = true; - _resultType = typeof(string); var context = new Context("op-key") { [Incoming.Key] = "incoming-value" @@ -117,7 +109,6 @@ public async Task AsAsyncPolicy_Generic_Ok() { _isVoid = false; _isSynchronous = false; - _resultType = typeof(string); var context = new Context("op-key") { [Incoming.Key] = "incoming-value" @@ -138,7 +129,6 @@ public async Task AsAsyncPolicy_Result_Ok() { _isVoid = false; _isSynchronous = false; - _resultType = typeof(string); var context = new Context("op-key") { [Incoming.Key] = "incoming-value"