前言

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

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

TraceId

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

针对单体程序,AspNetCore贴心的为我们提供了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, 现在着重聊一下应用方式和衍生知识点

① 启用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) =>                     {                         //configureDelegate默认会按照如下顺序加载ChainedConfiguration、appsetting.*.json,Environment、CommandLine                         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{    // rest of the code omitted for brevity    public void ConfigureServices(IServiceCollection services)    {        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();    }    // rest of the code omitted for brevity}

② 配置Nlog 以支持 TraceId

实际上nlog支持记录很多HttpContext信息,详情请关注https://nlog-project.org/config/?tab=layout-renderers。

下面的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即可追踪微服务的请求流。

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在单体程序和 分布式程序中的应用, 希望对大家在日志排障时有所帮助。

被忽略的TraceId,可以用起来了相关推荐

  1. 为什么我们需要Logstash,Fluentd等日志摄取器?

    前文传送门:如何利用NLog输出结构化日志,并在Kibana优雅分析日志? 疑问:既然应用能直接向ElasticSearch写日志,为什么我们还需要Logstash,Fluentd等日志摄取器?而且这 ...

  2. 如何利用NLog输出结构化日志,并在Kibana优雅分析日志?

    上文我们演示了使用NLog向ElasticSearch写日志的基本过程(输出的是普通文本日志),今天我们来看下如何向ES输出结构化日志.在Kibana中分析日志. 什么是结构化日志? 当前互联网.物联 ...

  3. HttpClientFactory日志不好用,自己扩展一个?

    前言 .NetCore2.1新推出HttpClientFactory工厂类, 替代了早期的HttpClient,并新增了弹性Http调用机制 (集成Policy组件). 替换的初衷还是简单说下: ①  ...

  4. 基于Spring Aop及log4j2的MDC实现全链路调用跟踪(traceid)

    环境: Springboot:2.2.3.RELEASE Spring-boot-starter-log4j2: 2.2.2.RELEASE jdk:1.8 目标: 实现Springboot框架下的全 ...

  5. MybatisPlus忽略实体类中的非数据库字段、JPA忽略实体类中的非数据库字段、HeHibernate忽略实体类中的非数据库字段

    mybatis plus忽略映射字段时可以在实体类属性上使用以下注解: @TableField(exist = false):表示该属性不为数据库表字段,但又是必须使用的. @TableField(e ...

  6. SVN优化(一) SVN忽略maven项目的target

    SVN优化(一) SVN忽略maven项目的target 一 eclipse刚开始导入的项目: 二  解决办法 方式一: 在项目代码路径,如: F:\xyx\sl  鼠标右键,"Tortoi ...

  7. Python:numpy实现生成随机数,忽略warnings

    ''' 作者:Dust ''' # 生成随机数:numpy下的random import numpy as npy import warnings warnings.filterwarnings(&q ...

  8. Android studio 设置忽略文件

    这个是android stuido 之前的版本设置的方法,最新的版本里面方法变了 还是使用.ignore 文件设置忽略文件比较好些 .ignore 设置忽略文件查看. 点击File-->sett ...

  9. Android 使用git 忽略文件

    git 使用的是.ignore 忽略文件的 下面是github上面的android 使用的忽略文件修改了部分 可以直接复制到项目中使用 ,如果有特殊的添加即可 # Built application ...

最新文章

  1. 计算机笔试图形推理题,【笔记】教资笔试丨4分钟掌握信息处理以及逻辑判断!...
  2. Navicat Monitor v1.7的新功能说明
  3. 为啥JAVA虚拟机不开发系统_理解Java虚拟机体系结构
  4. 四旋翼双环PID控制
  5. 关于android中的ramdisk.img及uImage无法包含驱动模块(*.ko)的问题
  6. 逼疯一个程序员有多简单?
  7. python操作mysql时mysqldb和pymysql的安装和使用
  8. 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1](简单易懂)
  9. 揭穿内存厂家“谎言”,实测内存带宽真实表现
  10. CnOpenData中国工业企业股东信息数据
  11. native mysql 分区_MySQL-表分区
  12. Linux中断(interrupt)子系统之三:中断流控处理层(转)
  13. C语言:甲乙丙丁分糖
  14. STM32L476入坑-2-STM32CubeMX安装
  15. python模拟登录钉钉,Python—实现钉钉后台开发,
  16. 【腾讯云的1001种玩法】几种在腾讯云建立WordPress的方法(Linux)(二)
  17. 后端日志【11】:回归自我,负重前行
  18. gerrit安装配置(http反向代理)
  19. 学生会工作必备计算机知识,必备学生会工作总结范文合集九篇
  20. AutoCAD入门——常用指令

热门文章

  1. macbook 下载时睡眠_MacBook进入睡眠状态时如何自动使其静音
  2. php 执行文件tar打包,利用tar for windows对大量文件进行快速打包
  3. HTML5程序开发范例宝典 完整版 (韩旭等著) 中文pdf扫描版
  4. 一个简单的MVC模式练习
  5. MongoDB基本操作(增删改查)
  6. 一次面试引发的思考(中小型网站优化思考) (转)
  7. 彻底搞定C指针-函数名与函数指针[转]
  8. 修炼九阴真经Windows Phone开发 (7):本地化应用程序栏Localizing an Application Bar 下...
  9. XenServer XAPI简介
  10. Spring4Shell的漏洞原理分析