zoukankan      html  css  js  c++  java
  • [Asp.net 5] Logging-日志系统的基本架构(下)

    接上节内容,我们继续讲解日志的其他部分.

    ILoggerProvider以及扩展类

    我们在上节的架构图上并没有看到有直接实现该接口的实现类。那么如果将Logger类直接使用会有什么结果呢?

    var factory = new LoggerFactory();
    var logger = factory.CreateLogger("name");
    logger.Log(LogLevel.Debug, 0, "state", null, null);

    这段代码能够正常运行但是不会记录任何日志。因为Logger类并没有直接记录日志的功能,需要通过LoggerFactory的GetProviders方法创建能够直接工作的ILogger类型日志。所以即使现在的工程中没有对于ILoggerProvider的扩展,但是我们可以预测:Microsoft.Framework.Logging.Console、Microsoft.Framework.Logging.NLog、Microsoft.Framework.Logging.TraceSource都会对ILoggerProvider进行实现,当然由于ILoggerProvider会产生ILogger,所以他们也会实现ILogger类。
    ILogValues以及扩展

    我们看到日志记录类的接口为:Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)

    该接口通过formatter将state和exception组合成字符串对象,然后记录到log中。如果使用扩展方法系统传入的formatter永远是:MessageFormatter

            private static string MessageFormatter(object state, Exception error)
            {
                if (state == null && error == null)
                {
                    throw new InvalidOperationException("No message or exception details were found " +
                        "to create a message for the log.");
                }
    
                if (state == null)
                {
                    return error.ToString();
                }
    
                if (error == null)
                {
                    return state.ToString();
                }
    
                return string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}", state, Environment.NewLine, error);
            }
    MessageFormatter

    如果我们需要记录的信息(state)比较复杂,是一个或多个复杂对象,那么我们一般使用ILogValues对象。

    系统中一共为我们提供2个ILogValues接口实现:FormattedLogValues、ReflectionBasedLogValues。

    • FormattedLogValues:系统默认扩展传入args以及formatter参数的扩展方法使用,能够将按照formmater的格式,将对象串行成字符串(只支持以及数组)
    • ReflectionBasedLogValues:通过反射,获取类的所有属性。(该类会在扩展log中使用)
        public class FormattedLogValues : ILogValues
        {
            private static ConcurrentDictionary<string, LogValuesFormatter> _formatters = new ConcurrentDictionary<string, LogValuesFormatter>();
            private readonly LogValuesFormatter _formatter;
            private readonly object[] _values;
    
            public FormattedLogValues(string format, params object[] values)
            {
                _formatter = _formatters.GetOrAdd(format, f => new LogValuesFormatter(f));
                _values = values;
            }
    
            public IEnumerable<KeyValuePair<string, object>> GetValues()
            {
                return _formatter.GetValues(_values);
            }
    
            public override string ToString()
            {
                return _formatter.Format(_values);
            }
        }
    FormattedLogValues
        public class ReflectionBasedLogValues : ILogValues
        {
            public virtual IEnumerable<KeyValuePair<string, object>> GetValues()
            {
                var values = new List<KeyValuePair<string, object>>();
                var properties = GetType().GetTypeInfo().DeclaredProperties;
                foreach (var propertyInfo in properties)
                {
                    values.Add(new KeyValuePair<string, object>(
                        propertyInfo.Name,
                        propertyInfo.GetValue(this)));
                }
                return values;
            }
        }
    ReflectionBasedLogValues

    其他类

    • LogLevel:日志的等级
    • LogFormatter:与MessageFormatter类似,提供不同的formmater方法。
  • 相关阅读:
    软件质量
    LINUX
    C# .net 多线程中集合数据同步
    一些常用COM接口表
    PHP、JAVA、C#、Object-C 通用的DES加密
    【C#公共帮助类】给大家分享一些加密算法 (DES、HashCode、RSA、AES等)
    C#中如何把int转换成两个字符的string 缺位补零
    C#中Math.Round()实现中国式四舍五入
    C# RGB与16进制颜色转换方法
    c# e语言 字节集 表示方式
  • 原文地址:https://www.cnblogs.com/watermoon2/p/4552034.html
Copyright © 2011-2022 走看看