【小作业】为NLog自定义LayoutRenderer

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

【小作业】为NLog自定义LayoutRenderer

nodotnet   2019-12-07 我要评论

长话短说

  前文《解剖HttpClientFactory,自由扩展HttpMessageHandler》主要想讲如何扩展HttpMessageHandler,  示例为在每个Http请求中的日志中显示TraceId,

现在来完成课后的小作业: 将TraceId显示到Nlog的LayoutRenderer上。

本次重新实现一个流畅简单的  LoggingHttpMessageHandler, 并添加到NLog LayoutRenderer。

 什么是Layout Renderer?

 nlog 日志上显示的特定字段,便于检索和分类。

头脑风暴

先给出自定义Renderer,定义名为eqid的自定义Renderer

# 截取自 nlog.config配置文件
<variable name="format1" value="${date:format=yy/MMhttps://img.qb5200.com/download-x/dd HH\:mm\:ss} [${level}].[${logger}].[${threadid}}].[${aspnet-request-url:IncludeScheme=false:IncludeHost=false}].[${eqid}]${newline}${message} ${exception:format=tostring}" />

<target name="bce-request"
           xsi:type="File"
           layout="${format1}"
           fileName="${logDir}/bce-request.log"
           encoding="utf-8"/>

 

-------------------------------1----------------------------

 Nlog 添加自定义LayOutRenderer, https://github.com/NLog/NLog/wiki/How-to-write-a-custom-layout-renderer

  有简单的lambda方式,这里我们采用稍微灵活的自定义类方式:

 [LayoutRenderer("eqid")]
    public class EqidLayoutRenderer : LayoutRenderer
    {
        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            builder.Append(logEvent.Properties["EventId_Name"].ToString());
        }
    }

关键点是实现 LayoutRenderer 的抽象方法 Append,  关键参数logevent由写入Logging时形成。

从EventId.Name中为eqid renderer取值的原因如步骤2

---------------------------------2-----------------------------

配合着,我们在写入日志时, 也在该property 中写入该Renderer的值:

public class AttachTraceIdScopeHttpMessageHandler : 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 eventName = request.RequestUri.LocalPath.Split('/').LastOrDefault();

            _logger.Log(LogLevel.Information, new EventId(100, eventName),
                $"Start processing HTTP request {request.RequestUri} {request.Method}");
            var response = await base.SendAsync(request, cancellationToken);
            stopwatch.Stop();
            _logger.Log(LogLevel.Information, new EventId(101, eventName),
                $"End processing HTTP request after {stopwatch.Elapsed.TotalMilliseconds}ms - {response.StatusCode}");
            return response;
        }
    }

EventId 中的Name属性,最后在 nlog的 EventLogInfo中被认定为 Property[EventId_Name], 所以我们有以上操作。

按照上文方式,添加到 CustomHttpMessageHandlerFilter,并注册为 IHttpMessageHandlerFilter 实现。

 

--------------------------------3------------------------

按照文档的要求,尽量早点注册自定义Nlog LayoutRenderer,

因此我在 main函数开始的时候就注册了该Renderer, 注册名称是TraceId

public static void Main(string[] args)
{
            LayoutRenderer.Register<EqidLayoutRenderer>("eqid");
......
}

最终输出如下:

19/12/07 00:35:42 [Info].[System.Net.Http.HttpClient.bce-request.LogicalHandler].[19}].[].[125aa91f0011426c000000045dea5ea0]
Start processing HTTP request http://localhost:5000/v1/eqid/125aa91f0011426c000000045dea5ea0 GET 
19/12/07 00:35:44 [Info].[System.Net.Http.HttpClient.bce-request.LogicalHandler].[5}].[].[125aa91f0011426c000000045dea5ea0]
End processing HTTP request after 2178.9971ms - OK 

 

ok, 运行本文示例,请务必参阅 《解剖HttpClientFactory,自由扩展HttpMessageHandler》思路,本文主要目的是讲解 自定义Nlog LayoutRenderer.

 

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们