目的
用于记录HTTP Client相互调用的日志,方便正式环境查询数据、排查问题;
实现
新建HttpMessageLogHandler文件,继承DelegatingHandler,重写SendAsync方法
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
//return base.SendAsync(request, cancellationToken);
var sw = Stopwatch.StartNew();
using (LogContext.PushProperty("ServiceHost", request?.RequestUri?.Host))
{
if (request == null) throw new ArgumentNullException(nameof(request), "Http request is null.");
var httpResponseMessage = await base.SendAsync(request, cancellationToken);
var responseBody = await httpResponseMessage.Content.ReadAsStringAsync(cancellationToken);
string encryptedBody;
string encryptedResponseHeaders;
var encryptedRequestBody = string.Empty;
if (request.Content != null)
{
var requestString = await request.Content.ReadAsStringAsync(cancellationToken);
encryptedRequestBody = _cryptoUtilityService.Aes256CbcEncrypt(requestString);
}
encryptedBody = _cryptoUtilityService.Aes256CbcEncrypt(responseBody);
encryptedResponseHeaders = _cryptoUtilityService.Aes256CbcEncrypt(JsonConvert.SerializeObject(httpResponseMessage.Headers));
_logger.LogInformation($"HTTP Response Headers:\r\n{encryptedResponseHeaders}\r\nResponseBody:\r\n{encryptedBody}\r\nRequestBody:\n\r{encryptedRequestBody}\r\n");
_logger.LogInformation($"HTTP Response {httpResponseMessage.StatusCode} {{@HttpMethod}}:{{@RequestPath}} in {{@Elapsed}}", request.Method, request.RequestUri, sw.Elapsed);
return httpResponseMessage;
}
}
注入
#region HttpClient
services.AddTransient<HttpMessageLogHandler>();
services.AddHttpClient(HttpClientConfig.WeatherForecast, Hc.DefaultClientConfig).AddHttpMessageHandler<HttpMessageLogHandler>();
services.AddHttpClient(HttpClientConfig.PostBodyTest, Hc.DefaultClientConfig).AddHttpMessageHandler<HttpMessageLogHandler>();
#endregion
测试
新建一个WebAPI项目,使用默认天气接口GetWeatherForecast,使用我们的程序发起HTTP请求,查看控制台的log输出
[HttpGet("weatherForecast")]
public async Task<ResponseBaseInfo> GetWeatherForecast()
{
var url = "https://localhost:7067/api/WeatherForecast";
var httpClient = _httpClientFactory.CreateClient(HttpClientConfig.WeatherForecast);
var response = await httpClient.GetAsync(url);
var data = await response.Content.ReadAsStringAsync();
return new ResponseBaseInfo(true, data);
}
控制台输出如下
解密查看数据
测试通过