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方法。
  • 相关阅读:
    C# Bitmap类型与Byte[]类型相互转化
    博客园添加个人Github链接
    C# Exception has been thrown by the target of an invocation(调用的目标已抛出异常) 解决办法
    C# 使用Renci.SshNet连接SSH远程服务器
    Oracle 查询当前数据库版本信息
    Oracle ORA-12569: TNS:包校验和失败
    Oracle Rollup()函数
    Oracle 字符串补零
    DataGridView 表格排序后颜色丢失
    DataGridView 实现最后一列的宽度自适应
  • 原文地址:https://www.cnblogs.com/watermoon2/p/4552034.html
Copyright © 2011-2022 走看看