TraceクラスのWriteメソッド(または、WriteLine、WriteIf、WriteLineIfなどのメソッド)はデフォルトでは出力ウィンドウだけにメッセージを出力します。ここでは、これをファイルにも出力する方法を紹介します。
なお、後述しますが、ここで紹介している方法はDebugクラスのWriteメソッドでも有効です。
簡単な方法は、DefaultTraceListenerクラスのLogFileNameプロパティに出力ファイル名を指定する方法です。Trace.ListenersプロパティのコレクションにはデフォルトでDefaultTraceListenerオブジェクトが格納されているため(名前は"Default")、これを取得し、LogFileNameプロパティを設定してあげれば、ログが書き込まれるようになります。
次の例では、この方法により、"C:\test\1.txt"ファイルに書き込むようにしています。ちなみに、ファイルには追加書込みされます。
'Imports System.Diagnostics 'がソースファイルの一番上に書かれているものとする 'DefaultTraceListenerオブジェクトを取得 Dim drl As DefaultTraceListener drl = CType(Trace.Listeners("Default"), DefaultTraceListener) 'LogFileNameを変更する drl.LogFileName = "C:\test\1.txt"
//using System.Diagnostics; //がソースファイルの一番上に書かれているものとする //DefaultTraceListenerオブジェクトを取得 DefaultTraceListener drl; drl = (DefaultTraceListener) Trace.Listeners["Default"]; //LogFileNameを変更する drl.LogFileName = "C:\\test\\1.txt";
Trace.Listenersプロパティが返すリスナのコレクションは、Debug.Listenersプロパティが返すリスナのコレクションと共通です。よってTrace.Listenersプロパティに加えた変更は、Debugクラスにも適用されます。例えば上記のコードを実行すると、Trace.Writeだけでなく、Debug.Writeでもファイルに書き込まれるようになります。
正攻法としては、Trace.ListenersプロパティのコレクションにTextWriterTraceListenerオブジェクトを追加することで、ファイルに書き込むことができます。
先ほどのDefaultTraceListenerは、AssertUiEnabledプロパティがTrueならば、Trace.AssertやTrace.Failメソッドが呼び出された時にメッセージボックスを表示しますが、TextWriterTraceListenerは表示しません。
次の例では、出力先ファイルを"C:\test\1.txt"としたTextWriterTraceListenerオブジェクトを作成し、Trace.Listenersに追加しています。
'Imports System.Diagnostics 'がソースファイルの一番上に書かれているものとする 'DefaultTraceListenerが必要なければ削除する Trace.Listeners.Remove("Default") '出力先ファイルを C:\test\1.txt、名前を LogFile として 'TextWriterTraceListenerオブジェクトを作成 Dim twtl As New TextWriterTraceListener("C:\test\1.txt", "LogFile") 'リスナコレクションに追加する Trace.Listeners.Add(twtl)
//using System.Diagnostics; //がソースファイルの一番上に書かれているものとする //DefaultTraceListenerが必要なければ削除する Trace.Listeners.Remove("Default"); //出力先ファイルを C:\test\1.txt、名前を LogFile として //TextWriterTraceListenerオブジェクトを作成 TextWriterTraceListener twtl = new TextWriterTraceListener("C:\\test\\1.txt", "LogFile"); //リスナコレクションに追加する Trace.Listeners.Add(twtl);
Trace.AutoFlushプロパティがFalseの時、実際にファイルに書込みが行われるのは、CloseやFlashメソッドを呼び出した時となります。Trace.AutoFlushをTrueにすることなく自動的にフラッシュされるようにするには、次のようにAutoFlushプロパティをTrueにしたTextWriterオブジェクトを使います。
'Imports System.Diagnostics 'Imports System.IO 'がソースファイルの一番上に書かれているものとする '出力ファイルを指定して、StreamWriterオブジェクトを作成 Dim sw As New StreamWriter("C:\test\1.txt") '自動的にフラッシュされるようにする sw.AutoFlush = True 'スレッドセーフラッパを作成 Dim tw As TextWriter = TextWriter.Synchronized(sw) '名前を LogFile としてTextWriterTraceListenerオブジェクトを作成 Dim twtl As New TextWriterTraceListener(tw, "LogFile") 'リスナコレクションに追加する Trace.Listeners.Add(twtl)
//using System.Diagnostics; //using System.IO; //がソースファイルの一番上に書かれているものとする //出力ファイルを指定して、StreamWriterオブジェクトを作成 StreamWriter sw = new StreamWriter("C:\\test\\1.txt"); //自動的にフラッシュされるようにする sw.AutoFlush = true; //スレッドセーフラッパを作成 TextWriter tw = TextWriter.Synchronized(sw); //名前を LogFile としてTextWriterTraceListenerオブジェクトを作成 TextWriterTraceListener twtl = new TextWriterTraceListener(tw, "LogFile"); //リスナコレクションに追加する Trace.Listeners.Add(twtl);
トレースのリスナコレクションにリスナを追加、削除する方法は上記のようにコードによる方法以外に、アプリケーション構成ファイルを使った方法もあります。(アプリケーション構成ファイルについては、こちらをご覧ください。)
アプリケーション構成ファイルを次のように書くことにより、出力先ファイル"C:\test\1.txt"、名前"LogFile"のTextWriterTraceListenerがトレースのリスナコレクションに追加され、DefaultTraceListenerが削除されます。ここではTraceのAutoFlushをTrueとし、インデントするスペースを4としています。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <trace autoflush="true" indentsize="4"> <listeners> <add name="LogFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\test\1.txt" /> <remove name="Default"/> </listeners> </trace> </system.diagnostics> </configuration>
補足:.NET Framework 2.0からは、<sharedListeners>要素を使ってリスナの設定を記述することもできます。複数のTraceが同じリスナを使う場合に便利です。これを使った例は、こちらで紹介します。
アプリケーション構成ファイルにより、Trace.AssertやFailメソッドでメッセージボックスを表示せずにログファイルに書き込むように設定することもできます。アプリケーション構成ファイルを次のように書くことにより、Trace.AssertやFailメソッドでメッセージボックスを表示せずに、"C:\test\1.txt"に出力されるようになります。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <assert assertuienabled="false" logfilename="C:\test\1.txt"/> </system.diagnostics> </configuration>
コンソールアプリケーションにおいて、Trace.Writeでコンソールにメッセージを出力できるようにするには、次のようにConsoleTraceListenerクラスを使用します。
'Imports System.Diagnostics 'がソースファイルの一番上に書かれているものとする 'コンソールに出力されるようにする Dim ctl As New ConsoleTraceListener() 'Trace.Listenersに追加する Trace.Listeners.Add(ctl)
//using System.Diagnostics; //がソースファイルの一番上に書かれているものとする //コンソールに出力されるようにする ConsoleTraceListener ctl = new ConsoleTraceListener(); //Trace.Listenersに追加する Trace.Listeners.Add(ctl);
.NET Framework 1.1以前ではConsoleTraceListenerが使えませんが、以下のようにTextWriterTraceListenerとConsole.Outプロパティを使うことで可能です。
'Imports System.Diagnostics 'がソースファイルの一番上に書かれているものとする 'コンソールの出力ストリームからTextWriterTraceListenerを作成 Dim twtl As New TextWriterTraceListener(System.Console.Out) 'Trace.Listenersに追加する Trace.Listeners.Add(twtl)
//using System.Diagnostics; //がソースファイルの一番上に書かれているものとする //コンソールの出力ストリームからTextWriterTraceListenerを作成 TextWriterTraceListener twtl = new TextWriterTraceListener(System.Console.Out); //Trace.Listenersに追加する Trace.Listeners.Add(twtl);
なお、トレースのリスナとして.NET Frameworkで用意されているクラスには上記で説明したDefaultTraceListener、TextWriterTraceListenerの他にも様々あります。以下にトレースのリスナとして使えるクラスを紹介します。
クラス名 | 説明 |
---|---|
DefaultTraceListener | 通常、WriteメソッドでVisual Studioの出力ウィンドウに出力される。また、既定では、Failメソッドでメッセージボックスを表示する。 |
TextWriterTraceListener | テキストライタやストリームに出力する。 |
EventLogTraceListener | イベントログに出力する。 |
FileLogTraceListener | テキストファイルに出力する。Microsoft.VisualBasic.Logging名前空間にある。.NET Framework 2.0から追加。 |
ConsoleTraceListener | コンソールに出力する。.NET Framework 2.0から追加。 |
DelimitedListTraceListener | 指定した区切り記号を使用する、区切られたテキスト形式のテキストライタやストリームに出力する。.NET Framework 2.0から追加。 |
XmlWriterTraceListener | XMLエンコードされたテキストライタやストリームに出力する。.NET Framework 2.0から追加。 |
WebPageTraceListener | ASP.NET Webページに出力する。System.Web名前空間にある。.NET Framework 2.0から追加。 |
補足:DefaultTraceListener.Writeメソッドは、Debugger.IsLoggingメソッドがTrueを返すならDebugger.Logメソッドを呼び出し、Falseを返すならOutputDebugString関数を呼び出します。また、Debugger.LogメソッドはOutputDebugString関数を呼び出します。OutputDebugString関数で送信されたメッセージは通常Visual Studioの出力ウィンドウに表示されますが、DebugViewのようなツールを使っても表示することができます。
EventLogTraceListenerを使った例を示します。次のコードでは、Trace.Writeでイベントログにメッセージが出力されるようにしています。
'Imports System.Diagnostics 'がソースファイルの一番上に書かれているものとする 'イベントログソース名を"MySouce"として出力するようにする Dim eltl As New EventLogTraceListener("MySource") 'Trace.Listenersに追加する Trace.Listeners.Add(eltl)
//using System.Diagnostics; //がソースファイルの一番上に書かれているものとする //イベントログソース名を"MySouce"として出力するようにする EventLogTraceListener eltl = new EventLogTraceListener("MySource"); //Trace.Listenersに追加する Trace.Listeners.Add(eltl);
.NET Framework 2.0で使用できるリスナをアプリケーション構成ファイルによりTraceに追加する例を示します。アプリケーション構成ファイルを以下のようにして、listeners要素内の使用したいリスナのコメントアウトを元に戻すだけです。ログを書き込む位置などは適当に書き換えてください。(こちらを参考にして作成しました。)
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <trace autoflush="true" indentsize="4"> <listeners> <!-- <add name="EventLog" /> --> <!-- <add name="TextLog" /> --> <!-- <add name="Delimited" /> --> <!-- <add name="XmlWriter" /> --> <!-- <add name="Console" /> --> <!-- <add name="FileLog" /> --> </listeners> </trace> <sharedListeners> <add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="sample application" /> <add name="TextLog" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\test\TextLog.txt" /> <add name="Delimited" type="System.Diagnostics.DelimitedListTraceListener" initializeData="C:\test\DelimitedLog.txt" delimiter="," traceOutputOptions="DateTime" /> <add name="XmlWriter" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\test\Log.xml" /> <add name="Console" type="System.Diagnostics.ConsoleTraceListener" initializeData="true" /> <add name="FileLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener" initializeData="FileLogWriter" /> </sharedListeners> </system.diagnostics> </configuration>