log4jの入手先は次です。バージョン1.2系列の入手
上記ページから、Downloadのリンクを辿り、入手します。
ログ機能は、アプリケーションの性能を低下させたり、ログ出力が膨大になって見えなくなってしまうことがあります。そこで、log4jは、性能を高め、柔軟性を持つように設計されました。また、理解しやすく使いやすいAPIを設けました。
もともとはIBMのAlphaworksから公開されていたが、開発者のGulcu氏がIBM(チューリッヒ研究所)を離れた後は、オープンソースとなっており、現在Apacheの下でメンテナンスされています。
log4jがIBMから離れたあと、IBMのAlphaworksでは、log4jとは別にThe Logging Toolkit for Java (JLog)というアプリケーション・アプレットのログ用ツールを開発しています。このアーキテクチャはloggers, handlers, filters, and formattersという概念から構成されます。Java2 SE 1.4で搭載するためのロギングAPIの仕様検討がJSR 47で進められましたが、その時点で普及していたlog4jの成果が取り込まれることはなく、独自に仕様化されました。このJSR 47の仕様は、IBMのThe Logging Toolkit for Javaをベースにしているように見えます。
log4jの開発者Gulcu氏は、log4jの開発からフェードアウトし、現在は別なロギングライブラリlogbackの開発に携わっています。
2010年現在、選択肢に上がるよく知られているロギング・ライブラリは次の3つに大別されます。
機能的には大同小異で、使い方も似ていることから、アプリケーションで必要とするログ機能を備えているか、Java標準のRuntime以外に追加のライブラリを一緒に配布できるか、といった観点で好ましいものをその都度選択すればよいと思います。
なお、ロギングAPIにはJava2 SE 5.0(Tiger)で追加された可変長引数の対応等が望まれるのですが、上記にはいずれも互換性から採用の見込みは少ないようです。
簡単なAPIで実現され、実行時にログレベルを選択可能。ログ出力先はコンソール、ファイル、GUI、リモートマシンのソケット、NTイベントログ、リモートのUNIX Syslogデーモンなどが提供されています。ログの設定は、APIからも外部の設定ファイルからも可能で、特にログ出力内容の記述を外部の設定ファイルで柔軟にできる点は秀逸です。
ダウンロードしたアーカイブを展開し、中に含まれるjarファイル(log4j-バージョン.jar)を、クラスパスに含めます。
外部の設定ファイルを使わず、BasicConfiguratorクラスを使ったデフォルトのログ出力設定であるコンソール(標準出力)で初期化して使用する例を示します。初期化は、アプリケーションのどこか一箇所(たとえばmainメソッド)で初期化します。
import org.apache.log4j.BasicConfigurator; public class Main { public static void main(String[] args) { BasicConfigurator.configure(); // log4jの初期化 MyApp app = new MyApp(123); app.doSomeThing(); app.end(); } }
ログの出力は以下のようにLoggerクラスを使ってレベルに応じたログ出力メソッドを呼び出します。
import org.apache.log4j.Logger; public class MyApp { private static Logger logger; // Loggerインスタンスはクラス変数で保持 public MyApp(int value) { logger = Logger.getLogger(MyApp.class); logger.debug("MyApp created with value:" + value); } void doSomeThing() { logger.info("do something"); } void end() { logger.error("end"); } }
この実行結果は、次のようになります。
0 [main] DEBUG MyApp - MyApp created with value:123 0 [main] INFO MyApp - do something 16 [main] ERROR MyApp - end
ログのレベルと対応するLoggerには次の種類があります。
ログのレベル | 代表的な用途 |
---|---|
TRACE | ループ内でのログ、メソッドのイン・アウト、通過点の記録など |
DEBUG | バグ原因の切り分けに必要な情報の出力など |
INFO | 正常系の処理の開始・完了など |
WARN | 運用に支障のないエラーの記録など |
ERROR | 運用上対処の必要なエラーの通知など |
FATAL | 運用が継続できない致命的なエラーの通知など |
各ログのレベルに対応するログメソッドがLoggerクラスに用意されています。
引数を見ると、出力するメッセージはObject型なら何でもよく、引数に指定したオブジェクトのtoString()メソッドが返す文字列がログに出力されます。また、エラー時のログでは例外オブジェクトをログ出力できるよう引数にThrowableが指定できるオーバーロード版メソッドも用意されています。
初期化方法は、先に紹介したBasicConfiguratorを含め、大きくは3つ存在します。
No | 方法 | 内容 |
---|---|---|
1 | BasicConfigurator | 出力先(Appender)を1つ使用する。デフォルト出力先はコンソール |
2 | PropertyConfigurator | Javaプロパティ形式のテキストファイルに記述した内容で初期化する。 |
3 | DOMConfigurator | XML形式のテキストファイルに記述した内容で初期化する。 |
また、これ以外にJavadocを見ると、ReloadingPropertyConfiguratorやDefaultLF5Configuratorなるものがあります。
Javaプロパティ形式のテキストファイルに設定を記述し、それを実行時に読み込みログの設定を行います。
import org.apache.log4j.PropertyConfigurator; public class Main { public static void main(String[] args) { String filePath = args[0]; PropertyConfigurator.configure(filePath); // ... } // ... }
log4j.rootLogger = INFO, stdout, file log4j.appender.stdout = org.apache.log4j.ConsoleHandler log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %C %M%n %p %m%n log4j.appender.file = org.apache.log4j.FileAppender log4j.appender.file.File = C:\\temp\\myapp.log log4j.appender.file.encoding = UTF-8 log4j.appender.file.layout = org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d %C %M%n %p %m%n
rootLoggerでは、ログ階層の最上位での優先度、アペンダーの指定をします。ここでは、優先度はINFO以上、"stdout"および"file"という名の2つのアペンダーを設定しています。アペンダーは続いて定義しています。
stdoutアペンダーは、ConsoleHandlerで、ログ出力文のフォーマットにはPatternLayoutを使用し、そのレイアウトは、%d %C %M%n %p %m%nを指定しています。
fileアペンダーは、FileHandlerで、ログ出力先ファイル名にC:\temp\myapp.logを指定し、エンコーディングにUTF-8を指定しています。レイアウトについてはstdoutと同様です。
アペンダーには、ほかにも一定サイズ毎にログローテーションするRollingFileAppender、日々でログローテーションするDailyRollingFileAppender、OSのログに出力するNTEventLogAppender、SyslogAppender、メールに出すSMTPAppender、ネットワークに出すSocketAppender、SocketHubAppender、TelnetAppender、その他があります。
Java標準ログは、プログラムの実行中にJMX経由でログレベルを変更することができます。(JDK付属のJConsoleツールを使うと簡単に確認できます)
log4jにも、これに類することができるHierarchyDynamicMBeanが用意されています。使用するには、ログ初期化時に、MBeanServerに登録します。
import java.lang.management.ManagementFactory; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.OperationsException; import org.apache.log4j.PropertyConfigurator; import org.apache.log4j.jmx.HierarchyDynamicMBean; public class Main { public static void main(String[] args) throws OperationsException, MBeanRegistrationException { PropertyConfigurator.configure(args[0]); HierarchyDynamicMBean dynamicMBean = new HierarchyDynamicMBean(); MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectName dynamicMBeanName = new ObjectName("log4j:type=HierarchyDynamicMBean"); server.registerMBean(dynamicMBean, dynamicMBeanName); // ... } // ... }