Skip to content

Commit 8fe2c18

Browse files
committed
HttpClient 日志过滤
1 parent 4a7c5a2 commit 8fe2c18

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

Natsurainko.FluentLauncher/Utils/Extensions/DependencyInjectionExtensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.DependencyInjection.Extensions;
23
using Microsoft.Extensions.Hosting;
4+
using Microsoft.Extensions.Http;
35
using Nrk.FluentCore.Resources;
46
using Serilog;
57
using System;
@@ -36,6 +38,8 @@ public static IServiceCollection UseHttpClient(this IServiceCollection services)
3638
builder.ConfigureHttpClient(c => c.DefaultRequestHeaders.UserAgent.Add(userAgent));
3739
});
3840

41+
services.Replace(ServiceDescriptor.Singleton<IHttpMessageHandlerBuilderFilter, CustomHttpMessageHandlerBuilderFilter>());
42+
3943
return services;
4044
}
4145

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using Microsoft.Extensions.Http;
2+
using Microsoft.Extensions.Logging;
3+
using System;
4+
using System.Net;
5+
using System.Net.Http;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace Natsurainko.FluentLauncher.Utils;
10+
11+
internal class CustomHttpMessageHandlerBuilderFilter(ILoggerFactory loggerFactory) : IHttpMessageHandlerBuilderFilter
12+
{
13+
private readonly ILoggerFactory _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
14+
15+
public Action<HttpMessageHandlerBuilder> Configure(Action<HttpMessageHandlerBuilder> next)
16+
{
17+
ArgumentNullException.ThrowIfNull(next);
18+
19+
return (builder) =>
20+
{
21+
// Run other configuration first, we want to decorate.
22+
next(builder);
23+
24+
var outerLogger = _loggerFactory.CreateLogger($"System.Net.Http.HttpClient.{builder.Name}.LogicalHandler");
25+
builder.AdditionalHandlers.Insert(0, new CustomLoggingScopeHttpMessageHandler(outerLogger));
26+
};
27+
}
28+
}
29+
30+
public partial class CustomLoggingScopeHttpMessageHandler(ILogger logger) : DelegatingHandler
31+
{
32+
private readonly ILogger _logger = logger ?? throw new ArgumentNullException(nameof(logger));
33+
34+
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
35+
CancellationToken cancellationToken)
36+
{
37+
ArgumentNullException.ThrowIfNull(request);
38+
39+
var response = await base.SendAsync(request, cancellationToken);
40+
41+
if (!response.IsSuccessStatusCode)
42+
_logger.ProcessingHttpRequestFailed(request.Method, request.RequestUri, response.StatusCode);
43+
44+
return response;
45+
}
46+
}
47+
48+
internal static partial class CustomLoggingScopeHttpMessageHandlerLoggers
49+
{
50+
[LoggerMessage(LogLevel.Error, "Processing HTTP request {httpMethod} {uri} failed - {statusCode}")]
51+
public static partial void ProcessingHttpRequestFailed(this ILogger logger, HttpMethod httpMethod, Uri? uri, HttpStatusCode statusCode);
52+
}

0 commit comments

Comments
 (0)