仅当内容类型等于 json 时才记录 WebAPI
WebAPI log only when content type equal to json
目前,我有一个全局注册的处理程序来捕获各种请求和响应。但是,系统包含一些内容类型为 pdf 或 csv 的端点。
public class LogRequestAndResponseHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// log request body
var requestBody = await request.Content.ReadAsStringAsync();
LogUtil.Info("[" + request.GetCorrelationId() + "] Call:" + request.RequestUri,"httpTrace");
if(!string.IsNullOrEmpty(requestBody))
LogUtil.Info(requestBody,"httpTrace");
// let other handlers process the request
var result = await base.SendAsync(request, cancellationToken);
if (result.Content != null)
{
// once response body is ready, log it
var responseBody = await result.Content.ReadAsStringAsync();
//LogUtil.Info(responseBody,"httpTrace");
LogUtil.Info("[" + request.GetCorrelationId().ToString() + "] Return:" + responseBody,"httpTrace");
}
return result;
}
}
我正在使用上面的代码,每当调用 pdf 端点时,整个 pdf body 将以二进制格式捕获到日志中。
我想知道最好的过滤方法是什么只过滤jsonbody或header来记录。
客户端和服务器都应该使用Content-Type header来表示body的内容类型。
您可以检查请求和响应 - 可能是这样的:
public class LogRequestAndResponseHandler : DelegatingHandler
{
private bool ShouldLog(IDictionary<string, IEnumerable<string>> headers)
{
if (headers.TryGetValue("Content-Type", out IEnumerable<string> values))
{
if (values.Any(x => x == "application/json"))
return true;
}
return false;
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// log request body
if (ShouldLog(request.Headers.ToDictionary(x => x.Key, x => x.Value)))
{
var requestBody = await request.Content.ReadAsStringAsync();
LogUtil.Info("[" + request.GetCorrelationId() + "] Call:" + request.RequestUri, "httpTrace");
if (!string.IsNullOrEmpty(requestBody))
LogUtil.Info(requestBody, "httpTrace");
}
// let other handlers process the request
var result = await base.SendAsync(request, cancellationToken);
if (result.Content != null)
{
if (ShouldLog(result.Headers.ToDictionary(x => x.Key, x => x.Value)))
{
// once response body is ready, log it
var responseBody = await result.Content.ReadAsStringAsync();
//LogUtil.Info(responseBody,"httpTrace");
LogUtil.Info("[" + request.GetCorrelationId().ToString() + "] Return:" + responseBody, "httpTrace");
}
}
return result;
}
}
您可能需要进一步完善它,也许您还想记录 text/plain
或其他一些类型,但这应该可以帮助您入门。
目前,我有一个全局注册的处理程序来捕获各种请求和响应。但是,系统包含一些内容类型为 pdf 或 csv 的端点。
public class LogRequestAndResponseHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// log request body
var requestBody = await request.Content.ReadAsStringAsync();
LogUtil.Info("[" + request.GetCorrelationId() + "] Call:" + request.RequestUri,"httpTrace");
if(!string.IsNullOrEmpty(requestBody))
LogUtil.Info(requestBody,"httpTrace");
// let other handlers process the request
var result = await base.SendAsync(request, cancellationToken);
if (result.Content != null)
{
// once response body is ready, log it
var responseBody = await result.Content.ReadAsStringAsync();
//LogUtil.Info(responseBody,"httpTrace");
LogUtil.Info("[" + request.GetCorrelationId().ToString() + "] Return:" + responseBody,"httpTrace");
}
return result;
}
}
我正在使用上面的代码,每当调用 pdf 端点时,整个 pdf body 将以二进制格式捕获到日志中。
我想知道最好的过滤方法是什么只过滤jsonbody或header来记录。
客户端和服务器都应该使用Content-Type header来表示body的内容类型。
您可以检查请求和响应 - 可能是这样的:
public class LogRequestAndResponseHandler : DelegatingHandler
{
private bool ShouldLog(IDictionary<string, IEnumerable<string>> headers)
{
if (headers.TryGetValue("Content-Type", out IEnumerable<string> values))
{
if (values.Any(x => x == "application/json"))
return true;
}
return false;
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
// log request body
if (ShouldLog(request.Headers.ToDictionary(x => x.Key, x => x.Value)))
{
var requestBody = await request.Content.ReadAsStringAsync();
LogUtil.Info("[" + request.GetCorrelationId() + "] Call:" + request.RequestUri, "httpTrace");
if (!string.IsNullOrEmpty(requestBody))
LogUtil.Info(requestBody, "httpTrace");
}
// let other handlers process the request
var result = await base.SendAsync(request, cancellationToken);
if (result.Content != null)
{
if (ShouldLog(result.Headers.ToDictionary(x => x.Key, x => x.Value)))
{
// once response body is ready, log it
var responseBody = await result.Content.ReadAsStringAsync();
//LogUtil.Info(responseBody,"httpTrace");
LogUtil.Info("[" + request.GetCorrelationId().ToString() + "] Return:" + responseBody, "httpTrace");
}
}
return result;
}
}
您可能需要进一步完善它,也许您还想记录 text/plain
或其他一些类型,但这应该可以帮助您入门。