如何使用Serilog.AspNetCore记录ASP.NET Core3.0的MVC属性

栏目: IT技术 · 发布时间: 4年前

内容简介:这是Serilog系列的第三篇文章。作者:依乐祝译文地址:

这是Serilog系列的第三篇文章。

  1. 第1部分-使用Serilog RequestLogging减少日志详细程度
  2. 第2部分-使用Serilog记录所选的终结点属性
  3. 第3部分-使用Serilog.AspNetCore记录MVC属性(本文)
  4. 第4部分-从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的请求日志摘要中添加其他属性(例如请求主机名或选定的端点名称)。这些属性都在 HttpContext 中可用,因此可以由中间件本身直接添加。

其他属性,例如MVC特定的功能,像操作方法ID,RazorPages处理程序名称或ModelValidationState, 在MVC上下文中可用,因此Serilog的中间件不能直接访问。

在本文中,我将展示如何创建 action/page 过滤器来为您记录这些属性,以便中间件可以在后续创建日志时访问。

Serilog的创建者Nicholas Blumhardt之前已经解决了这个话题 。解决方案非常相似,尽管他在他的示例中创建了一个特性,您可以使用该特性来装饰 actions/controllers 。我在本文中跳过了这种方法,并要求将其全局应用,我希望这将是常见的解决方案。

记录来自MVC的其他信息

就目前而言,ASP.NET Core中的一个特征是许多行为被MVC“基础结构”锁定在了MVC框架内部来实现。端点路由是采用MVC功能并将其下移到核心框架中的首要工作之一。ASP.NET Core团队一直在努力将更多MVC特定功能(例如模型绑定或操作结果)从MVC中移除,然后“下推”到核心框架中。 有关此内容的更多信息,请参见Ryan Nowak在NDC上对Houdini项目的讨论

但是,就目前情况而言,MVC内仍然存在一些不容易从应用程序其他部分访问的特性。当我们考虑到我们的 Serilog的请求记录中间件 的时候,这意味着有些属性我们也是不容易记录的。例如:

  • HandlerName( OnGet
  • ActionId( 1fbc88fa-42db-424f-b32b-c2d0994463f1
  • ActionName ( MyController.SomeApiMethod (MyTestApp)
  • RouteData( {action = "SomeApiMethod", controller = "My", page = ""}
  • ValidationState( True / False

在上一篇文章中我展示了如何使用RequestLogging中间件的扩展方法通过使用 IDiagnosticContext 将附加属性写入Serilog的请求日志中。这也仅适用于在 HttpContext 可用的值。在这篇文章中,我将展示如何在 过滤器中 使用 IDiagnosticContext ,以及将MVC特定值添加到日志中。我还将展示如何在 page过滤器 中添加RazorPages特定的值(如 HandlerName )。

使用自定义过滤器记录MVC属性

过滤器相当于为每个请求运行的类似于MVC的微型中间件管道。.NET Core MVC中有多种类型的过滤器,每种类型的过滤器在MVC过滤器管道中的有着不同的用途( 有关更多详细信息,请参见此文章 )。在本文中,我们将使用最常见的过滤器之一,即Action过滤器。

Action过滤器在执行MVC操作方法之前和之后运行。他们可以访问许多MVC属性的值,例如正在执行的Action及其将被调用的参数。

下面的Action过滤器直接实现 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)
        {

        }
    }

在将MVC服务添加到应用程序中时,可以在以下位置全局注册过滤器 Startup.ConfigureServices()

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(opts =>
    {
        opts.Filters.Add<SerilogLoggingPageFilter>();
    });
    // ... other service registration
}

无论你使用 AddControllersAddControllersWithViewsAddMvc ,或 AddMvcCore 的方式你都可以采用同样的方式来添加全局过滤器。

有了这个配置之后,如果你调用一个MVC控制器,你在Serilog的请求日志消息中会看到额外的数据( ActionNameActionId ,和 RouteDataValidationState )记录:

如何使用Serilog.AspNetCore记录ASP.NET Core3.0的MVC属性

您可以在此处将所需的任何其他数据添加到日志中。只需注意记录参数值-切记不要记录敏感或个人身份信息!

Nicholas Blumhardt在他的帖子中建议 的Action过滤器是从 ActionFilterAttribute 派生的,因此可以将其直接用作控制器和Action的特性。不幸的是,这意味着您必须使用服务定位来从每个请求的 HttpContext 中检索单例的 IDiagnosticContext 。我的方法可以改用构造函数注入,但是不建议将其用作属性,因此必须如上所述全局使用。而且,MVC将在我的实现中使用作用域生存期,而不是单例,因此它会在每个请求中创建一个新实例。

如果要记录其他集中MVC过滤器中的值,则可以以相同的方式实现其他过滤器,例如资源过滤器,结果过滤器或授权过滤器。

使用自定义page过滤器记录RazorPages属性

上面实现的 IActionFilter 过滤器在MVC和API控制器上能够正常运行,但它 不会 对RazorPages起作用。如果要为选择的给定Razor页面记录HandlerName,则需要创建一个自定义的 IPageFilter

页面过滤器直接类似于Action过滤器,但它们仅适用于Razor页面。以下示例从 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 RouteDataValidationState RazorPages的其他详细信息,则也需要在此处添加它。该 context 属性包含您可能需要的大多数属性,例如 ModelStateActionDescriptor

接下来,您需要在 Startup.ConfigureServices() 方法中注册页面过滤器:

public void ConfigureServices(IServiceCollection services)
        {
            //services.AddMvcCore(
            //    opts => opts.Filters.Add<SerilogLoggingPageFilter>()
            //    );
            services.AddRazorPages().AddMvcOptions(
                opts => opts.Filters.Add<SerilogLoggingPageFilter>()
                ) ;
        }

添加过滤器后,对“Razor页面”的请求现在可以看到添加的附加属性, IDiagnosticContext 这些属性将添加到Serilog请求日志中。请参见下图中的 RazorPageHandler 属性:

如何使用Serilog.AspNetCore记录ASP.NET Core3.0的MVC属性

总结

默认情况下,当用Serilog的请求日志记录中间件替换ASP.NET Core基础结构中的日志记录时,您会丢失一些信息(与开发环境的默认配置相比)。在本文中,我将展示如何自定义Serilog, RequestLoggingOptions 以重新添加特定于MVC的其他属性。

要将与MVC相关的属性添加到Serilog请求日志中,请创建一个 IActionFilter 并使用 IDiagnosticContext.Set() 来添加属性。要将与Razor页面相关的属性添加到Serilog请求日志中,请在 IPageFilter 中使用 IDiagnosticContext 的相同方法创建和添加属性。

下一节让我们一起探讨下如何从Serilog请求记录中排除运行状况检查端点。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据化管理

数据化管理

黄成明 (@数据化管理) / 电子工业出版社 / 2014-7 / 59.90元

《数据化管理:洞悉零售及电子商务运营》讲述了两个年轻人在大公司销售、商品、电商、数据等部门工作的故事,通过大量案例深入浅出地讲解了数据意识和零售思维。作者将各种数据分析方法融入到具体的业务场景中,最终形成数据化管理模型,从而帮助企业提高运营管理能力。 《数据化管理:洞悉零售及电子商务运营》全部案例均基于Excel,每个人都能快速上手应用并落地。一起来看看 《数据化管理》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

SHA 加密
SHA 加密

SHA 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具