如何使用Serilog.AspNetCore记录ASP.NET Core3.0的MVC属性
2021-04-22 10:29
标签:描述 state tps res sharp ini 应用程序 prope control 这是Serilog系列的第三篇文章。 作者:依乐祝 译文地址:https://www.cnblogs.com/yilezhu/p/12243984.html 原文地址:https://andrewlock.net/using-serilog-aspnetcore-in-asp-net-core-3-logging-mvc-propertis-with-serilog/ 在我上篇文章中,我描述了如何配置Serilog的RequestLogging中间件以向Serilog的请求日志摘要中添加其他属性(例如请求主机名或选定的端点名称)。这些属性都在 其他属性,例如MVC特定的功能,像操作方法ID,RazorPages处理程序名称或ModelValidationState,仅在MVC上下文中可用,因此Serilog的中间件不能直接访问。 在本文中,我将展示如何创建 Serilog的创建者Nicholas Blumhardt之前已经解决了这个话题。解决方案非常相似,尽管他在他的示例中创建了一个特性,您可以使用该特性来装饰actions/controllers。我在本文中跳过了这种方法,并要求将其全局应用,我希望这将是常见的解决方案。 就目前而言,ASP.NET Core中的一个特征是许多行为被MVC“基础结构”锁定在了MVC框架内部来实现。端点路由是采用MVC功能并将其下移到核心框架中的首要工作之一。ASP.NET Core团队一直在努力将更多MVC特定功能(例如模型绑定或操作结果)从MVC中移除,然后“下推”到核心框架中。有关此内容的更多信息,请参见Ryan Nowak在NDC上对Houdini项目的讨论。 但是,就目前情况而言,MVC内仍然存在一些不容易从应用程序其他部分访问的特性。当我们考虑到我们的Serilog的请求记录中间件的时候,这意味着有些属性我们也是不容易记录的。例如: 在上一篇文章中我展示了如何使用RequestLogging中间件的扩展方法通过使用 过滤器相当于为每个请求运行的类似于MVC的微型中间件管道。.NET Core MVC中有多种类型的过滤器,每种类型的过滤器在MVC过滤器管道中的有着不同的用途(有关更多详细信息,请参见此文章)。在本文中,我们将使用最常见的过滤器之一,即Action过滤器。 Action过滤器在执行MVC操作方法之前和之后运行。他们可以访问许多MVC属性的值,例如正在执行的Action及其将被调用的参数。 下面的Action过滤器直接实现 在将MVC服务添加到应用程序中时,可以在以下位置全局注册过滤器 无论你使用 有了这个配置之后,如果你调用一个MVC控制器,你在Serilog的请求日志消息中会看到额外的数据( 您可以在此处将所需的任何其他数据添加到日志中。只需注意记录参数值-切记不要记录敏感或个人身份信息! Nicholas Blumhardt在他的帖子中建议的Action过滤器是从 如果要记录其他集中MVC过滤器中的值,则可以以相同的方式实现其他过滤器,例如资源过滤器,结果过滤器或授权过滤器。 上面实现的 页面过滤器直接类似于Action过滤器,但它们仅适用于Razor页面。以下示例从 请注意,我们之前编写的 接下来,您需要在 添加过滤器后,对“Razor页面”的请求现在可以看到添加的附加属性, 默认情况下,当用Serilog的请求日志记录中间件替换ASP.NET Core基础结构中的日志记录时,您会丢失一些信息(与开发环境的默认配置相比)。在本文中,我将展示如何自定义Serilog, 要将与MVC相关的属性添加到Serilog请求日志中,请创建一个 下一节让我们一起探讨下如何从Serilog请求记录中排除运行状况检查端点。 如何使用Serilog.AspNetCore记录ASP.NET Core3.0的MVC属性 标签:描述 state tps res sharp ini 应用程序 prope control 原文地址:https://www.cnblogs.com/yilezhu/p/12243984.html
HttpContext
中可用,因此可以由中间件本身直接添加。action/page
过滤器来为您记录这些属性,以便中间件可以在后续创建日志时访问。
记录来自MVC的其他信息
OnGet
)1fbc88fa-42db-424f-b32b-c2d0994463f1
)MyController.SomeApiMethod (MyTestApp)
){action = "SomeApiMethod", controller = "My", page = ""}
)True
/ False
)IDiagnosticContext
将附加属性写入Serilog的请求日志中。这也仅适用于在HttpContext
可用的值。在这篇文章中,我将展示如何在过滤器中使用IDiagnosticContext
,以及将MVC特定值添加到日志中。我还将展示如何在page过滤器中添加RazorPages特定的值(如HandlerName
)。使用自定义过滤器记录MVC属性
IActionFilter
。该OnActionExecuting
方法在调用action方法之前被调用,并将额外的MVC特定属性添加到通过构造函数传入的IDiagnosticContext
中。public class SerilogLoggingActionFilter : IActionFilter
{
private readonly IDiagnosticContext _diagnosticContext;
public SerilogLoggingActionFilter(IDiagnosticContext diagnosticContext)
{
_diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
}
public void OnActionExecuting(ActionExecutingContext context)
{
_diagnosticContext.Set("RouteData", context.ActionDescriptor.RouteValues);
_diagnosticContext.Set("ActionName", context.ActionDescriptor.DisplayName);
_diagnosticContext.Set("ActionId", context.ActionDescriptor.Id);
_diagnosticContext.Set("ValidationState", context.ModelState.IsValid);
}
// Required by the interface
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
Startup.ConfigureServices()
:public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(opts =>
{
opts.Filters.Add
AddControllers
,AddControllersWithViews
,AddMvc
,或AddMvcCore
的方式你都可以采用同样的方式来添加全局过滤器。ActionName
,ActionId
,和RouteData
,ValidationState
)记录:
ActionFilterAttribute
派生的,因此可以将其直接用作控制器和Action的特性。不幸的是,这意味着您必须使用服务定位来从每个请求的HttpContext
中检索单例的IDiagnosticContext
。我的方法可以改用构造函数注入,但是不建议将其用作属性,因此必须如上所述全局使用。而且,MVC将在我的实现中使用作用域生存期,而不是单例,因此它会在每个请求中创建一个新实例。使用自定义page过滤器记录RazorPages属性
IActionFilter
过滤器在MVC和API控制器上能够正常运行,但它不会对RazorPages起作用。如果要为选择的给定Razor页面记录HandlerName,则需要创建一个自定义的IPageFilter
。PageHandlerSelectedContext
中检索处理程序名称并将其记录为属性RazorPageHandler
。在这种情况下,还需要一些样板代码,但过滤器的功能还是非常基础的-调用IDiagnosticContext.Set()
以记录属性。 public class SerilogLoggingPageFilter : IPageFilter
{
private readonly IDiagnosticContext _diagnosticContext;
public SerilogLoggingPageFilter(IDiagnosticContext diagnosticContext)
{
_diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
}
//Required by the interface
public void OnPageHandlerExecuted(PageHandlerExecutedContext context)
{
}
public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
{
}
public void OnPageHandlerSelected(PageHandlerSelectedContext context)
{
var name = context.HandlerMethod?.Name ?? context.HandlerMethod?.MethodInfo.Name;
if (name != null)
{
_diagnosticContext.Set("RazorPageHandler", name);
}
}
}
IActionFilter
代码不会在Razor Pages上运行,因此,如果您也想记录RazorPages RouteData
或ValidationState
RazorPages的其他详细信息,则也需要在此处添加它。该context
属性包含您可能需要的大多数属性,例如ModelState
和ActionDescriptor
。Startup.ConfigureServices()
方法中注册页面过滤器: public void ConfigureServices(IServiceCollection services)
{
//services.AddMvcCore(
// opts => opts.Filters.Add
IDiagnosticContext
这些属性将添加到Serilog请求日志中。请参见下图中的RazorPageHandler
属性:总结
RequestLoggingOptions
以重新添加特定于MVC的其他属性。IActionFilter
并使用IDiagnosticContext.Set()
来添加属性。要将与Razor页面相关的属性添加到Serilog请求日志中,请在IPageFilter
中使用IDiagnosticContext
的相同方法创建和添加属性。
文章标题:如何使用Serilog.AspNetCore记录ASP.NET Core3.0的MVC属性
文章链接:http://soscw.com/essay/78042.html