Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 读取并传播旧ASP.NET 4.8中的TraceId_C#_Asp.net - Fatal编程技术网

C# 读取并传播旧ASP.NET 4.8中的TraceId

C# 读取并传播旧ASP.NET 4.8中的TraceId,c#,asp.net,C#,Asp.net,我正在维护几个用ASP.NET4.8(完整框架)和ASP.NETCore编写的应用程序 .NETCore实现了这样的功能,我可以查看我的日志(我使用Serilog进行结构化日志记录),它丰富了ParentId、SpanId和最重要的TraceId 有没有办法在旧的ASP.NET 4.8应用程序中读取和传播TraceId 我的应用程序在彼此之间执行大量请求,这将极大地改善调试体验。不幸的是,大多数请求都源于旧的ASP.NET 4.8应用程序,并转到较新的.NET核心应用程序 理想情况下,我希望达到

我正在维护几个用ASP.NET4.8(完整框架)和ASP.NETCore编写的应用程序

.NETCore实现了这样的功能,我可以查看我的日志(我使用Serilog进行结构化日志记录),它丰富了ParentId、SpanId和最重要的TraceId

有没有办法在旧的ASP.NET 4.8应用程序中读取和传播TraceId

我的应用程序在彼此之间执行大量请求,这将极大地改善调试体验。不幸的是,大多数请求都源于旧的ASP.NET 4.8应用程序,并转到较新的.NET核心应用程序

理想情况下,我希望达到与ASP.NET核心应用程序相同的状态—如果请求Id来自HTTP头,则使用它并将其填充到ParentId和TraceId中,并基于此生成SpanId。此外,它还会进一步传播到源自.NET核心应用程序的其他HTTP请求


谢谢

好吧,我自己解决了

首先,需要添加
System.Diagnostics.DiagnosticSource
nugget包

然后,创建
ActivityManager
类:

公共静态类活动管理器
{
公共静态void StartActivity()
{
如果(Activity.Current==null)
{
var活动=新活动(“默认活动”);
字符串parentIdFromHeaders=HttpContext.Current?.Request.Headers[GetRequestIdHeaderName()];
如果(!string.IsNullOrEmpty(parentIdFromHeaders))
{
activity.SetParentId(parentIdFromHeaders);
}
activity.Start();
活动。当前=活动;
//有时我会遇到活动方面的问题。即使我设置了当前活动,它仍然是空的
//因此,为了确保这一点,我还将其添加到HttpContext项中。
HttpContext.Current?.Items.Add(“活动”,活动);
}
}
公共静态void StopActivity()
{
GetActivity()?.Stop();
}
公共静态活动GetActivity()
{
活动活动=活动.Current???(活动)HttpContext.Current.Items[“活动”];
返回活动;
}
公共静态字符串GetRequestIdHeaderName()
{
返回“请求Id”;
}
公共静态字符串GetRequestId()
{
Activity=GetActivity();
if(活动!=null)
{
字符串activityId=activity.Id;
返回活动ID;
}
//对于一些罕见的情况,当某些事情发生并且没有设置活动时
//首先尝试读取请求Id,如果没有,则创建新的GUID
返回HttpContext.Current?.Request.Headers.Get(GetRequestIdHeaderName())
??Guid.NewGuid().ToString().Replace(“-”,”);
}
}
并配置
Global.asax.cs
处理程序

受保护的无效应用程序\u Start()
{
Activity.DefaultIdFormat=ActivityIdFormat.Hierarchy;
}
受保护的无效应用程序_BeginRequest()
{
ActivityManager.StartActivity();
}
受保护的无效应用程序\u EndRequest()
{
ActivityManager.StopActivity();
}
现在,所有传入请求都会创建新的
活动
,并正确设置其
父ID

要将
SpanId
TraceId
ParentId
添加到日志上下文中,我创建了自定义日志充实器:

公共类TraceLogEnricher:ILogenerRicher
{
public void explore(LogEvent LogEvent,ILogEventPropertyFactory propertyFactory)
{
Activity=ActivityManager.GetActivity();
if(活动!=null)
{
字符串parentId=activity.parentId;
字符串rootId=activity.rootId;
字符串activityId=activity.Id;
AddPropertyIfAbsent(新的LogEventProperty(“SpanId”,新的ScalarValue(activityId));
AddPropertyFabSent(新的LogEventProperty(“ParentId”,新的ScalarValue(ParentId));
logEvent.AddPropertyIfAbsent(新的LogEventProperty(“TraceId”,新的ScalarValue(rootId));}
}
}
并使用
将其添加到Serilog配置中

最后一步是配置传出请求。在
HttpClient
中,使用
DefaultRequestHeaders
。(为了更方便,也可以在
IHttpClientFactory
配置中配置)

var requestId=ActivityManager.GetRequestId();
client.DefaultRequestHeaders.Add(“请求Id”,requestId);
如果使用web服务,最好将
请求Id
头也添加到web服务请求中。为此,重写web服务客户端的
GetWebRequest
方法。(它们通常作为分部类生成,因此在您自己的分部类文件中重写它)

受保护的覆盖WebRequest GetWebRequest(Uri)
{
var-request=base.GetWebRequest(uri);
Add(“请求Id”,ActivityManager.GetRequestId());
返回请求;
}