日志框架:聊聊记日志的最佳姿势

本文章首发于公众号攻城狮客栈,有需要的朋友可文末扫描二维码。

相信开发过大型系统的同学们都知道,日志在系统中有着举足轻重的位置,一方面,通过日志系统可以记录具体的业务流程以便完成业务追踪,另一方面,当系统出现异常时,通过日志可以快速的定位问题。在平时的开发中,相信大家都用过记录日志到文件以及使用老牌日志框架log4net等,特别是在网站开发过程中,很多都集成log4net来进行日志记录。那么在Netcore中有哪些日志记录的方式呢?从本节开始,我们就一块来看一下吧。

 

NETCore 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。

我们都知道,Netcore为我们提供了丰富的扩展库,涉及记录输出日志到不同的地方以及对不同的需求分别控制其日志级别。下面我们来看看如何将日志记录 API 与内置提供程序一起使用。

 

依赖包

Netcore提供了丰富的扩展来支持日志的不同输出需求

  • Microsoft.Extensions.Logging

  • Microsoft.Extensions.Logging.Abstractions

  • Microsoft.Extensions.Logging.Console

  • Microsoft.Extensions.Logging.Debug

  • Microsoft.Extensions.Logging.TraceSource

     

日志级别定义

每个日志都指定了一个 LogLevel 值。 日志级别指示严重性或重要程度。

public enum LogLevel:Enum
{
    Trace,//跟踪 = 0
    Debug,//调试 = 1
    Information,//信息 = 2
    Warning,//警告 = 3
    Error,//错误 = 4
    Critical,//严重 = 5
    None//禁止显示所有日志=6
}

一般的,使用日志级别控制写入到特定存储介质或显示窗口的日志输出量。 例如:

生产中:

  • 如果通过 Information 级别在 Trace 处记录,则会生成大量详细的日志消息。 为控制成本且不超过数据存储限制,请通过 Information 级别消息将 Trace 记录到容量大、成本低的数据存储中。

  • 如果通过 Critical 级别在 Warning 处记录,通常生成的日志消息更少且更小。 因此,成本和存储限制通常不是问题,而这使得在选择数据信息时更为灵活。

在开发过程中:

  • 通过 Critical 消息将 Warning 记录到控制台。

  • 在疑难解答时通过 Information 消息添加 Trace。

 

代码演示

若要创建日志,请使用 ILogger<TCategoryName> 对象。 在 Web 应用或托管服务中,由依赖关系注入 (DI) 获取 ILogger。 在非主机控制台应用中,使用 LoggerFactory 来创建 ILogger。

 

我们先来看一下使用LoggerFactory创建ILogger的方式。

{
    ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
    //创建指定名称的logger
    ILoggerFactory loggerFactory = serviceProvider.GetService<ILoggerFactory>();
    ILogger logger = loggerFactory.CreateLogger("alogger");
    logger.LogTrace("trace");
    logger.LogDebug("debug");
    logger.LogInformation("information");
    logger.LogWarning("warning");
}

从以上代码中,我们可以看到,首先,我们需要通过服务提供者Service-Provider的GetService方法来获取一个ILoggerFactory对象,接着可通过该对象来创建指定名称的日志记录器。

 

我们再来看一下如何通过DI获取ILogger。

我们可以先看一下以下代码,该代码是默认的aspnetcore网站的默认控制器中的代码

private readonly ILogger<WeatherForecastController> _logger;

public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
    _logger = logger;
}

​​​​​​​通过以上方式,即可获取到对应控制器的日志对象并进行日志操作,其实,这里就是使用的依赖注入框架来获取ILogger的。

那么同样的,在当前的控制台程序内,我们可以通过以下语句来获取日志对象。

ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
ILogger logger = serviceProvider.GetService<ILogger<Program>>();

是不是很简单呢?不过需要注意一下,这里是生成主机后从 DI 获取 ILogger实例,但并不直接支持在主机构造期间进行日志记录。 但是,可以使用单独的记录器。换句话说,就是可以在CreateHostBuilder函数中进行配置。

 

了解完日志记录的2种方式,那我们在平常使用时,一般推荐哪种方式呢?我们比较推荐第二种,即通过依赖注入框架获取的方式,毕竟asp.net core自身也是如此使用的,这方式的好处是在服务中直接定义ILogger,这样日志对象的命名是确定的,是命名空间+类名的方式,并且可在操作服务时直接操作日志。

比如,我们先来生成一个服务。

public class OrderService
{
    ILogger<OrderService> logger;

    public OrderService(ILogger<OrderService> logger)
    {
        this.logger = logger;
    }

    public void PrintLog()
    {
        logger.LogDebug(" Debug: Time now:{time}",DateTime.Now.ToString());
        logger.LogInformation(" info: Time now:{time}",DateTime.Now.ToString());
    }
}

​​​​​​​

接着,在startup的Configure方法内或Program的main方法里通过以下方式即可获取

serviceDescriptors.AddScoped<OrderService>();
ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();

OrderService orderService = serviceProvider.GetService<OrderService>();
orderService.PrintLog();

最后,我们再来看一种情况,就是通过配置来定义日志的输出级别,我们都知道,通过配置框架可以控制程序运行的一些特殊需求,那么针对不同的日志打印需求,我们同样可以通过日志框架来进行控制。

如我们的setting.json文件如下

{
  "logging": {
    "loglevel": {
      "Default": "information"
    },
    "Console": {
      "loglevel": {
        "Default": "None",
        "_11_LoggingSimpleDemo.Program": "Trace",
        "_11_LoggingSimpleDemo.OrderService": "Trace",
        "aLogger": "Trace"
      }
    }
  }
}

那么,在使用时可以通过如下方式来进行级别配置。

IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("settings.json");
IConfigurationRoot configurationRoot = configurationBuilder.Build();

IServiceCollection serviceDescriptors = new ServiceCollection();
serviceDescriptors.AddSingleton<IConfiguration>(p => configurationRoot);
serviceDescriptors.AddLogging(configure =>
{
    configure.AddConfiguration(configurationRoot.GetSection("Logging"));
    configure.AddConsole();//这里如果要在配置文件中定义level,那么,节的名称必须是”Console“,区分大小写的,否则不生效
});

​​​​​​​

好了,到这里的话,本节就先告一段落了,我们本节主要学习了日志框架的使用方式,包括日志级别定义、日志对象获取的方式以及通过logger名称进行日志过滤的配置逻辑等。

 

下一节,我们将学习日志作用域以及第三方日志框架serilog的内容。

源码可访问

https://github.com/IronMarmot/Samples/tree/master/CoreSamples

更多课程详细内容,可识别下方二维码购买。

扫描二维码购买课程,可后台留言获得10元红包返现。

                                                                      

部分内容来源于网络,侵删。

更多精彩内容,请微信搜索攻城狮客栈 或扫描下方二维码

------------------------------------------------------------------------------

公众号:攻城狮客栈

CSDN:画鸡蛋的不止达芬奇

 

                                                                 

让我们一起变的更优秀。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值