zoukankan      html  css  js  c++  java
  • 幸福框架:我是如何使用日志的

    日志的用途

    • 跟踪,监控应用程序的执行(框架开发人员需要关注这点)。
    • 审计,监控用户的行为(应用开发人员需要关注这点)。

    日志的使用原则

    • 使用或不适用日志,不应当对系统行为产生影响。
    • 可以通过配置修改日志的记录方式和记录哪些日志。

    适合AOP的日志场景

    • 记录“某些”异常。
    • 性能监控。
    • 操作日志。

    不适合AOP的场景

    • 执行跟踪。
    • SQL监控。

    下边介绍一下“幸福框架”中的日志API和使用原则

    日志接口拷贝了Log4Net

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace Happy.Logging
     8 {
     9     public interface ILoger
    10     {
    11         void Debug(object message);
    12 
    13         void Info(object message);
    14 
    15         void Warn(object message);
    16 
    17         void Error(object message);
    18 
    19         void Fatal(object message);
    20 
    21 
    22         void Debug(object message, Exception ex);
    23 
    24         void Info(object message, Exception ex);
    25 
    26         void Warn(object message, Exception ex);
    27 
    28         void Error(object message, Exception ex);
    29 
    30         void Fatal(object message, Exception ex);
    31 
    32 
    33         bool IsDebugEnabled { get; }
    34 
    35         bool IsInfoEnabled { get; }
    36 
    37         bool IsWarnEnabled { get; }
    38 
    39         bool IsErrorEnabled { get; }
    40 
    41         bool IsFatalEnabled { get; }
    42     }
    43 }

    日志实现采用了EnterpriseLibrary

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Diagnostics;
      4 using System.Linq;
      5 using System.Text;
      6 using System.Threading.Tasks;
      7 
      8 using Microsoft.Practices.EnterpriseLibrary.Logging;
      9 
     10 using Happy.DesignByContract;
     11 using Happy.Logging;
     12 
     13 namespace Happy.EnterpriseLibrary.Logging
     14 {
     15     public sealed class Loger : ILoger
     16     {
     17         private const int CONST_Priority = 10;
     18         private readonly LogWriter _writer;
     19         private readonly string _name;
     20 
     21         public Loger(LogWriter writer, string name)
     22         {
     23             Check.RequireNotNull(writer, "writer");
     24             Check.RequireNotNull(name, "name");
     25 
     26             _writer = writer;
     27             _name = name;
     28         }
     29 
     30         public void Debug(object message)
     31         {
     32             this.Write(message, TraceEventType.Verbose);
     33         }
     34 
     35         public void Info(object message)
     36         {
     37             this.Write(message, TraceEventType.Information);
     38         }
     39 
     40         public void Warn(object message)
     41         {
     42             this.Write(message, TraceEventType.Warning);
     43         }
     44 
     45         public void Error(object message)
     46         {
     47             this.Write(message, TraceEventType.Error);
     48         }
     49 
     50         public void Fatal(object message)
     51         {
     52             this.Write(message, TraceEventType.Critical);
     53         }
     54 
     55 
     56         public void Debug(object message, Exception ex)
     57         {
     58             this.Write(message, ex, TraceEventType.Verbose);
     59         }
     60 
     61         public void Info(object message, Exception ex)
     62         {
     63             this.Write(message, ex, TraceEventType.Information);
     64         }
     65 
     66         public void Warn(object message, Exception ex)
     67         {
     68             this.Write(message, ex, TraceEventType.Warning);
     69         }
     70 
     71         public void Error(object message, Exception ex)
     72         {
     73             this.Write(message, ex, TraceEventType.Error);
     74         }
     75 
     76         public void Fatal(object message, Exception ex)
     77         {
     78             this.Write(message, ex, TraceEventType.Critical);
     79         }
     80 
     81 
     82         public bool IsDebugEnabled
     83         {
     84             get
     85             {
     86                 return _writer.TraceSources[_name].Level >= SourceLevels.Verbose;
     87             }
     88         }
     89 
     90         public bool IsInfoEnabled
     91         {
     92             get
     93             {
     94                 return _writer.TraceSources[_name].Level >= SourceLevels.Information;
     95             }
     96         }
     97 
     98         public bool IsWarnEnabled
     99         {
    100             get
    101             {
    102                 return _writer.TraceSources[_name].Level >= SourceLevels.Warning;
    103             }
    104         }
    105 
    106         public bool IsErrorEnabled
    107         {
    108             get
    109             {
    110                 return _writer.TraceSources[_name].Level >= SourceLevels.Error;
    111             }
    112         }
    113 
    114         public bool IsFatalEnabled
    115         {
    116             get
    117             {
    118                 return _writer.TraceSources[_name].Level == SourceLevels.Critical;
    119             }
    120         }
    121 
    122 
    123         private void Write(object message, TraceEventType traceEventType)
    124         {
    125             _writer.Write(message, _name, CONST_Priority, 0, traceEventType);
    126         }
    127 
    128         private void Write(object message, Exception ex, TraceEventType traceEventType)
    129         {
    130             var properties = GetProperties(ex);
    131 
    132             _writer.Write(message, _name, CONST_Priority, 0, traceEventType, ex.Message, properties);
    133         }
    134 
    135         private static Dictionary<string, object> GetProperties(Exception ex)
    136         {
    137             return
    138                     new Dictionary<string, object>
    139                     {
    140                         { "异常", ex }
    141                     };
    142         }
    143     }
    144 }

    日志的使用场景(Debug)

     1         private void RegistBundleToUnity(Bundle bundle)
     2         {
     3             foreach (var convention in _conventions)
     4             {
     5                 convention.AutoRegist(bundle.Assembly);
     6             }
     7 
     8             foreach (var register in bundle.Assembly.GetConcreteDescendentInstances<IUnityRegister>())
     9             {
    10                 register.Regist(UnityBundleContainerExtensions.ChildContainer);
    11             }
    12 
    13             this.LogChildContainer();
    14         }
    15 
    16         private void LogChildContainer()
    17         {
    18             var registrationsInfo =
    19                                     UnityBundleContainerExtensions
    20                                     .ChildContainer
    21                                     .Registrations
    22                                     .JoinToString(x => string.Format("{0}->{1}({2})", x.RegisteredType.FullName, x.MappedToType.FullName, x.LifetimeManagerType.Name), ",\r\n\t");
    23 
    24             LogHelper.Debug(string.Format("“{0}”中的注册的类型信息:\r\n\t{1}。", UnityBundleContainerExtensions.ChildContainer.GetType().Name, registrationsInfo));
    25         }

    日志的使用场景(Info)

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 using System.Diagnostics;
     8 
     9 using Happy.Logging;
    10 using Happy.DesignByContract;
    11 
    12 namespace Happy.Messaging
    13 {
    14     public sealed class LoggingFilter : IMessageFilter
    15     {
    16         public void Intercept(IMessagePipeLine pipeLine)
    17         {
    18             Check.RequireNotNull(pipeLine, "pipeLine");
    19 
    20             try
    21             {
    22                 var watch = Stopwatch.StartNew();
    23                 pipeLine.Next();
    24                 watch.Stop();
    25 
    26                 LogHelper.Info(string.Format("执行消息“{0}”耗费了“{1}”。", pipeLine.Message.GetType().FullName, watch.Elapsed));
    27             }
    28             catch (Exception ex)
    29             {
    30                 LogHelper.Info(string.Format("执行消息“{0}”时出现异常。", pipeLine.Message.GetType().FullName), ex);
    31 
    32                 throw;
    33             }
    34         }
    35     }
    36 }

    日志的使用场景(Warn)

     1         private IEnumerable<IMessageHandler> GetMessageHandlers(MessageScene scene, IMessage message)
     2         {
     3             var handlerType = GetMessageHandler(message);
     4 
     5             var hanlders = _serviceLocator.GetAllInstances(handlerType);
     6 
     7             if (hanlders == null)
     8             {
     9                 LogHelper.Warn(string.Format("没有找到消息“{0}”对应的Handler", message.GetType().FullName));
    10 
    11                 return Enumerable.Empty<IMessageHandler>();
    12             }
    13 
    14             return
    15                     hanlders
    16                     .Cast<IMessageHandler>()
    17                     .Where(hanlder => hanlder.Scene == scene);
    18         }

    日志的使用场景(Fatal)

     1         private void LoadAssemblies()
     2         {
     3             try
     4             {
     5                 new DirectoryInfo(_bundleDirectoryPath).LoadAssemblies(_includeSubdirectories);
     6             }
     7             catch (TypeLoadException ex)
     8             {
     9                 LogHelper.Fatal(string.Format("类型“{0}”加载失败。", ex.TypeName), ex);
    10 
    11                 throw;
    12             }
    13             catch (ReflectionTypeLoadException ex)
    14             {
    15                 var extraMessages = ex.LoaderExceptions.Select(x => x.Message).JoinToString();
    16                 LogHelper.Fatal(string.Format("类型“{0}”加载失败,更多信息:{1}。", ex.Types.JoinToString(), extraMessages), ex);
    17 
    18                 throw;
    19             }
    20         }

    日志的使用场景(Error)

    1             _dbContext.OnError(x =>
    2                 LogHelper.Error(
    3                     string.Format("数据库查询(语句:{0},类型:{1},参数:{2})执行出错。", x.Command.CommandText, x.Command.CommandType, this.GetCommandParameters(x.Command)),
    4                     x.Exception
    5                 )
    6             );

    日志的使用场景(监控SQL)

     1             Stopwatch watch = null;
     2 
     3             _dbContext.OnExecuting(x =>
     4             {
     5                 watch = Stopwatch.StartNew();
     6 
     7                 LogHelper.Debug(
     8                     string.Format("数据库查询(语句:{0},类型:{1},参数:{2})正在查询。", x.Command.CommandText, x.Command.CommandType, this.GetCommandParameters(x.Command))
     9                 );
    10             });
    11 
    12             _dbContext.OnExecuted(x =>
    13             {
    14                 watch.Stop();
    15 
    16                 LogHelper.Debug(
    17                     string.Format("数据库查询(语句:{0},类型:{1},执行时间:{2},参数:{3})执行完毕。", x.Command.CommandText, x.Command.CommandType, watch.Elapsed,
    18                                     this.GetCommandParameters(x.Command))
    19                 );
    20             });

    备注

    没有用日志的朋友,请赶快使用日志。

  • 相关阅读:
    EF架构~终于实现了Update方法的统一
    刚刚做了个文件上传功能,拿来分享一下!(MVC架构及传统架构通用)
    关于需求分析,你不能不知道的4个必杀技:捡金子+ Warroom作战室+情节串联板+Build构建 (2/2)
    DockLayout布局
    Linux系统安装出错后出现grub rescue的修复方法
    如何批量清除128组节点db上面的过期的binlog,释放磁盘空间。
    读取Fits数据及画图显示JAVA版
    深入理解Oracle索引(17):Cost 值相同 CBO 对索引的选择
    Xeon Phi之MIC编程知识点
    WDK编译libwdi
  • 原文地址:https://www.cnblogs.com/happyframework/p/3000835.html
Copyright © 2011-2022 走看看