幸福框架:我是如何使用日志的

日志的用途

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

日志的使用原则

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

适合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             });

备注

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

posted on 2013-04-05 15:12  幸福框架  阅读(891)  评论(0编辑  收藏  举报

导航

我要啦免费统计