日志

ILoggerFactory 根据日志类型(categoryName)调用 对应的 ILoggerProvider 获取 ILogger

    • Logger 日子记录器
    • ILoggerFactory 日志记录器工厂
    • ILoggerProvider 日志记录器提供器
  public interface ILoggerFactory : IDisposable
    {
        ILogger CreateLogger(string categoryName);
        void AddProvider(ILoggerProvider provider);
    }    
   public interface ILogger
    {       
        void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter);    
        bool IsEnabled(LogLevel logLevel);
        IDisposable BeginScope<TState>(TState state);
    }
/// <typeparam name="TCategoryName">The type who's name is used for the logger category name.</typeparam>
    public interface ILogger<out TCategoryName> : ILogger
    {        
    }

Start.Configure() 方法中直接注入ILoggerFactory(ps:这个方法非常特殊,这方法的参数可以无穷多个,但是每个参数都必须是DI托管的对象。)

 public static IServiceCollection AddLogging(this IServiceCollection services, Action<ILoggingBuilder> configure)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            services.AddOptions();

            services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
            services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));

            services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<LoggerFilterOptions>>(
                new DefaultLoggerLevelConfigureOptions(LogLevel.Information)));

            configure(new LoggingBuilder(services));
            return services;
        }
    }

注入到Controller的ILooger到底是哪个Logger?难道只是某一个提供器生成Logger对象?

首先看看到底是哪个ILogger的托管到了容器里(Provider生成Logger对象并没有托管给容器,所以容器注入的Logger肯定不是日志提供器创建的ILogger对象)

在AddLogging() 中看到了

这个Logger就非常有意思, 他的成员变量里有LoggerFactory和LoggerInformation[] 引用 !!!(LoggerInformation是Logger的包装类,主要增加了一些Logger的元数据,可以理解成这就是一个Logger,这个logger就是LoggerProvider创建的Logger)
    public class Logger<T> : ILogger<T>
    {
        private readonly ILogger _logger;

        /// <summary>
        /// Creates a new <see cref="Logger{T}"/>.
        /// </summary>
        /// <param name="factory">The factory.</param>
        public Logger(ILoggerFactory factory)
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            _logger = factory.CreateLogger(TypeNameHelper.GetTypeDisplayName(typeof(T)));
        }
 public ILogger CreateLogger(string categoryName)
        {
            if (CheckDisposed())
            {
                throw new ObjectDisposedException(nameof(LoggerFactory));
            }

            lock (_sync)
            {
                if (!_loggers.TryGetValue(categoryName, out var logger))
                {
                    logger = new Logger(this)
                    {
                        Loggers = CreateLoggers(categoryName)
                    };
                    _loggers[categoryName] = logger;
                }

                return logger;
            }
        }
       private LoggerInformation[] CreateLoggers(string categoryName)
        {
            var loggers = new LoggerInformation[_providerRegistrations.Count];
            for (int i = 0; i < _providerRegistrations.Count; i++)
            {
                SetLoggerInformation(ref loggers[i], _providerRegistrations[i].Provider, categoryName);
            }

            ApplyRules(loggers, categoryName, 0, loggers.Length);
            return loggers;
        }
  • 跟踪Trace = 0 表示仅对于开发人员调试问题有价值的信息。 这些消息可能包含敏感应用程序数据,因此不得在生产环境中启用它们。 默认情况下禁用。

  • 调试Debug = 1 表示在开发和调试过程中短期有用的信息。除非要排查问题,否则通常不会在生产中启用 Debug 级别日志,因为日志数量过多。

  • 信息Information = 2 用于跟踪应用程序的常规流。 这些日志通常有长期价值。

  • 警告Warning = 3 表示应用程序流中的异常或意外事件。 可能包括不会中断应用程序运行但仍需调查的错误或其他条件。 Warning 日志级别常用于已处理的异常。

  • 错误Error = 4 表示无法处理的错误和异常。 这些消息指示的是当前活动或操作(如当前 HTTP 请求)中的失败,而不是应用程序范围的失败。

  • 严重Critical = 5 需要立即关注的失败。 例如数据丢失、磁盘空间不足。

  • None = 6 是禁用所有日志,因为没有比None更高的等级

原文地址:https://www.cnblogs.com/cloudsu/p/11819190.html