3

私は現在Windowsサービスのメンテナンスを行っており、コードの特定の時点でいくつかの例外処理があります(たとえば、タイマーやその他の外部イベントからのコールバック)。

try {
  ...
}
catch (Exception ex) {
   _logger.Log("Unhandled exception: {0}\r\n{1}", ex.Message, ex.StackTrace);
   Environment.FailFast("Fatal error.");
}

例外情報をログに記録すると、問題のトラブルシューティングに役立ちます。ただし、興味深い情報が内部例外である場合があり、問題の根本原因を特定するのが困難になります。たとえば、aTypeInitializationExceptionは理解しにくい場合があります。

トラブルシューティングの目的で例外情報をログに記録するためのより良い方法はありますか?

4

3 に答える 3

7

トラブルシューティングの目的で例外情報をログに記録するためのより良い方法はありますか?

はいあります。ex.Message「賢く」して使用しないでくださいex.StackTrace。を使用するだけex.ToString()です。内部例外(必要に応じて複数のレベル)に再帰し、完全なスタックトレースを表示します。

try {
  ...
}
catch (Exception ex) {
   _logger.Log("Unhandled exception:\r\n{0}", ex);
   Environment.FailFast("Fatal error.");
}

簡単な例を示すと、これは、クラスの静的コンストラクターで例外をスローするクラスのインスタンスを作成した場合に得られるものです。この例外スローは。でラップされますTypeInitializationException

前:

未処理の例外:「SomeClass」の型初期化子が例外をスローしました。
   SomeNamespace.SomeClass..ctor()で
   c:\ ExceptionHandlingDemo.cs:line 34のSomeNamespace.Callback()で

あまり役に立ちません。何が悪かったのかを判断するのは難しいです。

後:

未処理の例外:
System.TypeInitializationException:「SomeClass」の型初期化子が例外をスローしました。---> System.ArgumentException:同じキーを持つアイテムがすでに追加されています。
   System.ThrowHelper.ThrowArgumentException(ExceptionResourceリソース)で
   System.Collections.Generic.Dictionary`2.Insert(TKey key、TValue value、Boolean add)で
   System.Collections.Generic.Dictionary`2.Add(TKey key、TValue value)で
   c:\ ExceptionHandlingDemo.cs:line 43のSomeNamespace.SomeClass..cctor()で
   ---内部例外スタックトレースの終わり---
   SomeNamespace.SomeClass..ctor()で
   c:\ ExceptionHandlingDemo.cs:line 34のSomeNamespace.Callback()で

これで、辞書のキーが重複しているという問題の根本原因を簡単に特定し、ソースファイルの43行目に特定することができます。

于 2012-08-10T08:51:19.813 に答える
0

これが役立つかどうかはわかりません。例外のすべての情報をログに記録するために、このユーティリティ クラスを作成しました。情報をログに記録するには、Exception.DataException.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
                    }
    }
}
于 2013-02-22T15:27:59.873 に答える
0

これが役立つかどうか、またはレベルが高すぎるかどうかはわかりませんが、Microsoft の Enterprise Library をご存知ですか? ( http://msdn.microsoft.com/en-us/library/ff648951.aspx )。

その中には、大ハンマーのようなロギング「アプリケーションブロック」がありますが、最終的には非常に強力/柔軟です。私が望むように設定する演習を行った後(すべて構成主導)、これは私が構築するすべてのものの標準になりました。

特に例外を除いて、意味のある情報を得るために多くのことをする必要はまったくなかったと思います。

于 2012-08-10T10:49:45.197 に答える