框架介绍
在之前的.NET中,微软还没有提供过像样的日志框架,目前能用的一些框架比如Log4Net、NLog、CommonLogging使用起来多多少少都有些费劲,和java的SLF4J根本无法相比。但在新版的ASP.NET5中,可谓是牛气冲天,微软提供的Microsoft.Framework.Logging框架集可谓就是.NET版的SLF4J,提供相应的接口,其它第三方组件可以根据接口实现自己的实现。
ILoggerFactory接口
ILoggerFactory
接口是日志的入库点,在系统中通过依赖注入可以获取该接口的实例,并根据该示例创建日志记录器ILogger
来记录日志,示例如下:
1
2
3
4
5
6
7
|
var factory = ServiceProvider.GetRequiredService<ILoggerFactory>(); var logger1 = factory.CreateLogger( typeof (HomeController).FullName); //CreateLogger var logger2 = factory.CreateLogger<HomeController>(); //CreateLogger logger1.Log(LogLevel.Information, 1, null , null , null ); // 日志记录 logger1.LogInformation( "123" ); // 扩展方法 logger1.LogError( "123" ); // 扩展方法 |
或者,你也可以在Startup.cs的Configure方法中,从loggerfactory参数中获取上述示例。
ILoggerFactory
接口的定义如下:
1
2
3
4
5
6
7
8
9
10
|
public interface ILoggerFactory { //日志最小记录级别 LogLevel MinimumLevel { get ; set ; } //创建日志记录实例 ILogger CreateLogger( string categoryName); //一般是根据功能模块或类名进行分类 void AddProvider(ILoggerProvider provider); // 添加日志记录provider(如第三方实现) } |
在该接口的实现中,我们可以设置日志的最小记录基本,其类别如下:
1
2
3
4
5
6
7
8
9
|
public enum LogLevel { Debug = 1, Verbose = 2, Information = 3, Warning = 4, Error = 5, Critical = 6, } |
也可以添加第三方实现的Provider,比如添加一个控制台版本的实现:
1
2
3
4
5
|
public static ILoggerFactory AddConsole( this ILoggerFactory factory) { factory.AddProvider( new ConsoleLoggerProvider((category, logLevel) => logLevel >= LogLevel.Information)); return factory; } |
然后通过CreateLogger方法创建日志记录器实例,最后再记录日志。
ILoggerProvider和ILogger
所有的第三方实现都需要实现ILoggerProvider接口和ILogger接口,其中接口很简单,就是实现创建ILogger接口的方法即可,代码如下:
1
2
3
4
|
public interface ILoggerProvider { ILogger CreateLogger( string name); //创建给定类别的ILgger实例 } |
而ILogger的实现,也相对简单,除了实现通用的日志记录方法以外,还需要实现一个日志级别判断的方法以及一个作用域创建方法,接口定义如下:
1
2
3
4
5
6
7
8
9
10
11
|
public interface ILogger { //支持大多数日志记录的通用方法,其它访问通过扩展方法进行完善 void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func< object , Exception, string > formatter); //判断是否可以记录给定的日志级别 bool IsEnabled(LogLevel logLevel); //开启一个逻辑操作作用域 IDisposable BeginScopeImpl( object state); } |
实现了上述两个接口,即可通过factory
的AddProvider
方法,将该provider添加到实例中,达到记录日志的目的。ASP.NET 5中目前的默认实现了4中日志记录Provider,分别是:Console、NLog、Serilog、Trace,注册这些Provider的时候,均可以使用扩展方法,实例如下:
1
2
3
4
5
|
loggerfactory.AddConsole() loggerfactory.AddNLog( new NLog.LogFactory()) loggerfactory.AddSerilog( new LoggerConfiguration()) var testSwitch = new SourceSwitch( "TestSwitch" , "Level will be set to warning for this test" ); factory.AddTraceSource(testSwitch, new ConsoleTraceListener()); |
ILogger的扩展方法
为了方便记录日志,微软在Microsoft.Framework.Logging.LoggerExtensions
上,针对6个级别的日志记录均定义了6个如下形式的扩展方法,实例如下:
1
2
3
4
5
6
7
8
|
public static void LogInformation( this ILogger logger, string message) public static void LogInformation( this ILogger logger, int eventId, string message) public static void LogInformation( this ILogger logger, string format, params object [] args) public static void LogInformation( this ILogger logger, int eventId, string format, params object [] args) public static void LogInformation( this ILogger logger, ILogValues state, Exception error = null ) public static void LogInformation( this ILogger logger, int eventId, ILogValues state, Exception error = null ) // 其它Debug、Verbose、Warning、Error、Critical也都遵循LogXXXX()规则. |
所以使用的时候,我们可以使用像LogDebug()、LogError()这样的方法来进行快速记录日志。另外,该类还为Warning、Error、Critical三个级别,又分别定义了2个扩展方法,示例如下:
1
2
|
public static void LogWarning( this ILogger logger, string message, Exception error) public static void LogWarning( this ILogger logger, int eventId, string message, Exception error) |
有些这些扩展方法,使用起来估计打遍天下无敌手了。
总结
通过基于接口的编程机制和DI依赖注入机制,我们可以很容易实现第三方日志provider的扩展,从而将日志记录到我们想记录的任意地方,如MongoDB等NoSQL数据库。