簡體   English   中英

Polly 記錄所有帶有 URL、標頭、內容和響應的請求

[英]Polly log all requests with URL, Headers, Content and Response

我有一個從其他項目調用許多 rest API 的項目,我遇到了一些問題,不僅要識別來自這些 API 的錯誤,還要識別正確的響應,但信息在其他系統上不正確。 我做了這部分,但它只記錄重試,我還需要記錄成功。

services.AddHttpClient<IClient, Client>("AuthClient", x =>
    {
        x.BaseAddress = new Uri(urlAn);
    }).AddPolicyHandler((services, request) => 
    HttpPolicyExtensions.HandleTransientHttpError().WaitAndRetryAsync(
    new[]
    {
        TimeSpan.FromSeconds(1),
        TimeSpan.FromSeconds(5),
        TimeSpan.FromSeconds(10)
    },
    onRetry: (outcome, timespan, retryAttempt, context) =>
    {
        services.GetService<ILogger>()
            .LogWarning("Delaying for {delay}ms, then making retry {retry}.", timespan.TotalMilliseconds, retryAttempt);
    }));

只有在出現錯誤時才會執行onRetry方法,錯誤由策略處理。 HandleTransientHttpError觸發策略

  • 當出現HttpRequestException
  • 或者當響應代碼是 408 或 5xxx 時。

要注入應在每種情況下執行的邏輯,您需要使用自定義DelegatingHandler 這個擴展點讓您可以將自定義代碼注入到 HttpClient 的管道 ( 1 ) 中。

這是LoggerHandler的簡單實現:

class LoggerHandler: DelegatingHandler
{
    private readonly ILogger<LoggerHandler> _logger;

    public LoggerHandler(ILogger<LoggerHandler> logger)
    {
        _logger = logger;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        try
        {
            var response = await base.SendAsync(request, cancellationToken);
            _logger.LogInformation(response.StatusCode.ToString());
            return response;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Request has failed after several retries");
            throw;
        }
    }
}
  • 如您所見,我們已將記錄器注入處理程序
    • 如果下游請求完美無缺,我們會在信息級別記錄一些事實
    • 如果下游請求有問題,我們會在錯誤級別記錄異常

現在,讓我們連接所有的東西:

var retryPolicy = HttpPolicyExtensions.HandleTransientHttpError().WaitAndRetryAsync(
    new[]
    {
        TimeSpan.FromSeconds(1),
        TimeSpan.FromSeconds(5),
        TimeSpan.FromSeconds(10)
    });

services.AddHttpClient<IClient, Client>("AuthClient", x => { x.BaseAddress = new Uri(urlAn); })
    .AddPolicyHandler(retryPolicy)
    .AddHttpMessageHandler<LoggerHandler>();

請謹記報名順序事宜。

  • 請檢查此SO 主題以獲取更多詳細信息。

還有幾件小事也可以改進:

  • 您不必為HttpClient指定名稱,因為您使用的是 Typed-Client。
    • services.AddHttpClient<IClient, Client>(x =>...)
  • 我強烈建議使用比IClientClient更好的命名。 想象一種情況,您需要向您的應用程序再添加一個客戶端。 怎么命名呢? AuthClient可能是一個更好的名字:
    • services.AddHttpClient<IAuthClient, AuthClient>(x =>...)
  • 我還鼓勵您使用抖動來增加重試睡眠持續時間的隨機性。 如果所有客戶端都嘗試對過載的服務器執行重試,那么它對下游沒有幫助。
    • 嘗試分配具有抖動的重試。
  • 我還建議閱讀這篇關於 Retry、Timeout 和 DelegatingHandler 的文章。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM