hBifTs

山自高兮水自深!當塵霧消散,唯事實留傳.荣辱不惊, 看庭前花开花落; 去留随意, 望天上云展云舒.
随笔 - 82, 文章 - 27, 评论 - 442, 阅读 - 25万

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

自己做一个ExceptionLOG

Posted on   hbiftsaa  阅读(2923)  评论(7编辑  收藏  举报

看到了li-new的新文章获得系统异常的详细信息后,想到了前几天玩过的DynamicProxy和AOP,如果把这两个结合起来,不就是一个自定义的异常记录系统了么?
嗯,说做就做.

在这里,我没有使用JGTM的使用RealProxy的方法,原因我已在Dynamic For .NET中说得很明白了,不是吗:)

我们先写一个接口
 public interface ICalculator{
  void Run();
 }
再实现我们的类.
 public class Calculator : ICalculator{
  public void Run(){
   Console.WriteLine("hell,this is the run");
  }
 }

好了..现在我们就得写记录异常信息的类了...
记录异常信息,那得有一个Exception或是它的子类.嗯,Good~,我们写一个接口(为什么要写个接口?直接写类不是方便的多吗?为什么要这么麻烦呢?)
 public interface ILog{
  object LogException(Exception ex);
  void Write(object res);
 }

实现这个接口:
 public class Log : ILog
 {
  #region ILog Members

  public object LogException(Exception ex)
  {
   // TODO:  Add Log.Write implementation
//这个地方的代码取自于获得异常信息的详细信息
   StackTrace trace = new StackTrace(ex,true);
   StackFrame sf;
   string res = "";
   MemberInfo mi;
   for(int i=0;i<trace.FrameCount;i++){
    sf = trace.GetFrame(i);
    mi = sf.GetMethod();
    res = mi.DeclaringType.Namespace + ".";
    //class名
    res = res + mi.DeclaringType.Name + ".";
    res = res + mi.Name;
    //取得文件名(物理路径)、行号,列号
    if(sf.GetFileName() != string.Empty){
     res = res + sf.GetFileName() + ",Line" + sf.GetFileLineNumber() + ",Col" + sf.GetFileColumnNumber();
    }
   }
   Write(res);   
   return res;
  }

  public void Write(object res){
   Console.WriteLine(res);
  }

  #endregion

 }
在这里我们可以看到,LogException(...)函数就是用来从异常中取得信息,Write(...)函数就是用来把得到的异常信息通过命令行显示出来 : )
而且,在这里我是直接在LogException中调用Write的..

好了,记录异常的类Log已经写完了.现在该写在LogFactory类了:P
同样的,我们的LogFactory从DynamicProxy.IProxyInvocationHandler继承(不要问我为什么,去看DynamicProxy的代码自会明白)
public class LogFactory : DynamicProxy.IProxyInvocationHandler
然后再构造函数
由于我们要使用Log这个类来记录异常信息,所以构架函数是这样子的:
  private object target;
  private ILog log;

  public LogFactory(object obj){
   target = obj;
  }

  public LogFactory(object obj,ILog log){
   target = obj;
   this.log = log;
  }

再实现生成动态代理的函数:

  public object Create(){
   return ProxyFactory.GetInstance().Create(this,target.GetType());
  }
这就是函数调用的地方了:

  public object Invoke(object proxy, System.Reflection.MethodInfo method, object[] parameters){
   // TODO:  Add LogFactory.Invoke implementation
   try{   
    object result =  method.Invoke(target,parameters);
    return result;
   }
   catch(Exception ex){
    if(log != null){ //判断log类是否不为空,如果为空,即不用记录:P
     log.LogException(ex);
    }
    return null;
   }
  }

该写的都写了~再就是测试用例了:P
//这里不需要记录异常
  [Test] public void TestRun(){
   ICalculator cal = (ICalculator)(new LogFactory(new Calculator()).Create());
   cal.Run();   
  }

//这里记录异常的信息

  [Test] public void TestLogRun(){
   ICalculator cal = (ICalculator)(new LogFactory(new Calculator(),new Log()).Create());
   cal.Run();
  }

OK了.,,这样子我们就完成了一个简单的异常记录系统(姑且这样子说吧)...
呵呵...我们还可以进一步写我们的XMLLog类,把异常信息记录到一个XML文件中,或是再写一个EnvenLog类,把异常信息放进系统的事件中:P


源代码下载: exceptionLog

编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示