C# .NET Core Serilog用户名始终为空
我添加这个中间件是为了将用户名添加到日志中,但是,它总是显示为null 这是中间件C# .NET Core Serilog用户名始终为空,c#,asp.net-core,serilog,C#,Asp.net Core,Serilog,我添加这个中间件是为了将用户名添加到日志中,但是,它总是显示为null 这是中间件 private readonly RequestDelegate next; public LogUserName(RequestDelegate next) { this.next = next; } public async Task InvokeAsync(HttpContext context) { LogContext.Push
private readonly RequestDelegate next;
public LogUserName(RequestDelegate next)
{
this.next = next;
}
public async Task InvokeAsync(HttpContext context)
{
LogContext.PushProperty("UserName", context.User.Identity.Name);
await next(context);
//return next(context);
}
我在Program.cs和Startup.cs中这样称呼它
Program.cs
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.Enrich.FromLogContext()
.Filter.ByExcluding(Matching.FromSource("Microsoft"))
.Filter.ByExcluding(Matching.FromSource("System"))
.CreateLogger();
Startup.cs
app.UseAuthentication();
app.UseMiddleware<LogUserName>();
app.UseAuthentication();
app.UseMiddleware();
我注意到,当我硬编码一个属性时,它会出现在我的日志中的properties标签下。例如
LogContext.PushProperty("UserName", "Test");
<properties><property key='SourceContext'>AAAA.Areas.Identity.Pages.Account.LoginModel</property><property key='ActionId'>e477aa96-f0b5-4790-9253-80fcbc72fbda</property><property key='ActionName'>/Account/Login</property><property key='RequestId'>0HLJ6EBJ4V6PP:00000002</property><property key='RequestPath'>/Identity/Account/Login</property><property key='CorrelationId'></property><property key='ConnectionId'>0HLJ6EBJ4V6PP</property><property key='UserName'>Test</property></properties>
LogContext.PushProperty(“用户名”、“测试”);
AAAA.Areas.Identity.Pages.Account.LoginModele477aa96-f0b5-4790-9253-80fcbc72fbda/Account/Login0HLJ6EBJ4V6PP:00000002/Identity/Account/Login0HLJ6EBJ4V6PPTest
另外,如果可能的话,我想把它从properties标签中带出来,放到它自己的字段中
我注意到,当我硬编码一个属性时,它会出现在我的日志中的properties标签下。例如,LogContext.PushProperty(“用户名”、“测试”)
试验
另外,如果可能的话,我想把它从properties标签中带出来,放到它自己的字段中
默认情况下,用于Serilog的MSSqlServer接收器会将其他属性以XML格式放入properties
列中。但是,有一种方法可以将某些属性移动到它自己的属性中。您可以使用代码进行配置,但由于您使用的是appsettings.json
,因此也可以在那里进行配置
配置应如下所示(此处缩短配置以仅显示相关部分):
默认情况下,该列配置为varchar
,因此它应该适用于您的字符串值
要正确填充自定义属性,请参见以下问题:
- (用于一般情况下使用Serilog)
- (使用ASP.NET Core 1.x,但仍应给出总体思路)
在聊天中建议以下内容: 根据您目前的解释,我想知道您是否希望在消息中看到
UserName
,该消息是作为实际登录您的请求的一部分记录的。如果您预期会出现这种情况,则不会出现这种情况,因为LogContext.PushProperty
调用发生在您调用类似于PasswordSignInAsync
的内容之前(假设您使用的是Identity)
如果这确实是您的情况,那么您应该知道设置自定义属性的中间件在任何控制器逻辑运行之前正在运行。因此,自定义属性是在登录完成之前设置的,因此,在中间件运行时,添加了一个空用户名作为自定义属性。因此,这种行为是完全正确的。只有在后续请求中,身份验证中间件才能在中间件运行之前对用户进行身份验证,以便在日志输出中看到正确的用户名
这并不是一个好办法。当然,您可以在用户登录时再次显式设置自定义属性。但是我建议您不要这样做,因为从技术上讲,请求仍然是在没有任何身份验证的情况下调用的,因此没有用户名应该不会有问题。只是为了澄清问题所在:将用户名记录在Serilog日志中通常有效吗?例如,当您在中间件内部设置一些静态值时,它是否正常工作?但是当执行中间件时,
context.User.Identity.Name
为空,您可以从调试中看到这一点吗?您是否真的登录并能够在其他地方(例如控制器内部)看到非空名称?不,它根本不起作用。当我登录时,我知道context.User.Identity.Name不是空的,因为我的名字出现在菜单上。然而,我认为这对记录器来说太晚了。对不起,这并不能真正回答我的问题。您能否验证您的中间件是否已执行,以及是否在中间件中设置了context.User.Identity.Name
(即,使用调试器来解决这一问题)。或者使用LogContext.PushProperty(“用户名”、“测试”)
并检查您的日志是否包含Test
作为用户名您在这里有两个不同的问题(Serilog日志记录和访问经过身份验证的用户),我们不知道这两个问题中的哪一个真正适合您;它仍然显示为空。这很奇怪。好吧,所以Serilog日志一般不起作用。你能展示一下你是如何用ASP.NET内核建立Serilog的吗?也就是说,不仅仅是您如何创建记录器,还包括您如何使用记录器?
"Serilog": {
"WriteTo": [
{
"Name": "MSSqlServer",
"Args": {
"connectionString": "…",
"schemaName": "AnalyticsStudio",
"tableName": "EventLogs",
"columnOptionsSection": {
"additionalColumns": [
{ "ColumnName": "UserName" }
]
}
}
}
]
}