博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用StackTrace堆栈跟踪记录详细日志(可获取行号)
阅读量:6328 次
发布时间:2019-06-22

本文共 8465 字,大约阅读时间需要 28 分钟。

  上一篇我们提到使用.NET自带的TraceSource实现简单的日志,具体请看《》,这一篇注意想讲的是日志的详细记录,包含请求开始到结束的过程中调用的方法链以及记录日志那一刻的类名,方法名,行号等。

  其实也就是堆栈的跟踪了,微软为我们提供了一个对堆栈跟踪的对象StackTrace,具体信息请看 .

  下面是对TraceSourceLogger类的改进:

1     public sealed class TraceSourceLogger  2         :ILogger  3     {  4   5         TraceSource _source;  6   7         public TraceSourceLogger()  8         {  9             _source = new TraceSource("Bulrush"); 10         } 11  12         public void Fatal(string message, params object[] args) 13         { 14             if (String.IsNullOrWhiteSpace(message)) 15                 return; 16  17             string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args); 18             TraceStack(TraceEventType.Critical, messageToTrace); 19         } 20  21         public void Fatal(string message, Exception exception, params object[] args) 22         { 23             if (String.IsNullOrWhiteSpace(message) || exception == null) 24                 return; 25  26             string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args); 27             TraceException(TraceEventType.Critical, exception, messageToTrace); 28         } 29  30         public void Infomation(string message, params object[] args) 31         { 32             if (String.IsNullOrWhiteSpace(message)) 33                 return; 34  35             string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args); 36             Trace(TraceEventType.Information, messageToTrace); 37         } 38  39         public void Warning(string message, params object[] args) 40         { 41             if (String.IsNullOrWhiteSpace(message)) 42                 return; 43  44             string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args); 45             Trace(TraceEventType.Warning, messageToTrace); 46         } 47  48         public void Error(string message, params object[] args) 49         { 50             if (String.IsNullOrWhiteSpace(message)) 51                 return; 52  53             string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args); 54             TraceStack(TraceEventType.Error, messageToTrace); 55         } 56  57         public void Error(string message, Exception exception, params object[] args) 58         { 59             if (String.IsNullOrWhiteSpace(message) || exception == null) 60                 return; 61  62             string messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args); 63             TraceException(TraceEventType.Error, exception, messageToTrace); 64         } 65  66         void Trace(TraceEventType eventType, string message) 67         { 68             if (_source != null) 69             { 70                 try 71                 { 72                     _source.TraceEvent(eventType, (int)eventType, message); 73                 } 74                 catch (SecurityException) 75                 { 76                     //这里处理写入是出现的安全问题,如文件没有写入权限。 77                 } 78             } 79         } 80  81         void TraceStack(TraceEventType eventType, string message) 82         { 83             string stackMessage = BuildStackTraceMessage(); 84             string messageToTrace = message + Environment.NewLine + Environment.NewLine + stackMessage; 85  86             Trace(eventType, messageToTrace); 87         } 88  89         void TraceException(TraceEventType eventType, Exception ex, string message) 90         { 91             StringBuilder builder = new StringBuilder(); 92             builder.AppendFormat("错误信息:{0}", message).AppendLine(); 93             builder.AppendFormat("异常信息:{0}", ex.Message).AppendLine(); 94             builder.AppendFormat("异常类型:{0}", ex.GetType().Name).AppendLine(); 95  96             string stackMessage = BuildStackTraceMessage(); 97             builder.Append(stackMessage); 98  99             Trace(eventType, builder.ToString());100         }101 102         string BuildStackTraceMessage()103         {104             StackTrace trace = new StackTrace(true);105             return BuildStackTraceMessage(trace);106         }107 108         string BuildStackTraceMessage(StackTrace stackTrace)109         {110             if (stackTrace != null)111             {112                 var frameList = stackTrace.GetFrames();113                 var realFrameList = frameList.Where(i => i.GetMethod().DeclaringType != this.GetType() && i.GetFileLineNumber() > 0);114                 if (realFrameList.Any())115                 {116                     StringBuilder builder = new StringBuilder();117                     realFrameList = realFrameList.Reverse();118                     var lastFrame = realFrameList.Last();119                     builder.AppendFormat("源文件:{0}", lastFrame.GetFileName()).AppendLine();120                     builder.AppendFormat("行号:{0}", lastFrame.GetFileLineNumber()).AppendLine();121                     builder.AppendFormat("方法名:{0}", lastFrame.GetMethod().ToString()).AppendLine();122                     builder.AppendLine("堆栈跟踪:");123                     builder.AppendLine("=================================================================");124 125                     MethodBase method;126                     foreach (var frame in realFrameList)127                     {128                         method = frame.GetMethod();129                         builder.AppendFormat("> {0} 类下的第{1}行 {2} 方法", method.DeclaringType.ToString(), frame.GetFileLineNumber(), method.ToString()).AppendLine();130                     }131                     builder.AppendLine("=================================================================");132                     return builder.ToString();133                 }134             }135             return "没有堆栈信息";136         }137     }

最主要的部分在于BuildStackTraceMessage这个方法

1     string BuildStackTraceMessage(StackTrace stackTrace) 2         { 3             if (stackTrace != null) 4             { 5                 var frameList = stackTrace.GetFrames(); 6                 var realFrameList = frameList.Where(i => i.GetMethod().DeclaringType != this.GetType() && i.GetFileLineNumber() > 0); 7                 if (realFrameList.Any()) 8                 { 9                     StringBuilder builder = new StringBuilder();10                     realFrameList = realFrameList.Reverse();11                     var lastFrame = realFrameList.Last();12                     builder.AppendFormat("源文件:{0}", lastFrame.GetFileName()).AppendLine();13                     builder.AppendFormat("行号:{0}", lastFrame.GetFileLineNumber()).AppendLine();14                     builder.AppendFormat("方法名:{0}", lastFrame.GetMethod().ToString()).AppendLine();15                     builder.AppendLine("堆栈跟踪:");16                     builder.AppendLine("=================================================================");17 18                     MethodBase method;19                     foreach (var frame in realFrameList)20                     {21                         method = frame.GetMethod();22                         builder.AppendFormat("> {0} 类下的第{1}行 {2} 方法", method.DeclaringType.ToString(), frame.GetFileLineNumber(), method.ToString()).AppendLine();23                     }24                     builder.AppendLine("=================================================================");25                     return builder.ToString();26                 }27             }28             return "没有堆栈信息";29         }

下面这句代码是为了去除.NET FrameWork方法的堆栈跟踪和当前记录日志方法的跟踪,i.GetFileLineNumber() > 0行号大于0表示为获取当前项目方法的堆栈跟踪。

1 var realFrameList = frameList.Where(i => i.GetMethod().DeclaringType != this.GetType() && i.GetFileLineNumber() > 0);

下面我们做个测试:

 

[TestMethod]        public void TestTraceSourceLogger()        {            GetMyNumber();        }        private int GetMyNumber()        {            ILoggerFactory factory = new TraceSourceLoggerFactory();            LoggerContext.SetCurrent(factory);            try            {                var number = int.Parse("我要转成Int32类型");                return number;            }            catch (FormatException)            {                LoggerContext.CreateLog().Error("字符串无法转换为Int32类型");            }            return 0;        }

日志的记录结果如下:

 

当然也可以将异常的直接扔到StackTrace中,获取详细的堆栈,但是这样无法获取从请求那一刻开始的方法链的跟踪。

还有一个是乎无法解决的问题,就是获取详细的代码行,估计微软也是为了确保程序的安全性吧,要是一不小心显示出关键代码被人拿走了就糟糕了,如果有哪位大牛知道怎么获取的话,麻烦指点指点!!

 

出处:http://www.cnblogs.com/zcylife/p/3690300.html

你可能感兴趣的文章
低版本mybatis不能用PageHeper插件的时候用这个分页
查看>>
javaweb使用自定义id,快速编码与生成ID
查看>>
[leetcode] Add Two Numbers
查看>>
elasticsearch suggest 的几种使用-completion 的基本 使用
查看>>
04-【MongoDB入门教程】mongo命令行
查看>>
Hadoop HA元数据备份
查看>>
字符串与整数之间的转换
查看>>
断点传输HTTP和URL协议
查看>>
redis 数据类型详解 以及 redis适用场景场合
查看>>
mysql服务器的主从配置
查看>>
巧用AJAX技术,通过updatePanel控件实现局部刷新
查看>>
20140420技术交流活动总结
查看>>
SaltStack配置salt-api
查看>>
各种情况下block的类型
查看>>
ThinkPHP 3.2.x 集成极光推送指北
查看>>
MYSQL 表情评论存储(emoji)
查看>>
js作用域链
查看>>
java中如何选择Collection Class--java线程(第3版)
查看>>
ASP.NET页面之间传递值的几种方式
查看>>
Linux系统权限
查看>>