更多精彩内容请关注我们
长话短说
前文《解剖HttpClientFactory,自由扩展HttpMessageHandler》主要讲如何为HttpClientFactory自定义HttpMessageHandler组件,
现在完成课后的小作业: 将重点日志字段显示到Nlog的Layout Renderer上
本文自定义一个NLog Layout Renderer(显示HttpClient请求的耗时)
什么是Layout Renderer?
nlog日志上输出的特定字段,便于检索和分类。
# 截取自nlog.config配置文件 <target name="bce-request"
xsi:type="File" layout="${date:format=yy/MM/dd HH\:mm\:ss} [${level}].[${logger}].[${threadid}}].[${elapse}]${newline}${message} ${exception:format=tostring}" fileName="${logDir}/bce-request.log" encoding="utf-8"/>
以上配置输出如下日志:
19/12/08 22:46:29 [Info].[System.Net.Http.HttpClient.bce-request.LogicalHandler].[6}].[415.2504]
HTTP request http://localhost:5000/v1/eqid/e741e8d600151edc000000035decf3bf after 415.2504ms end -OK
19/12/08 22:47:15 [Info].[System.Net.Http.HttpClient.bce-request.LogicalHandler].[40}].[80.2951]
HTTP request http://localhost:5000/v1/eqid/2a41e8d600151edc000000028decf3bf after 80.2951ms end -OK
19/12/08 22:48:06 [Info].[System.Net.Http.HttpClient.bce-request.LogicalHandler].[43}].[36.8624]
HTTP request http://localhost:5000/v1/eqid/1a41e8d600151edc000000028decf3bf after 36.8624ms end -OK
头脑风暴
nlog所有的日志Render依赖日志写入时的信息, 因此我们在写入日志时附带该Renderer值, 然后配置nlog显示日志时提取该Renderer值。
1
写入日志时,为Message传入参数{Url}, {Elapse}, {StatusCode}, 这三个参数值可被提取作为 Renderer
public class CustomHttpMessageHandler : DelegatingHandler
{
private readonly ILogger _logger;
public AttachTraceIdScopeHttpMessageHandler(ILogger logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}
var stopwatch = Stopwatch.StartNew();
var response = await base.SendAsync(request, cancellationToken);
stopwatch.Stop();
_logger.Log(LogLevel.Information, new EventId(101, "Request End"),
"HTTP request {Url} after {Elapse}ms end -{StatusCode}",
request.RequestUri, stopwatch.Elapsed.TotalMilliseconds, response.StatusCode);
return response;
}
}
2
添加自定义LayOutRenderer
① 简单的lambda方式,
② 我们采用稍灵活的自定义类方式:
关键点是实现LayoutRenderer的抽象方法Append, 从LogEventInfo中提出Renderer值:
[LayoutRenderer("elapse")]
public class ElapseLayoutRenderer : LayoutRenderer
{
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
builder.Append(logEvent.Properties["Elapse"].ToString());
}
}
# 参数Url、Elapse、StatusCode均可在LogEventInfo.Prpperties键值对提取
3
按照文档的要求,尽早注册自定义Nlog Layout Renderer:
public static void Main(string[] args)
{
LayoutRenderer.Register<ElapseLayoutRenderer>("elapse");
......
}
END
关于将该HttpMessgaeHandler应用到HttpClientFactory,请参阅《解剖HttpClientFactory,自由扩展HttpMessageHandler》思路。本文演示为nlog添加自定义LayoutRenderer。
+ https://github.com/NLog/NLog/wiki/How-to-write-a-custom-layout-renderer
扫一扫左边二维码,
更多干货等着你。
............