for WPF developers
Home Profile Tips 全記事一覧

Trace クラスによるログファイル出力

(2016/12/03 0:00:38 created.)

(2016/12/03 0:01:09 modified.)

Trace クラスはプリプロセスシンボル TRACE が定義されていない場合はコンパイル対象にはなりませんが、Release ビルド構成でもシンボル TRACE は定義されるため、リリース後のアプリケーションでもログ情報を残したいときなどに使用します。

Trace クラスでリスナーを追加する方法も前節の Debug クラスによる追加方法と同じで、Trace.Listeners プロパティを用い、TextWriterTraceListener クラスを追加するだけです。さらに、実は Debug.Listeners プロパティも Trace.Listeners プロパティも実体は同じインスタンスを参照していますので、どちらを操作しても同じ結果となります。

Trace クラスには Debug クラスと同様の Write()、WriteLine() メソッドの他に、TraceInformation()、TraceWarning()、TraceError() メソッドというものがあります。それぞれ情報、警告、エラーのためのメッセージ出力をおこなうもので、ただ WriteLine() メソッドでメッセージを出力するよりもトレースレベルなどの情報が付加された形でログが残せます。
ただし、その書式が決まってしまっているので、独自にカスタマイズした書式でログを残したい場合には向いていません。

独自にカスタマイズできるように工夫した DebugTrace クラスをサンプルコードとして掲載します。

Program.cs
  1. namespace Tips_DebugTrace
  2. {
  3.     using System.Diagnostics;
  4.     using System.IO;
  5.     using System.Runtime.CompilerServices;
  6.  
  7.     /// <summary>
  8.     /// デバッグ用トレースをおこなうクラスを表します。
  9.     /// summary>
  10.     public static class DebugTrace
  11.     {
  12.         /// <summary>
  13.         /// ログファイル名
  14.         /// summary>
  15.         private static readonly string _logFilePath = "log.txt";
  16.  
  17.         /// <summary>
  18.         /// ログファイル出力リスナー名
  19.         /// summary>
  20.         private static readonly string _listenerName = "LogFile";
  21.  
  22.         /// <summary>
  23.         /// 初期化時にログファイルをクリアする
  24.         /// summary>
  25.         private static readonly bool _clearLogFileAtInitializing = true;
  26.  
  27.         #region 初期化
  28.         /// <summary>
  29.         /// 静的なコンストラクタです。
  30.         /// summary>
  31.         static DebugTrace()
  32.         {
  33.             Initialize();
  34.         }
  35.  
  36.         /// <summary>
  37.         /// 静的な初期化をおこないます。
  38.         /// Debug 構成のみ有効です。
  39.         /// summary>
  40.         [Conditional("DEBUG")]
  41.         private static void Initialize()
  42.         {
  43.             if (!string.IsNullOrWhiteSpace(_logFilePath))
  44.             {
  45.                 if (_clearLogFileAtInitializing && File.Exists(_logFilePath))
  46.                 {
  47.                     File.Delete(_logFilePath);
  48.                 }
  49.  
  50.                 var fileListener = new TextWriterTraceListener(_logFilePath, _listenerName);
  51.                 Trace.Listeners.Add(fileListener);
  52.                 Trace.AutoFlush = true;
  53.             }
  54.         }
  55.         #endregion 初期化
  56.  
  57.         #region 公開メソッド
  58.         /// <summary>
  59.         /// 情報メッセージを出力します。
  60.         /// summary>
  61.         /// <param name="message">メッセージを指定します。param>
  62.         /// <param name="name">メソッド名を指定します。param>
  63.         /// <param name="filePath">ソースファイルのフルパスを指定します。param>
  64.         /// <param name="lineNumber">行番号を指定します。param>
  65.         [Conditional("DEBUG")]
  66.         public static void TraceInformation(string message, [CallerMemberName]string name = null, [CallerFilePath]string filePath = null, [CallerLineNumber]int lineNumber = 0)
  67.         {
  68.             WriteLine(message, "Information", name, filePath, lineNumber);
  69.         }
  70.  
  71.         /// <summary>
  72.         /// 警告メッセージを出力します。
  73.         /// summary>
  74.         /// <param name="message">メッセージを指定します。param>
  75.         /// <param name="name">メソッド名を指定します。param>
  76.         /// <param name="filePath">ソースファイルのフルパスを指定します。param>
  77.         /// <param name="lineNumber">行番号を指定します。param>
  78.         [Conditional("DEBUG")]
  79.         public static void TraceWarning(string message, [CallerMemberName]string name = null, [CallerFilePath]string filePath = null, [CallerLineNumber]int lineNumber = 0)
  80.         {
  81.             WriteLine(message, "Warning", name, filePath, lineNumber);
  82.         }
  83.  
  84.         /// <summary>
  85.         /// エラーメッセージを出力します。
  86.         /// summary>
  87.         /// <param name="message">メッセージを指定します。param>
  88.         /// <param name="name">メソッド名を指定します。param>
  89.         /// <param name="filePath">ソースファイルのフルパスを指定します。param>
  90.         /// <param name="lineNumber">行番号を指定します。param>
  91.         [Conditional("DEBUG")]
  92.         public static void TraceError(string message, [CallerMemberName]string name = null, [CallerFilePath]string filePath = null, [CallerLineNumber]int lineNumber = 0)
  93.         {
  94.             WriteLine(message, "Error", name, filePath, lineNumber);
  95.         }
  96.         #endregion 公開メソッド
  97.  
  98.         #region ヘルパ
  99.         /// <summary>
  100.         /// メッセージを出力するためのヘルパです。
  101.         /// summary>
  102.         /// <param name="message">メッセージを指定します。param>
  103.         /// <param name="type">メッセージの種別を指定します。param>
  104.         /// <param name="name">メソッド名を指定します。param>
  105.         /// <param name="filePath">ソースファイルのフルパスを指定します。param>
  106.         /// <param name="lineNumber">行番号を指定します。param>
  107.         [Conditional("DEBUG")]
  108.         private static void WriteLine(string message, string type, [CallerMemberName]string name = null, [CallerFilePath]string filePath = null, [CallerLineNumber]int lineNumber = 0)
  109.         {
  110.             var str = string.Format("{0}({1}): {4} :{2} {3}", filePath, lineNumber, name != null ? " [" + name + "]" : "", message, type);
  111.             Trace.WriteLine(str);
  112.         }
  113.         #endregion ヘルパ
  114.     }
  115. }