Logging 三大对象
可以看到 Logging 的核心抽象就是三个接口,分别是:
ILogger:负责具体的日志写入逻辑,如:FileLogger,ConsoleLogger,SQLLogger,ElasticsearchLogger 等。
ILoggerProvider:用来创建记录器,一般和Logger配套使用,相当于单个Logger类型的工厂接口。
ILoggerFactory:记录器工厂,直接面向使用者的,使用者可以通过记录器工厂添加记录器提供程序和创建记录器。
这几个核心抽象位于 NuGet包:“Microsoft.Extensions.Logging.Abstractions”中。
日志等级
在.NET Core提供的日志抽象中提供了7个日志等级(比一般的日志组件多提供了一个Trace和None),分别是:
Trace
包含最详细消息的日志。 这些消息可能包含敏感的应用程序数据。 默认情况下禁用这些消息,并且不应在生产环境中启用这些消息。
Debug
在开发过程中用于交互式调查的日志。 这些日志应主要包含对调试有用的信息,不具有长期价值。
Information
跟踪应用程序的一般流程的日志。 这些日志应具有长期价值。
Warning
突出显示应用程序流中异常或意外事件的日志,但是否则不会导致应用程序执行停止。
Error
当当前执行流程由于失败而停止时,会突出显示的日志。这些应该指示当前活动中的故障,而不是应用程序范围的故障。
Critical
描述不可恢复的应用程序或系统崩溃或灾难性的日志失败需要立即关注。
None
不用于写日志消息。 指定记录类别不应写任何消息。
简单使用
注入容器
/// <summary> /// 程序入口 /// </summary> public static class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } /// <summary> /// 创建监听宿主 /// </summary> /// <param name="args">接收启动命令参数</param> /// <returns>宿主接口</returns> private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); logging.AddDebug(); }) .UseAutofac(); }
记录日志
public HomeController(ILogger<HomeController> logger) { logger.LogDebug("测试一下"); }
CreateLogger方法
方法接口
/// <summary> /// Represents a type used to configure the logging system and create instances of <see cref="T:Microsoft.Extensions.Logging.ILogger" /> from /// the registered <see cref="T:Microsoft.Extensions.Logging.ILoggerProvider" />s. /// </summary> public interface ILoggerFactory : IDisposable { /// <summary> /// Creates a new <see cref="T:Microsoft.Extensions.Logging.ILogger" /> instance. /// </summary> /// <param name="categoryName">The category name for messages produced by the logger.</param> /// <returns>The <see cref="T:Microsoft.Extensions.Logging.ILogger" />.</returns> ILogger CreateLogger(string categoryName); /// <summary> /// Adds an <see cref="T:Microsoft.Extensions.Logging.ILoggerProvider" /> to the logging system. /// </summary> /// <param name="provider">The <see cref="T:Microsoft.Extensions.Logging.ILoggerProvider" />.</param> void AddProvider(ILoggerProvider provider); }
扩展方法
/// <summary> /// ILoggerFactory extension methods for common scenarios. /// </summary> public static class LoggerFactoryExtensions { /// <summary> /// Creates a new <see cref="ILogger"/> instance using the full name of the given type. /// </summary> /// <param name="factory">The factory.</param> /// <typeparam name="T">The type.</typeparam> /// <returns>The <see cref="ILogger"/> that was created.</returns> public static ILogger<T> CreateLogger<T>(this ILoggerFactory factory) { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } return new Logger<T>(factory); } /// <summary> /// Creates a new <see cref="ILogger"/> instance using the full name of the given <paramref name="type"/>. /// </summary> /// <param name="factory">The factory.</param> /// <param name="type">The type.</param> /// <return>The <see cref="ILogger"/> that was created.</return> public static ILogger CreateLogger(this ILoggerFactory factory, Type type) { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } if (type == null) { throw new ArgumentNullException(nameof(type)); } return factory.CreateLogger(TypeNameHelper.GetTypeDisplayName(type, includeGenericParameters: false, nestedTypeDelimiter: '.')); } }
在扩展方法内部使用了“GetTypeDisplayName(Type type)”来根据类型获取名称(里面有一些逻辑处理,但一般是采用“{命名空间}.{类型名称}”作为分类名称)。
Log方法
/// <summary>Represents a type used to perform logging.</summary> /// <remarks>Aggregates most logging patterns to a single method.</remarks> public interface ILogger { /// <summary>Writes a log entry.</summary> /// <param name="logLevel">Entry will be written on this level.</param> /// <param name="eventId">Id of the event.</param> /// <param name="state">The entry to be written. Can be also an object.</param> /// <param name="exception">The exception related to this entry.</param> /// <param name="formatter">Function to create a <see cref="T:System.String" /> message of the <paramref name="state" /> and <paramref name="exception" />.</param> /// <typeparam name="TState">The type of the object to be written.</typeparam> void Log<TState>( LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter); /// <summary> /// Checks if the given <paramref name="logLevel" /> is enabled. /// </summary> /// <param name="logLevel">level to be checked.</param> /// <returns><c>true</c> if enabled.</returns> bool IsEnabled(LogLevel logLevel); /// <summary>Begins a logical operation scope.</summary> /// <param name="state">The identifier for the scope.</param> /// <typeparam name="TState">The type of the state to begin scope for.</typeparam> /// <returns>An <see cref="T:System.IDisposable" /> that ends the logical operation scope on dispose.</returns> IDisposable BeginScope<TState>(TState state); }
logLevel
日志等级,详情见上文。
eventId(结构体,必填,可以传入 0 或 default(EventId)来充当默认值)
事件ID。
这边的事件ID是用来追踪的,类似 ErrorCode、StatusCode。这样在日志检索的时候可以通过code很方便的找到。
是一个结构体,默认为:“0”。
state(可为null)
状态。
需要记录的对象,这边可以传入任何类型,这就有点奇怪了日志不都是字符吗?
如果我传一个自建类 UserModel 进去会记录出什么信息呢?请接下来看 formatter 参数。
exception(可为null)
异常。
不多说了,如果当前上下文有异常,你丢进去就好了。
formatter(不可为null)
格式化器。
这个参数是一个委托可以看到定义“Func<TState,Exception,string>”,这个就可以解释state是非字符的情况下如何记录日志了。
这边可以通过你自己的逻辑来重建消息的内容(异常信息都会进行输出)。
如果传入null,日志组件会使用默认的格式化器替换,默认的格式化器逻辑是调用“state.ToString()”
扩展方法
/// <summary> /// ILogger extension methods for common scenarios. /// </summary> public static class LoggerExtensions { private static readonly Func<FormattedLogValues, Exception, string> _messageFormatter = MessageFormatter; //------------------------------------------DEBUG------------------------------------------// /// <summary> /// Formats and writes a debug log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogDebug(0, exception, "Error while processing request from {Address}", address)</example> public static void LogDebug(this ILogger logger, EventId eventId, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Debug, eventId, exception, message, args); } /// <summary> /// Formats and writes a debug log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogDebug(0, "Processing request from {Address}", address)</example> public static void LogDebug(this ILogger logger, EventId eventId, string message, params object[] args) { logger.Log(LogLevel.Debug, eventId, message, args); } /// <summary> /// Formats and writes a debug log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogDebug(exception, "Error while processing request from {Address}", address)</example> public static void LogDebug(this ILogger logger, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Debug, exception, message, args); } /// <summary> /// Formats and writes a debug log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogDebug("Processing request from {Address}", address)</example> public static void LogDebug(this ILogger logger, string message, params object[] args) { logger.Log(LogLevel.Debug, message, args); } //------------------------------------------TRACE------------------------------------------// /// <summary> /// Formats and writes a trace log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogTrace(0, exception, "Error while processing request from {Address}", address)</example> public static void LogTrace(this ILogger logger, EventId eventId, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Trace, eventId, exception, message, args); } /// <summary> /// Formats and writes a trace log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogTrace(0, "Processing request from {Address}", address)</example> public static void LogTrace(this ILogger logger, EventId eventId, string message, params object[] args) { logger.Log(LogLevel.Trace, eventId, message, args); } /// <summary> /// Formats and writes a trace log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogTrace(exception, "Error while processing request from {Address}", address)</example> public static void LogTrace(this ILogger logger, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Trace, exception, message, args); } /// <summary> /// Formats and writes a trace log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogTrace("Processing request from {Address}", address)</example> public static void LogTrace(this ILogger logger, string message, params object[] args) { logger.Log(LogLevel.Trace, message, args); } //------------------------------------------INFORMATION------------------------------------------// /// <summary> /// Formats and writes an informational log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogInformation(0, exception, "Error while processing request from {Address}", address)</example> public static void LogInformation(this ILogger logger, EventId eventId, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Information, eventId, exception, message, args); } /// <summary> /// Formats and writes an informational log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogInformation(0, "Processing request from {Address}", address)</example> public static void LogInformation(this ILogger logger, EventId eventId, string message, params object[] args) { logger.Log(LogLevel.Information, eventId, message, args); } /// <summary> /// Formats and writes an informational log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogInformation(exception, "Error while processing request from {Address}", address)</example> public static void LogInformation(this ILogger logger, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Information, exception, message, args); } /// <summary> /// Formats and writes an informational log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogInformation("Processing request from {Address}", address)</example> public static void LogInformation(this ILogger logger, string message, params object[] args) { logger.Log(LogLevel.Information, message, args); } //------------------------------------------WARNING------------------------------------------// /// <summary> /// Formats and writes a warning log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogWarning(0, exception, "Error while processing request from {Address}", address)</example> public static void LogWarning(this ILogger logger, EventId eventId, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Warning, eventId, exception, message, args); } /// <summary> /// Formats and writes a warning log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogWarning(0, "Processing request from {Address}", address)</example> public static void LogWarning(this ILogger logger, EventId eventId, string message, params object[] args) { logger.Log(LogLevel.Warning, eventId, message, args); } /// <summary> /// Formats and writes a warning log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogWarning(exception, "Error while processing request from {Address}", address)</example> public static void LogWarning(this ILogger logger, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Warning, exception, message, args); } /// <summary> /// Formats and writes a warning log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogWarning("Processing request from {Address}", address)</example> public static void LogWarning(this ILogger logger, string message, params object[] args) { logger.Log(LogLevel.Warning, message, args); } //------------------------------------------ERROR------------------------------------------// /// <summary> /// Formats and writes an error log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogError(0, exception, "Error while processing request from {Address}", address)</example> public static void LogError(this ILogger logger, EventId eventId, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Error, eventId, exception, message, args); } /// <summary> /// Formats and writes an error log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogError(0, "Processing request from {Address}", address)</example> public static void LogError(this ILogger logger, EventId eventId, string message, params object[] args) { logger.Log(LogLevel.Error, eventId, message, args); } /// <summary> /// Formats and writes an error log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogError(exception, "Error while processing request from {Address}", address)</example> public static void LogError(this ILogger logger, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Error, exception, message, args); } /// <summary> /// Formats and writes an error log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogError("Processing request from {Address}", address)</example> public static void LogError(this ILogger logger, string message, params object[] args) { logger.Log(LogLevel.Error, message, args); } //------------------------------------------CRITICAL------------------------------------------// /// <summary> /// Formats and writes a critical log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogCritical(0, exception, "Error while processing request from {Address}", address)</example> public static void LogCritical(this ILogger logger, EventId eventId, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Critical, eventId, exception, message, args); } /// <summary> /// Formats and writes a critical log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogCritical(0, "Processing request from {Address}", address)</example> public static void LogCritical(this ILogger logger, EventId eventId, string message, params object[] args) { logger.Log(LogLevel.Critical, eventId, message, args); } /// <summary> /// Formats and writes a critical log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogCritical(exception, "Error while processing request from {Address}", address)</example> public static void LogCritical(this ILogger logger, Exception exception, string message, params object[] args) { logger.Log(LogLevel.Critical, exception, message, args); } /// <summary> /// Formats and writes a critical log message. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="message">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <example>logger.LogCritical("Processing request from {Address}", address)</example> public static void LogCritical(this ILogger logger, string message, params object[] args) { logger.Log(LogLevel.Critical, message, args); } /// <summary> /// Formats and writes a log message at the specified log level. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="logLevel">Entry will be written on this level.</param> /// <param name="message">Format string of the log message.</param> /// <param name="args">An object array that contains zero or more objects to format.</param> public static void Log(this ILogger logger, LogLevel logLevel, string message, params object[] args) { logger.Log(logLevel, 0, null, message, args); } /// <summary> /// Formats and writes a log message at the specified log level. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="logLevel">Entry will be written on this level.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="message">Format string of the log message.</param> /// <param name="args">An object array that contains zero or more objects to format.</param> public static void Log(this ILogger logger, LogLevel logLevel, EventId eventId, string message, params object[] args) { logger.Log(logLevel, eventId, null, message, args); } /// <summary> /// Formats and writes a log message at the specified log level. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="logLevel">Entry will be written on this level.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message.</param> /// <param name="args">An object array that contains zero or more objects to format.</param> public static void Log(this ILogger logger, LogLevel logLevel, Exception exception, string message, params object[] args) { logger.Log(logLevel, 0, exception, message, args); } /// <summary> /// Formats and writes a log message at the specified log level. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to write to.</param> /// <param name="logLevel">Entry will be written on this level.</param> /// <param name="eventId">The event id associated with the log.</param> /// <param name="exception">The exception to log.</param> /// <param name="message">Format string of the log message.</param> /// <param name="args">An object array that contains zero or more objects to format.</param> public static void Log(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string message, params object[] args) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } logger.Log(logLevel, eventId, new FormattedLogValues(message, args), exception, _messageFormatter); } //------------------------------------------Scope------------------------------------------// /// <summary> /// Formats the message and creates a scope. /// </summary> /// <param name="logger">The <see cref="ILogger"/> to create the scope in.</param> /// <param name="messageFormat">Format string of the log message in message template format. Example: <code>"User {User} logged in from {Address}"</code></param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <returns>A disposable scope object. Can be null.</returns> /// <example> /// using(logger.BeginScope("Processing request from {Address}", address)) /// { /// } /// </example> public static IDisposable BeginScope( this ILogger logger, string messageFormat, params object[] args) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } return logger.BeginScope(new FormattedLogValues(messageFormat, args)); } //------------------------------------------HELPERS------------------------------------------// private static string MessageFormatter(FormattedLogValues state, Exception error) { return state.ToString(); } }
EventId作用
测试代码
public HomeController(ILogger<HomeController> logger) { for (int i = 0; i < 5; i++) { logger.LogDebug(i, "测试一下"); } }
效果图
日志域
测试代码
public HomeController(ILogger<HomeController> logger) { using (logger.BeginScope("开始测试")) { for (int i = 0; i < 5; i++) { logger.LogDebug(i, "测试一下"); } } }
日志过滤器
配置日志过滤
{ "Logging": { "LogLevel": { "Default": "Debug", "Microsoft": "Information", "Microsoft.Hosting.Lifetime": "Information" } }
如果你的命名空间中存在多个“.”符号则还会被分割
分割完成之后会将这些 Key 拿去与“FilterLoggerSettings”中的字典表进行匹配,优先最大匹配,也就是说如果我们配置了“Microsoft.Hosting.Lifetime”这条项目,则优先使用这条,否则继续寻找“Microsoft”这条项目,如果都没匹配到则使用默认的规则。
在 NLog、log4jnet 等组件中模糊匹配是采用“.*”的方式,例如:”Microsoft.*”,在 .NET Core 中的 Logging 中是不被支持的(把“.*”去掉实现相同的效果),这点需要注意
特殊Logger=>NullLogger
public class NullLogger<T> : ILogger<T> { /// <summary> /// Returns an instance of <see cref="NullLogger{T}"/>. /// </summary> /// <returns>An instance of <see cref="NullLogger{T}"/>.</returns> public static readonly NullLogger<T> Instance = new NullLogger<T>(); /// <inheritdoc /> public IDisposable BeginScope<TState>(TState state) { return NullDisposable.Instance; } /// <inheritdoc /> /// <remarks> /// This method ignores the parameters and does nothing. /// </remarks> public void Log<TState>( LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { } /// <inheritdoc /> public bool IsEnabled(LogLevel logLevel) { return false; } private class NullDisposable : IDisposable { public static readonly NullDisposable Instance = new NullDisposable(); public void Dispose() { // intentionally does nothing } } }
public HomeController(ILogger<HomeController> logger) { logger ??= NullLogger<HomeController>.Instance; logger.LogDebug("x"); }
可以看到在没有添加 Logging 组件的时候日志记录也不会抛出异常。
总结
.NET Core 中统一了非常多的常用组件,为开发者统一环境提供了极大的方便
后续的文章会分享如何集成第三方 Logging 组件,比如:NLog、Serilog 等。