.NET用定番コンポーネントを紹介する新連載。まずは構成ファイルの修正だけでカスタマイズ可能な「log4net」を解説。
powered by Insider.NET
アプリケーションの開発では、コーディングが完了して動作確認をしたらきっぱり開発者の手を離れる……などということはほとんどないでしょう。コンシューマ向けのパッケージ作成であれば入念な動作テストが行われた後にリリースということになるでしょうが、特に社内で使用するアプリケーションの作成では、配布後にいろいろな修正要求や「うまく動かないんだけど……」といったリクエストを受け取ることが多々あります。
ユーザーからの「うまく動かない」という報告があった場合、「動かない」状況をきちんと(開発者が納得できるような)説明をしてもらえることは(まずほとんど)期待できません。そのためアプリケーションにログ機能を持たせ、ログ・ファイルに実行状態を書き込んだり、エラー発生時にはイベント・ログを出力するなどして問題が発生した場合の原因特定の手掛かりを残しておくことは不可欠ともいえます。
Visual Basic(以降、VB)では、My.Application.Logオブジェクトを使ってログを記録できますが、本稿では、オープンソースとして公開されているApache Logging Services Projectの「log4net」というログ作成ツールを紹介します。log4netはJava用に作成されたログ作成ツールである「log4j」をベースに作成されたもので、.NET Framework用のlog4net以外にも、C++用のlog4cxx、PHP用のlog4phpなども提供されています。
log4netの特徴はなんといってもログの出力先の構成の柔軟さにあります。通常のファイルに出力することはもちろん、一定のファイル・サイズでログ・ファイルを切り替えたり、月ごとにログ・ファイルを分けたり、イベント・ログを出力先にしたり、さらにはSQL Serverにログを書き込むことや、ログをメール送信することも可能です。構成の変更はビルド後でも行えるので、ログ出力の構成を変更するのにコードを修正したり、再ビルドしたりする必要はありません。
まずはlog4netを使った簡単なサンプルを紹介しましょう。
log4netは、「Download Apache log4net」のページからソース・コードとバイナリが含まれたZIPファイルをダウンロードできます(本稿執筆時点の最新バージョンは1.2.10で、ダウンロードできるファイルは「incubating-log4net-1.2.10.zip」)。
ダウンロードしたZIPファイルを展開すると、さまざまなターゲット向けのバイナリやドキュメント、ソース・ファイルなどが含まれているのが分かりますが、VB 2005でlog4netを利用する場合は、bin\net\2.0にあるlog4net.dllを使用します。.NET Framework 1.1を使用する場合は、bin\net\1.1に含まれるlog4net.dllを使用します。なお、ZIPファイルを展開するフォルダはどこでも構いません。
■VB 2005でプロジェクトを作成
ここでは、一番シンプルなWindows用のアプリケーションであるコンソール・アプリケーションを作成します。Visual Studio 2005からプロジェクトの新規作成でコンソール・アプリケーションのテンプレートを選択して、プロジェクトを作成します。
■参照の追加
プロジェクトが作成できたら、プロジェクトからlog4netが利用できるように「参照の追加」を行います。
これには、ソリューション・エクスプローラに表示されているプロジェクトを右クリックして表示されるメニューから[参照の追加]を選択し、先ほどのlog4net.dllを追加します。ソリューション・エクスプローラのツールバーから[すべてのファイルを表示]ボタンをクリックしておくとプロジェクトのツリーの中に「参照設定」という項目が表示されますので、そこから[参照の追加]を行ってもよいでしょう。
■アプリケーション構成ファイル「app.config」の追加
log4netの構成を記述するためにアプリケーション構成ファイルである「app.config」を用意します。これもソリューション・エクスプローラでプロジェクトを右クリックして[追加]−[新しい項目]を選択してから、テンプレートとして「アプリケーション構成ファイル」を選択します。ファイル名はapp.configのままで大丈夫です。
■log4netを使用できるようにコードを追加
次にlog4netのアセンブリ情報を追加します。これはlog4netの初期値を指定するもので、構成ファイルの名前や、構成情報が修正された際に構成情報を再ロードするように構成情報の監視(Watch:=True)を指定します。ここでは、構成ファイルはデフォルトのまま(app.config)ですので、構成情報のファイル名の指定は行っていません(ASP.NETの場合については後述します)。ソリューション・エクスプローラから「My Project」の項目を展開して、コード・エディタでAssemblyInfo.vbを開きます*1。そして、AssemblyInfo.vbの最後に次の1行を追加します。
<Assembly: log4net.Config.XmlConfigurator(Watch:=True)>
*1 ソリューション・エクスプローラに「My Project」が表示されていない場合は、ソリューション・エクスプローラのツールバーの「すべてのファイルを表示」をオンにしてください。
■アプリケーション構成ファイルの修正
続いては、どんな媒体にログを出力するかというlog4netの構成を決めます。この構成は、先ほど作成したapp.configに記述していきます。
app.configにすでに記述されている内容はそのままにして、リスト1に示すように<configuration>要素の中に<configSection>要素と<log4net>要素を追加します。ここでは最低限のログ出力ということで、ファイルにログを出力するように設定しています。リスト1では、「C:\log-file.txt」に追加でログを書き込む指定を行っています(内容についての解説は後述)。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type=" log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net>
<!-- ログ出力先の定義 -->
<appender name="LogFileAppender"
type="log4net.Appender.FileAppender" >
<!-- 作成するログファイル -->
<param name="File" value="C:\log-file.txt" />
<!-- 追加 -->
<param name="AppendToFile" value="true" />
<!-- ログの書式 -->
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern"
value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<root>
<!-- ログのレベルを指定 -->
<!-- すべてのログレベルを出力 -->
<level value="ALL" />
<!-- どのログ出力先を使用するか -->
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
<!-- (自動生成された部分は省略) -->
</configuration>
■ログ出力のコード追加
以上でログを作成する準備ができました。最後にソース・コードにログを記録するコードを記述していきます。
まず、ログ出力を行うオブジェクト(インスタンス)を取得する必要があります。これには、
ReadOnly log As log4net.ILog = _
log4net.LogManager.GetLogger( _
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
というコードをModule内の先頭に記述しておきます。このコードはlog4net利用時の定型的なものなので、オマジナイだと思ってコピー&ペーストしておけばよいでしょう。これによりlogという名前のオブジェクトを使ってログの出力が行えるようになります。
自分で定義したクラスでログを出力したい場合は、クラス定義の先頭部分に、
Private Shared ReadOnly log As log4net.ILog = _
log4net.LogManager.GetLogger( _
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
と記述しておき、クラス内のメソッドでlogオブジェクトのメソッドを呼び出せるようにしておきます。
log4netでログを出力するプログラムは、例えば次のリスト2のようになります。
Module Module1
ReadOnly log As log4net.ILog = _
log4net.LogManager.GetLogger( _
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
Sub Main()
Console.WriteLine("program started.")
log.Debug("Program Started")
Dim myobj As New someclass
myobj.mymethod()
log.Fatal("Program が終了します")
End Sub
End Module
Public Class someclass
Private Shared ReadOnly log As log4net.ILog = _
log4net.LogManager.GetLogger( _
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
Public Sub mymethod()
log.InfoFormat("mymethod:今日の日付 Date:{0}", DateTime.Now)
End Sub
End Class
log4netでログを出力するには、
log.Debug("Program Started")
log.Warn("警告です")
log.InfoFormat("mymethod:今日の日付 Date:{0}", DateTime.Now)
という具合に、logオブジェクトのメソッド(Fatal、Error、Info、Debug、Warnなど)を呼び出します。このとき引数として指定できるのは、文字列もしくは例外オブジェクトです。log4netでは、ログのレベルを5段階に分けており(DEBUG < INFO < WARN < ERROR < FATAL)、それぞれに対応したログ出力のメソッドが用意されています。
後述しますが、どのレベルのログを出力するかを構成ファイルで指定することで、ログの出力内容をコントロールできます。つまり、デバッグ時はすべてのログを出力し、リリース後はログのレベルがERROR以上だけを出力する(log.Errorメソッドとlog.Fatalメソッドのみを有効にする)といったことが可能です。
■ビルド
ビルドの際に特別な作業はありません。参照設定に追加したlog4net.dllがビルド後にbin\Debug(リリース・ビルドではbin\Release)にコピーされていることが確認できれば問題ありません。log4net.dllがDebugフォルダにコピーされていない場合は、log4netの参照プロパティの「ローカルコピー」がTrueになっているかを確認してみてください。
また、「log4netのスキーマ情報が見つかりませんでした」というエラー・メッセージが表示される場合がありますが、この場合は、まずソース・ファイルにコンパイル・エラーがないかを確認してみてください。
■出力されたログを確認
以上の作業でlog4netによるログ出力を行うサンプル・プログラムが実行できるようになりました。実際に実行してみると、次のリスト4のような内容のログ・ファイル「C:\log-file.txt」が作成されます。
2007-12-12 14:05:46,933 [10] DEBUG Log4NetSampleVb.Module1 - Program Started
2007-12-12 14:05:47,012 [10] INFO Log4NetSampleVb.someclass - mymethod:今日の日付 Date:12/12/2007 14:05:47
2007-12-12 14:05:47,027 [10] FATAL Log4NetSampleVb.Module1 - Program が終了します
出力されたログには、ソース・コード上で引数として指定した文字列に加えて、日付やクラス名なども含まれているのが分かります。このログの書式については後述しますが、ユーザー名、ファイル名などをログに含めることも可能です。
Copyright© Digital Advantage Corp. All Rights Reserved.