• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >ASP.NET > 详解ASP.NET Core应用中如何记录和查看日志

详解ASP.NET Core应用中如何记录和查看日志

作者:Artech 字体:[增加 减小] 来源:互联网 时间:2017-05-11

Artech通过本文主要向大家介绍了pro asp.net core mvc,asp core h5,asp core area,asp net培训,asp.net等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

日志记录不仅对于我们开发的应用,还是对于ASP.NET Core框架功能都是一项非常重要的功能特性。我们知道ASP.NET Core使用的是一个极具扩展性的日志系统,该系统由Logger、LoggerFactory和LoggerProvider这三个核心对象组成。我们可以通过简单的配置实现对LoggerFactory的定制,以及对LoggerProvider添加。

一、 配置LoggerFactory

我们在上面一节演示了一个展示ASP.NET Core默认注册服务的实例,细心的读者一定会看到显示的列表中就包含了针对LoggerFactory的服务。如果这个默认的LoggerFactory服务不能满足我们的需求,我们完全可以配置任何一个需要的LoggerFactory,针对LoggerFactory的设置可以直接调用WebHostBuilder的UseLoggerFactory方法来实现。

public interface IWebHostBuilder
  {
    IWebHostBuilder UseLoggerFactory(ILoggerFactory loggerFactory);
    IWebHostBuilder ConfigureLogging(Action<ILoggerFactory> configureLogging);
    ...
  }
</div>

不过针对日志的配置更多地还是体现在针对某种LoggerProvider的添加,而这可以通过调用WebHostBuilder的ConfigureLogging方法来完成。我们在上面演示的实例中就曾经采用如下的方式将一个ConsoleLoggerProvider注册到LoggerFactory之上,这样我们可以直接在宿主应用的扩展台上看到记录的日志信息。

 new WebHostBuilder()
    .ConfigureLogging(factory=>factory.AddConsole())
    ...
</div>

既然LoggerFactory已经作为一个服务进行了注册,那么我们完全按照依赖注入的来获取这个对象,并利用它创建对应的Logger对象来写日志。如果我们需要在一个定义的中间件中写入某种类型的日志,就可以按照如下的方式在Invoke方法中定义ILoggerFactory类型的参数注入这个LoggerFactory。

 public class FoobarMiddleware
  {
    private RequestDelegate _next;
   
    public FoobarMiddleware(RequestDelegate next)
    {
      _next = next;
    }
   
    public async Task Invoke(HttpContext context, ILoggerFactory loggerFactory)
    {
      ILogger<FoobarMiddleware> logger = loggerFactory.CreateLogger<FoobarMiddleware>();
      logger.LogInformation("...");
      await _next(context);
    }
  }
</div>

不仅仅我们开发的应用或者中间件可以利用注册的LoggerFactory来创建进行日志记录的Logger对象,ASP.NET Core管道本身也会在处理请求过程中采用相同的方式记录一些日志。比如管道每次处理请求的开始和结束时候分别会写入两条Information等级的日志,我们现在就来通过一个简单的实例看看这两条日志信息具有怎样的内容。

public class Program
  {
    public static void Main()
    {
      new WebHostBuilder()
        .ConfigureLogging(factory=>factory.AddConsole())
        .UseKestrel()
        .UseStartup<Startup>()        
        .Build()
        .Run();
    }
  }
  
  public class Startup
  {
    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
      app.Run(async context =>
      {
        loggerFactory.CreateLogger("App").LogInformation("Log entry for test...");
        await context.Response.WriteAsync("Hello world!");
      });
    }
  }
</div>

如上所示的代码有两处与日志有关,第一个地方是调用WebHostBuilder的ConfigureLogging方法通过调用扩展方法AddConsole将一个ConsoleProvider添加到当前LoggerFactory之上,另一个地方就是启动类的Configure方法注册的中间件在执行过程中会利用注入的LoggerFactory创建一个Logger对象,我们利用后者写入了一条Information等级的日志。我们运行程序之后利用浏览器访问目标地址后,宿主控制台上会出现如下图所示的三条日志。除了第二条日志是由我们自己编写的代码写入的之外,其余两条都是ASP.NET Core框架自己写入的。第一条日志包含不仅仅包含请求的目标地址,还包括请求采用的协议(HTTP/1.1)和HTTP方法(GET),第三条则反映了整个请求处理过程所花的时间。

由于ASP.NET Core管道对请求的处理总是在一个由HttpApplication创建的执行上下文中进行,所以上下文的创建和回收释放可以视为 整个请求处理流程开始和结束的标识。对于上述的这两条分别在处理请求开始和结束时写入的日志,实际上是在HostingApplication的CreateContext和DisposeContext方法分别被调用的时候被记录下来的。之所以在结束的时候能够计算出整个请求处理过程所花的时间,是因为创建的这个上下文对象保存了开始处理请求的时间戳,该时间戳对应着Context结构的StartTimestamp属性。

 public class HostingApplication IHttpApplication<HostingApplication.Context>
  {
    public struct Context
    {
      public HttpContext   HttpContext { get; set; }
      public IDisposable   Scope { get; set; }
      public long     StartTimestamp { get; set; }
    }
  }
</div>

二、以当前请求作为日志范围

我们知道日志系统有一个叫做“日志范围”的概念,它的目的在于为多次相关的日志记录创建一个上下文范围,并为这个范围提供一个唯一标识,这个标识会作为日志内容的一部分被写入。当我们在进行日志分析的时候,可以根据日志范围标识将一组原本独立的日志关联起来。这个概念对于Web应用尤为重要,因为很多情况下我们所做的日志分析都是针对某一个请求,这就要求我们必须明确地分辨出被记录下来的日志隶属于哪一个请求,只有这样才能将针对同一请求的所有日志提取出来做综合的分析以得出一个准确的结论。

从上个实例最终写入的三条日志来看,它们并不携带当前请求的标识信息。但是这不是ASP.NET Core的问题,而是我们在调用LoggerFactory的扩展方法AddConsole注册ConsoleLoggerProvider的时候并未显式开启针对日志范围的支持。为了让注册的ConsoleLoggerProvider创建的Logger能够支持日志范围,我们只需按照如下的方式在调用AddConsole方法的时候添加一个额外的参数(true)即可。

 new WebHostBuilder()
    .ConfigureLogging(factory=>factory.AddConsole(true))
    .UseKestrel()
    .UseStartup<Startup>()        
    .Build()
    .Run();
</div>

我们再次请求应用并利用浏览器对目标地址发送两次请求,六条写入的日志将会以如下图所示的形式输出到控制台上。不同于上面的输出结果,本次输出的日志包含请求的ID(Request Id),在同一个请求下被记录下来的日志具有相同的ID。除了请求ID,记录的日志还携带了请求的路径(Request Path)。

日志范围携带的用于唯一标识当前请求的ID,同时也可以视为当前HttpContext的唯一标识,它对应着HttpContext的TranceIdentifier属性。对于DefaultHttpContext来说,针对这个属性的读写是借助一个名为HttpRequestIdentifierFeature的特性实现的,下面的代码提供了该对象对应的接口IHttpRequestIdentifierFeature和默认实现类HttpRequestIdentifierFeature的定义。

public abstract class HttpContext
  {
    //省略其他成员
    public abstract string TraceIdentifier { get; set; }
  }
   
  public interface IHttpRequestIdentifierFeature
  {
    string TraceIdentifier { get; set; }
  }
  
  public class HttpRequestIdentifierFeature IHttpRequestIdentifierFeature
  {
    private string _id;
    private static long _requestId = DateTime.UtcNow.Ticks;
    private static unsafe string GenerateRequestId(long id);
    public string TraceIdentifier
    {
      get
      {
        return _id??(id= GenerateRequestId(Interlocked.Increment(ref _requestId)));
      }
      set
      {
        this._id = value;
      }
    }
  }
</div>

HttpRequestIdentifierFeature生成TraceIdentifier的逻辑很简单。如上面的代码片断所示,它具有一个静态长整型字段_requestId,其初始值为当前时间戳。对于某个具体的HttpRequestIdentifierFeature对象来说,它的TraceIdentifier属性的默认值返回的是这个字段_requestId加1之后转换的字符串。具体的转换逻辑定义在GenerateRequestId方法中,它会采用相应的算法 将指定的整数转换一个长度为13的字符串。

和开始请求处理的时间戳一样,被创建出来的日志范围实际被保存在HostingApplication的上下文对象中,它对应着Context结构的Scope属性。当HostingApplication创建这个Context对象的时候,它会从当前HttpContext中

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • ASP.NET Core发送邮件的方法
  • 在ASP.NET Core 中发送邮件的实现方法(必看篇)
  • Asp.net core WebApi 使用Swagger生成帮助页实例
  • ASP.NET core Web中使用appsettings.json配置文件的方法
  • ASP.NET Core部署前期准备 使用Hyper-V安装Ubuntu Server 16.10
  • ASP.NET Core应用中与第三方IoC/DI框架的整合
  • ASP.NET Core程序发布到Linux生产环境详解
  • 详解ASP.NET Core 网站发布到Linux服务器
  • ASP.NET Core全面扫盲贴
  • 基于ASP.NET Core数据保护生成验证token示例

相关文章

  • 2017-05-11asp.net 购物车的实现浅析
  • 2017-05-11ASP.NET MVC 导出Word报表
  • 2017-05-11控件开发时两种JS嵌入资源方式的使用方法
  • 2017-05-11asp.net计算每个页面执行时间的方法
  • 2017-05-11ASP.NET页面请求处理介绍
  • 2017-05-11.Net消息队列的使用方法
  • 2017-05-11asp.net运行原理 详解
  • 2017-05-11Asp.net MVC下使用Bundle合并、压缩js与css文件详解
  • 2018-08-20ASP.NET Core缓存静态资源示例详解
  • 2017-05-11asp.net获得数据控件事件索引并获取其中值总结

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • asp.net mvc发送邮件实例讲解
    • Asp.Net Oracle数据的通用操作类
    • .Net中导出数据到Excel(asp.net和winform程序中)
    • asp.net小孔子cms中的数据添加修改
    • 配置Visual Studio 以调试.net framework源代码第1/2页
    • ASP.NET中常用的优化性能的方法
    • .net core使用redis基于StackExchange.Redis
    • ASP.NET页面之间传值的方式之Application实例详解
    • GridView中点击CheckBox选中一行来改变此行的颜色
    • 获取远程网页的内容之二(downmoon原创)

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有