zoukankan      html  css  js  c++  java
  • 被忽略的TraceId,可以用起来了

    前言

      .NetCore日志,相信大家多少都接触过,博客园有关 ① AspNetCore依赖注入第三方日志组件   ②第三方日志组件Nlog,Serilog 应用方法的博文层出不穷。

    结合程序的部署结构,本文分单体和微服务聊一聊AspNetCore中追踪日志流的方法。

    TraceID作用和组成

    TraceID标记了 浏览器发起的某个请求, 这个id可在服务端从接收请求到 响应请求中流转,甚至接力传递给下游应用中流转,用于唯一标记和定外这次请求。

    一般用于定位请求日志

      ASP.Net Core 基于中间件管道处理请求, 根据需要记录日志; 生产出故障时,在数量庞大的日志记录中追踪某个请求完整的处理链显得很有必要(这个深有体会)。

    针对单体程序,ASP.Net Core为我们提供了HttpContext.TraceIdentifier属性, 这个TraceId由{ConnectionId}:{Request Number}组成,理论上这个id标记了位于某Http连接上的某次请求。

    ① 为什么由 {ConnectionId}:{Request Number}组成?

    默认大部分读者知晓Http1.1 一个连接上可发起多个Http请求

    ② TraceId 中ConnectionId由Kestrel从{0-9,a-z}中生成,可参考:https://github.com/aspnet/KestrelHttpServer/blob/a48222378b8249a26b093b5b835001c7c7b45815/src/Kestrel.Core/Internal/Infrastructure/CorrelationIdGenerator.cs

    ok, 现在着重聊一下使用方式和衍生知识点

    ASP.NET Core使用TraceId

    搭配Nlog记录TraceId

    ① 启用NLog日志

      添加  <PackageReference Include="NLog.Web.AspNetCore" Version="4.9.0" />

    public class Program
        {
            public static void Main(string[] args)
            {
                var webHost = WebHost.CreateDefaultBuilder(args)
                         .ConfigureAppConfiguration((hostingContext, configureDelagate) =>
                         {
                             configureDelagate.AddJsonFile($"appsettings.secrets.json", optional: true, reloadOnChange: true);
                         })
                         .ConfigureLogging((hostingContext, loggingBuilder) =>
                         {
                             loggingBuilder.AddConsole().AddDebug();
                         })
                         .UseNLog()       // 默认会找工作目录下nlog.config配置文件
                         .UseStartup<Startup>()
                         .Build();
                webHost.Run();
            }
        }

    很明显,Nlog要在Pipeline中自由获取HttpContext属性,这里需要

    ② 注册IHttpContextAccessor

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        }
    }

    ③ 配置Nlog 显示TraceId

       TraceId在Nlog 是以Layout Renderer形式表达的:

    更多的Renderer参考。下面的Nlog配置文件呈现了TraceId & User_Id(业务上的UserId能帮助我们在茫茫日志中快速缩小日志)

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  autoReload="true" throwExceptions="false"  internalLogFile="internal-nlog.txt">
      <variable name="logDir" value="logs/${date:format=yyyyMMdd}" />     <!-- 日志存储文件夹-->
      <variable name="format" value="${date:format=yy/MM/dd HH:mm:ss} [${level}].[${logger}].[${aspnet-TraceIdentifier}].[${aspnet-user-identity}]${newline}${message} ${exception:format=tostring}" />
      <targets>
        <target name="info"
               xsi:type="File"
               layout="${format}"
               fileName="${logDir}/info.log"
               encoding="utf-8"/>
      </targets>   
      <rules>
        <logger name="*" minlevel="Info" writeTo="info" />
      </rules>
    </nlog>

     结果如下:

    以上是在单体程序内根据traceid追踪请求流的方法。

    进一步思考,在微服务中,各服务独立形成TraceId,在初始阶段生成 TraceId 并在各微服务中保持该Traceid即可追踪微服务的请求流

    ASP.NET Core分布式TraceId:CorrelationId

    这里首先假设你的微服务/ 分布式服务已经部署ELK 等日志几种采集处理框架,没有部署ELK也可将多个服务的日志写到同一个物理文件夹。

      隆重介绍轮子 CorrelationId: https:/github.com/stevejgordon/CorrelationId

    CorrelationId是通过自定义Header来标记TraceId概念

    •   CorrelationId 在首次收到请求时自定义名为【X-Correlation-ID】 的请求头,在本服务Response写入该Header 

    •   后置服务检测到请求头中包含该Header, 将该CorrelationId作为本服务的TraceId 向后流转

    这样在集中日志中,能通过某TraceID追踪微服务/分布式 全链路请求处理日志。

    使用方式也相当简单:

    // Install-Package CorrelationId -Version 2.1.0
    
    public void ConfigureServices(IServiceCollection services)
    {
       services.AddMvc();
       services.AddCorrelationId();
    }

    一般在所有请求处理Middleware之前注册 CorrelationId, 这样在所有中间件就能获取到 TraceId:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
       app.UseCorrelationId();
    
       if (env.IsDevelopment())
       {
          app.UseDeveloperExceptionPage();
       }
    
       app.UseMvc();
    }

    打算应用该TraceId追踪全流程请求日志的服务都需要包含 中间件。

    Ok, 本文聊一聊TraceID的作用和一般组成,衍生出ASP. NETCore  单体和分布式程序中 TraceId 的使用方式, 希望对大家在日志排障时有所帮助。

  • 相关阅读:
    idea工具如何在修改jsp后不用一直重启idea
    解决端口被占用问题
    tomcat端口强制关闭
    tomcat部署方式之三(war包,也是最重要的)
    tomcat部署方式之二
    tomcat的配置方式一
    在启动tomcat时出现java_home未配置的问题(闪退)
    mysql出现“mysql不是内部或外部命令也不是可运行”
    staruml下载
    用java语言实现一个观察者模式
  • 原文地址:https://www.cnblogs.com/JulianHuang/p/11952959.html
Copyright © 2011-2022 走看看