Logging Polly wait and retry policy ASP.NET CORE 2.1
Asked Answered
S

2

10

I need to log retry policy defined via Polly in APS.NET CORE 2.1+.

My code is below showing Polly retry polly and using HttpClient.

public IServiceProvider ConfigureServices(IServiceCollection services)
        {
          //...

            //https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory            
            Random jitterer = new Random();
            services.AddHttpClient<SimpleCastClient>()
                //TransientErrors:
                //Network failures(System.Net.Http.HttpRequestException)
                //HTTP 5XX status codes(server errors)
                //HTTP 408 status code(request timeout)
                .AddTransientHttpErrorPolicy(policyBuilder =>
                    //Exponential backoff with Randomisation
                    policyBuilder.WaitAndRetryAsync(10,
                        retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
                                        + TimeSpan.FromMilliseconds(jitterer.Next(1, 100))
                    ));
}

  [ApiVersion("1")]
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    public class MyController : ControllerBase
    {
        ILog _logger;
        private SimpleCastClient _simpleCastClient;

        public MyController(ILog logger, SimpleCastClient simpleCastClient)
        {
            _logger = logger;
            _simpleCastClient = simpleCastClient;
        }

        [HttpPost]
        public async Task Post()
        {           
            await _simpleCastClient.PostAsync();

        }

    }


  public class SimpleCastClient
    {
        private HttpClient _client;

        public SimpleCastClient(HttpClient client)
        {
            _client = client;

        }
        public async Task PostAsync()
        {
            string url = $"http://localhost:1111/api/v1/Mock/";
            using (var content = new StringContent("data", Encoding.UTF8, "application/json"))
            {                
                var response = await _client.PostAsync(url, content);                          
            }
        }
}

I wonder if there is a better way than what is on stevejgordon.

Sundowner answered 4/12, 2018 at 1:15 Comment(1)
If the code is otherwise working as expected, you could post it on codereview.stackexchange.com instead.Velum
G
22

With HttpClientFactory you can apply a Polly policy to a pre-configured HttpClient, and use an ILogger configured on DI in that Polly policy, with code like this:

services.AddHttpClient<MyServiceHttpClient>(/* etc */)
    .AddPolicyHandler((services, request) => HttpPolicyExtensions.HandleTransientHttpError()
        .WaitAndRetryAsync(new[]
        {
            TimeSpan.FromSeconds(1),
            TimeSpan.FromSeconds(5),
            TimeSpan.FromSeconds(10)
        },             
        onRetry: (outcome, timespan, retryAttempt, context) =>
        {
            services.GetService<ILogger<MyServiceHttpClient>>()
                .LogWarning("Delaying for {delay}ms, then making retry {retry}.", timespan.TotalMilliseconds, retryAttempt);
        }
        ));

Reference: https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory#configuring-policies-to-use-services-registered-with-di-such-as-iloggert

Geithner answered 4/12, 2018 at 8:34 Comment(1)
I have a similar code and the retry stopped working because I got a null pointer exception because services.GetService<ILogger<MyServiceHttpClient>>() does not resolve in the context. For just the security reasons use SeriLog static object "Log" or at least put the logging in try catchOrgano
S
0

Since you are using ASP.NET core 2.1 consider using HttpClientFactory. Fits great with polly with additional benefits and logging is simplified.

https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory

Substratosphere answered 4/12, 2018 at 4:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.