最近我已经将Serilog配置为与ASP.NET Core 2 MVC应用程序配合使用,接下来的任务是在系统的每一层上跟踪传入的Web应用程序请求。基本上,我们希望传播一些令牌(如Serilog生成的RequestId
到更低层的应用程序)。
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.RollingFile" ],
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning"
}
},
"WriteTo": [
{
"Name": "RollingFile",
"Args": {
"pathFormat": "log-{Hour}.txt",
"fileSizeLimitBytes": "",
"retainedFileCountLimit": "",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Application}] [{Level}] [{RequestId}] - {Message}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"Properties": {
"Application": "MultilayerApp"
}
},
在日志中我们有很好的输入,比如
2018-01-19 14:06:01.165 +00:00 [App] [Warning] [0HLAV6PIMA9M0:00000001] - Accessing expired session, Key:"6e7f3ab5-db62-335d-1bc7-6824e5b918f5"
但我的问题是Serilog在RequestId
实现更丰富的地方?老实说,我找不到它。
答案 0 :(得分:13)
在ASP.NET Core中,某些记录器公开的RequestId
是HttpContext
上TraceIdentifier
的值。可以在整个应用程序中使用此属性来标识当前请求。
出于记录目的,回退到HttpContext
不是可行的方法。 Microsoft.Extensions.Logging
抽象支持logging scopes,这是为在该范围内应用的记录器提供附加信息的一种方式。
默认情况下,ASP.NET Core会打开两个日志记录范围。其中一个是HostingLogScope
被打开at the beginning of every request(如果至少启用了关键日志记录)。
记录器可以通过实现BeginScope
method来访问信息,does pretty much the same在每个请求开始时传递给它的HostingLogScope
对象,并简单地迭代对象直到找到属性:
string requestId = null;
if (state is IEnumerable<KeyValuePair<string, object>> properties)
{
foreach (var property in properties)
{
if (property.Key == "RequestId")
{
requestId = property.Value as string;
}
}
}
Serilog in the log event但存储了所有属性{{3}}。这就是为什么你没有找到RequestId
的明确引用,但是当你指定包含它的日志字符串格式时它仍然存在。