web-dev-qa-db-ja.com

C#での例外のロギング

ロギング例外以下のコードでは、例外の内容をテキストファイルに保存できます。ここでは、エラーの説明のみを取得しています。

ただし、どこで例外が発生したかはわかりません。例外が発生した行番号も取得できるように、どうすればそれを実現できるか教えてもらえますか?

#region WriteLogError
/// <summary>
/// Write an error Log in File
/// </summary>
/// <param name="errorMessage"></param>
public void WriteLogError(string errorMessage)
{
  try
  {
    string path = "~/Error/" + DateTime.Today.ToString("dd-mm-yy") + ".txt";
    if (!File.Exists(System.Web.HttpContext.Current.Server.MapPath(path)))
    {
      File.Create(System.Web.HttpContext.Current.Server.MapPath(path))
     .Close();
    }
    using (StreamWriter w = File.AppendText(System.Web.HttpContext.Current.Server.MapPath(path)))
    {
      w.WriteLine("\r\nLog Entry : ");
      w.WriteLine("{0}", DateTime.Now.ToString(CultureInfo.InvariantCulture));
      string err = "Error in: " + System.Web.HttpContext.Current.Request.Url.ToString() 
                 + ". Error Message:" + errorMessage;
      w.WriteLine(err);
      w.WriteLine("__________________________");
      w.Flush();
      w.Close();
    }
  }
  catch (Exception ex)
  {
    WriteLogError(ex.Message);
  }

}

#endregion
21
happysmile

C#で例外をログに記録する最も簡単な方法は、ToString()メソッドを呼び出すことです。

try
{

}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

通常、これにより、エラーメッセージやスタックトレースなどの必要なすべての情報に加えて、追加の例外固有のコンテキスト情報が提供されます。 (ただし、アプリケーションがデバッグ情報でコンパイルされている場合、スタックトレースにはソースファイルと行番号のみが表示されることに注意してください)

ただし、完全なスタックトレースを表示することは、ユーザーにとってかなり不快になる可能性があるため、可能な限り例外を処理し、よりわかりやすいエラーメッセージを出力するようにしてください。

別のメモ-メソッドWriteLogErrorを完全な機能を備えたロギングフレームワーク( Serilogに置き換える必要があります自分で書こうとする代わりに。

あなたのロギングメソッドはスレッドセーフではありません(ログファイルはおそらくログメッセージが互いに混ざり合うことになるでしょう)そして例外をキャッチした場合それ自身を絶対に呼び出すべきではありません-これはロギングエラーの間に発生する例外がおそらくあることを意味しますStackOverflow例外の診断が困難になります。

それらを修正する方法を提案することもできますが、適切なロギングフレームワークを使用するだけで十分に対応できます。

45
Justin

ToString()をログに記録するだけです。スタックトレースが得られるだけでなく、内部の例外も含まれます。

7
Steven Sudit

また、たとえばコードのリリースビルドを本番環境にデプロイする場合は、リリースパッケージに.pdbファイルを含めることを忘れないでください。除外されたコードの行番号を取得するには、そのファイルが必要です( を参照してください)pdbファイルに含まれる情報の量(C#/ .NET)

4
theburningmonk

あなたの解決策はかなり良いです。私は同じフェーズを通過しました
そして最終的にはどんどんログに記録する必要がありました(それは来るでしょう...):

  • ログソースの場所
  • 例外前の呼び出しスタック(実際には別の場所にある可能性があります)
  • 同じ方法ですべての内部例外
  • プロセスID /スレッドID
  • 時間(またはティックの要求)
  • web用-URL、httpヘッダー、クライアントIP、Cookie、Webセッションコンテンツ
  • 他のいくつかの重要な変数値
  • メモリに読み込まれたアセンブリ
  • ...

エラーが発生したファイルリンクをクリックした方法で、
またはコールスタックのリンクをクリックすると、適切な場所でVisual Studioが開きました。
(もちろん、行う必要があるのは*.PDBファイル、ILコードからのパス
リリースされたソースへのC#が格納されます。)

だから私は最終的にこのソリューションを使い始めました:
Nugetパッケージとして存在-Desharp .
Webとデスクトップの両方のアプリケーションタイプ用です。
Desharp Githubドキュメント を参照してください。多くの設定オプションがあります。

try {
    var myStrangeObj = new { /*... something really mysterious ...*/ };
    throw new Exception("Something really baaaaad with my strange object :-)");
} catch (Exception ex) {

    // store any rendered object in debug.html or debug.log file
    Desharp.Debug.Log(myStrangeObj, Desharp.Level.DEBUG);

    // store exception with all inner exceptions and everything else
    // you need to know later in exceptions.html or exceptions.log file
    Desharp.Debug.Log(ex);
}

HTMLログ形式で、例外はすべて1行で、
そしてブラウザで開くことができるhtmlページから、あなたはクリックすることができます
ファイルリンクからVisual Studioに移動します-本当に中毒性があります!
これだけをインストールする必要があります Desharpエディターオープナー

ここにいくつかのデモを見てください:

これらのリポジトリのいずれかをチェックアウトして、上記の方法で何かをログに記録してみてください。
その後、記録された結果を~/Logsディレクトリ。ほとんどの場合、構成可能です。

1
Tom Flídr

例外クラスはシリアライズ可能であることに注意してください。つまり、組み込みのXmlSerializerを使用して例外クラスをディスクに簡単に書き込むことができます。たとえば、カスタムシリアライザーを使用して、txtファイルに書き込むことができます。

もちろん、出力へのロギングは、他の回答で述べられているようにエラーメッセージを読み取るだけでなく、ToString()を使用して行うこともできます。

例外クラス

https://docs.Microsoft.com/en-us/dotnet/api/system.exception?redirectedfrom=MSDN&view=netframework-4.7.2

シリアル化、オブジェクトをディスク上のファイルに、またはその逆に変換する行為に関する情報。

https://docs.Microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/serialization/

0
sommmen

私は質問に答えるだけです、他の人々はすでにコードについてすでに述べました。ログに行番号を含める場合は、サーバーへのデプロイメントに生成されたデバッグファイル(pdb)を含める必要があります。それがあなたのDev/Testリージョンだけでも問題ないが、本番環境での使用はお勧めしません。

0
Naveen