被忽略的TraceId,可以用起来了

前言

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312845.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCP协议详解

一、TCP协议简介 TCP协议&#xff0c;即传输控制协议&#xff08;Transmission Control Protocol&#xff09;&#xff0c;是一种面向连接的、可靠的、基于字节流的传输层通信协议。在因特网协议族中&#xff0c;TCP层是位于IP层之上&#xff0c;应用层之下的中间层。尽管IP层只…

UDP协议详解

一、UDP协议简介 UDP协议&#xff0c;即用户数据报协议&#xff08;User Datagram Protocol&#xff09;&#xff0c;是一个简单的面向数据报的传输层协议。UDP协议只在IP数据报服务商增加了很少一点的功能&#xff0c;就是复用和分用&#xff0c;以及差错检测的功能。 二、UDP…

冰雪奇缘,白色世界:四个IT人的四姑娘山双桥沟游记

去年9月初去了川西的稻城亚丁&#xff0c;体会了金色世界秋日童话&#xff0c;还写了一篇游记《从你的全世界路过-一群程序员的稻城亚丁游记》&#xff0c;也是得到了很多朋友和童鞋的点赞。今年11月初趁着周末的两天时间和朋友去了川西的四姑娘山&#xff0c;体会了白色世界冰…

TCP三次握手建立连接

一、三次握手的过程 TCP需要三次握手才能建立连接&#xff0c;整个过程如下图所示&#xff1a; 假设A运行的是TCP客户端进程&#xff0c;而B运行的是TCP服务端进程。最开始的时候两端的TCP进程都处于ClOSED&#xff08;关闭&#xff09;状态。 这时候&#xff0c;A主动打开连接…

[原]排错实战——通过对比分析sysinternals事件修复程序功能异常

缘起 最近&#xff0c;我们程序的某个功能在一台机器上不正常&#xff0c;但是在另外一台机器上却是正常的。代码是同一份&#xff0c;vs版本也一样&#xff08;打的补丁也一样&#xff09;。编译出来的程序在两台电脑上运行的结果就是不一样。惊不惊喜&#xff0c;意不意外&am…

[原]windbg调试系列——崩溃在ComFriendlyWaitMtaThreadProc

前言 这是几年前在项目中遇到的一个崩溃问题&#xff0c;崩溃在了ComFriendlyWaitMtaThreadProc()里。没有源码&#xff0c;耗费了我很大精力&#xff0c;最终通过反汇编并结合原代码才最终搞清楚了事情的来龙去脉。本文的分析是基于真实项目进行的&#xff0c;中间略去了很多反…

TCP四次握手释放连接

一、四次握手的过程 TCP需要三次握手才能建立连接&#xff0c;整个过程如下图所示&#xff1a; 假设A运行的是TCP客户端进程&#xff0c;而B运行的是TCP服务端进程。最开始的时候两端的TCP进程都处于ESTABLISHED&#xff08;已建立连接&#xff09;状态。 这时候&#xff0c;A…

开源WPF控件库MaterialDesignInXAML推荐

今天介绍一个开源的C# WPF开源控件库&#xff0c;非常漂亮&#xff0c;重点是开源哦WPF做桌面开发是很有优势的&#xff0c;除了微软自带的控件外&#xff0c;还有很多第三方的控件库&#xff0c;比如收费的Dev Express For WPF、Telerik For WPF等&#xff0c;及Github上开源免…

TCP连续ARQ协议和滑动窗口协议

TCP协议通过使用连续ARQ协议和滑动窗口协议&#xff0c;来保证数据传输的正确性&#xff0c;从而提供可靠的传输。 一、ARQ协议 ARQ协议&#xff0c;即自动重传请求&#xff08;Automatic Repeat-reQuest&#xff09;&#xff0c;是OSI模型中数据链路层和传输层的错误纠正协议之…

ASP.NET Core 集成测试中模拟登录用户的一种姿势

不管哪种用户验证方式&#xff0c;最终都是在验证成功后设置 HttpContext.User &#xff0c;后续处理环节通过 HttpContext.User 获取用户信息。如果能直接修改 HttpContext.User &#xff0c;就能达到模拟登录的目的&#xff0c;而 ASP.NET Core 的中间件&#xff08;middlewa…

【NServiceBus】什么是Saga,Saga能做什么

前言Saga单词翻译过来是指尤指古代挪威或冰岛讲述冒险经历和英雄业绩的长篇故事&#xff0c;对&#xff0c;这里强调长篇故事。许多系统都存在长时间运行的业务流程&#xff0c;NServiceBus使用基于事件驱动的体系结构将容错性和可伸缩性融入这些业务处理过程中。 当然…

数据一致性基本知识

在分布式系统中&#xff0c;我们经常提及CAP定理&#xff0c;即一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;和分区容忍性&#xff08;Partition tolerance&#xff09;。在本文中&#xff0c;我们将对数据一致性这一知识进行基本回…

分享一次与SharpDX坑爹Bug刚正面的过程

和SharpDX坑爹的Variant刚正面几个月前我写了这篇文章《.NET中生成动态验证码》文章&#xff0c;其实里面藏着一个大坑。运行里面的代码&#xff0c;会发现运行的 gif图片并没有循环播放&#xff1a; 细心的网友也注意到了这个问题&#xff1a;……但后来他备注说“已解决”&am…

EF Core 3.0查询

随着.NET Core 3.0的发布&#xff0c;EF Core 3.0也随之正式发布&#xff0c;关于这一块最近一段时间也没太多去关注&#xff0c;陆续会去对比之前版本有什么变化没有&#xff0c;本节我们来看下两个查询。分组我们知道在EF Core 3.0版本之前&#xff0c;对于分组查询是在客户端…

经典排序算法(1)——冒泡排序算法详解

冒泡排序&#xff08;Bubble Sort&#xff09;是一种典型的交换排序算法&#xff0c;通过交换数据元素的位置进行排序。 一、算法基本思想 &#xff08;1&#xff09;基本思想 冒泡排序的基本思想就是&#xff1a;从无序序列头部开始&#xff0c;进行两两比较&#xff0c;根据…

C++模版和C#泛型求同存异录(一)sizeof(T)

sizeof(T)从C的模板代码往C#代码移植的时候发现了一个小问题。在C模板代码中 sizeof(T)是一种有效的写法&#xff0c;最终在会编译器展开成sizeof(int),sizeof(float)或者sizeof(myclass),然后在运行时这个代码是有效的&#xff0c;能够执行的。于是我们看上去就可以计算在运行…

经典排序算法(2)——快速排序算法详解

快速排序&#xff08;Quick Sort&#xff09;也是一种典型的交换排序算法&#xff0c;通过交换数据元素的位置进行排序。 一、算法基本思想 &#xff08;1&#xff09;基本思想 快速排序的基本思想就是&#xff1a;通过一趟排序将要排序的数据分割成独立的两部分&#xff0c;其…

经典排序算法(3)——直接插入排序算法详解

直接插入排序&#xff08;Insertion Sort&#xff09;是一种插入排序算法&#xff0c;通过不断地将数据元素插入到合适的位置进行排序。 一、算法基本思想 &#xff08;1&#xff09;基本思想 直接插入排序的基本思想是&#xff1a;顺序地把待排序的序列中的各个元素按其关键字…

[ASP.NET Core 3框架揭秘] 异步线程无法使用IServiceProvider?

标题反映的是上周五一个同事咨询我的问题&#xff0c;我觉得这是一个很好的问题。这个问题有助于我们深入理解依赖注入框架在ASP.NET Core中的应用&#xff0c;以及服务实例的生命周期。一、问题重现我们通过一个简单的实例来模拟该同事遇到的问题。我们采用极简的方式创建了如…

经典排序算法(4)——折半插入排序算法详解

折半插入排序&#xff08;Binary Insertion Sort&#xff09;是一种插入排序算法&#xff0c;通过不断地将数据元素插入到合适的位置进行排序&#xff0c;在寻找插入点时采用了折半查找。 一、算法基本思想 &#xff08;1&#xff09;基本思想 折半插入排序的基本思想是&#x…