如何记录exception信息以进行故障排除?
我目前正在对Windows服务进行维护,并且在代码中的某些点处存在一些exception处理(例如,来自计时器和其他外部事件的回调):
try { ... } catch (Exception ex) { _logger.Log("Unhandled exception: {0}\r\n{1}", ex.Message, ex.StackTrace); Environment.FailFast("Fatal error."); }
记录exception信息有助于排除出错的问题。 但是,有时候有趣的信息是内部exception,这使得很难确定问题的根本原因。 例如, TypeInitializationException
可能很难理解。
是否有更好的方法来记录exception信息以进行故障排除?
是否有更好的方法来记录exception信息以进行故障排除?
就在这里。 不要“聪明”并使用ex.Message
和ex.StackTrace
。 只需使用ex.ToString()
。 它将递归到内部exception(如果需要,可以是多个级别)并显示完整的堆栈跟踪。
try { ... } catch (Exception ex) { _logger.Log("Unhandled exception:\r\n{0}", ex); Environment.FailFast("Fatal error."); }
为了提供一个小例子,如果您创建一个在类的静态构造函数中抛出exception的类的实例,那么这就是您所获得的。 此exceptionthrow将包装在TypeInitializationException
。
之前:
未处理的exception:'SomeClass'的类型初始值设定项引发了exception。 at SomeNamespace.SomeClass..ctor() 在C:\ ExceptionHandlingDemo.cs中的SomeNamespace.Callback():第34行
不是很有帮助。 很难确定出了什么问题。
后:
未处理的exception: System.TypeInitializationException:'SomeClass'的类型初始值设定项引发了exception。 ---> System.ArgumentException:已添加具有相同键的项。 在System.ThrowHelper.ThrowArgumentException(ExceptionResource资源) 在System.Collections.Generic.Dictionary`2.Insert(TKey键,TValue值,布尔加法) 在System.Collections.Generic.Dictionary`2.Add(TKey键,TValue值) 在C:\ ExceptionHandlingDemo.cs中的SomeNamespace.SomeClass..cctor():第43行 ---内部exception堆栈跟踪结束--- at SomeNamespace.SomeClass..ctor() 在C:\ ExceptionHandlingDemo.cs中的SomeNamespace.Callback():第34行
现在,您可以非常轻松地确定问题的根本原因是字典中的重复键,并将其精确定位到源文件中的第43行。
我不知道这是否会有所帮助,或者它是否过高,但您是否了解微软的企业库? ( http://msdn.microsoft.com/en-us/library/ff648951.aspx )。
在其中有一个记录“应用程序块”,它是一个大锤,但最终非常强大/灵活。 经历了我想要的设置(它的所有配置驱动),这现在是我构建的exerything的标准。
特别是在例外情况下,我认为我不必为了获得有意义的信息而做很多事情。
我不确定这是否会有所帮助。 我编写了这个Utility类来记录exception的所有信息,我使用Exception.Data和Exception.Message来记录信息
这里分享的东西: https : //stackoverflow.com/a/15005319/1060656
public class ExceptionInfoUtil { public static string GetAllExceptionInfo(Exception ex) { StringBuilder sbexception = new StringBuilder(); int i = 1; sbexception.Append(GetExceptionInfo(ex, i)); while (ex.InnerException != null) { i++; ex = ex.InnerException; sbexception.Append(GetExceptionInfo(ex, i)); } return sbexception.ToString(); } private static string GetExceptionInfo(Exception ex, int count) { StringBuilder sbexception = new StringBuilder(); sbexception.AppendLine(string.Format("")); sbexception.AppendLine(string.Format("")); sbexception.AppendLine(string.Format("************************************************")); sbexception.AppendLine(string.Format("************************************************")); sbexception.AppendLine(string.Format(" Inner Exception : No.{0} ", count)); sbexception.AppendLine(string.Format("************************************************")); sbexception.AppendLine(string.Format("==================================================")); sbexception.AppendLine(string.Format(" Error Message : {0} ", ex.Message)); sbexception.AppendLine(string.Format("==================================================")); #region Mine Thru data dictionary try { sbexception.AppendLine(string.Format("==================================================")); sbexception.AppendLine(string.Format(" Data parameters Count at Source :{0}", ex.Data.Count)); sbexception.AppendLine(string.Format("==================================================")); string skey = string.Empty; foreach (object key in ex.Data.Keys) { try { if (key != null) { skey = Convert.ToString(key); sbexception.AppendLine(string.Format(" Key :{0} , Value:{1}", skey, Convert.ToString(ex.Data[key]))); } else { sbexception.AppendLine(string.Format(" Key is null")); } } catch (Exception e1) { sbexception.AppendLine(string.Format("** Exception occurred when writting log *** [{0}] ", e1.Message)); } } } catch (Exception ex1) { sbexception.AppendLine(string.Format("** Exception occurred when writting log *** [{0}] ", ex1.Message)); } #endregion sbexception.AppendLine(string.Format("==================================================")); sbexception.AppendLine(string.Format(" Source : {0} ", ex.Source)); sbexception.AppendLine(string.Format("==================================================")); sbexception.AppendLine(string.Format(" StackTrace : {0} ", ex.StackTrace)); sbexception.AppendLine(string.Format("==================================================")); sbexception.AppendLine(string.Format(" TargetSite : {0} ", ex.TargetSite)); sbexception.AppendLine(string.Format("************************************************")); sbexception.AppendLine(string.Format(" Finished Writting Exception info :{0} ", count)); sbexception.AppendLine(string.Format("************************************************")); sbexception.AppendLine(string.Format("************************************************")); sbexception.AppendLine(string.Format("")); sbexception.AppendLine(string.Format("")); return sbexception.ToString(); } }
下面是使用此实用程序类的示例类
[Serializable] public class FlatFileItem { ArrayList errorlist = new ArrayList(); public FlatFileItem() { if (errorlist == null) { errorlist = new ArrayList(); } } //Name of the file public string FileName { get; set; } public override string ToString() { return string.Format(@"FlatFileItem (Unzip FTPLineItem) => FileName:{0}", this.FileName); } } public class someclass { public void somemethod(){ try{ //Throw exception code } catch (Exception ex) { ex.Data["flatfile"] = Convert.ToString(flatfile); //Using data property flatfile.HasErrors = true; //not there in above example flatfile.Parent.AddErrorInfo(ex); //not there in above example logger.Error(String.Format(ex.Message)); //not there in above example throw ( new Exception ("yourmsg",ex)); //if you want to do this } } }