けっこう前から気になっていたロギングライブラリ、JBoss Loggingを使ってみました。
JBoss ASやWildFlyなど、JBoss関連のプロダクトで使われているロギングライブラリです。
まあ、興味を持ったのはInfinispanでも使われているからですが。
JBoss Loggingって?
JBoss Logging自体は、Commmons LoggingやSLF4Jのような、ログの実装に対するインターフェースを提供するプロダクトです。
JBoss Logging
https://github.com/jboss-logging/jboss-logging
単体では、以下の優先順位でクラスパス上からログ実装を探していき、最初に見つかったものを採用します。
- JBoss Log Manager(https://github.com/jboss-logging/jboss-logmanager)
- Log4j 2 *JBoss Logging 3.2から
- Log4j
- SLF4J *Logbackが同時に使用されている場合
- java.util.logging
この探索をしているコードは、このあたりになります。
master branch
https://github.com/jboss-logging/jboss-logging/blob/master/src/main/java/org/jboss/logging/LoggerProviders.java#L38
JBoss Log Managerは、java.util.loggingを拡張した実装で、JBoss ASやWildFlyなどで使用されているようです。これを使用するには、クラスパスに存在する以外に、java.util.logging.LogManager#getLogManagerが、JBoss Log Managerのクラスとなっている必要があります(システムプロパティで、java.util.logging.managerでorg.jboss.logmanager.LogManagerを指定)。
が、設定をあんまり追いきれなかったので、今回はパス。
まあ、今回はJBoss Logging単体で使ってみましょう。
依存関係の定義
まずは、JBoss Loggingの依存関係を定義します。
<dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> <!-- <version>3.1.4.GA</version> --> <!-- 安定版 --> <version>3.2.0.Beta1</version> <!-- Log4j2を使いたい場合、こちら --> </dependency>
最新安定版は3.1.4.GAですが、Log4j 2を裏で使いたい場合は、3.2系になります。
サンプルコード
サンプルコードは、こんな感じで用意しました。
src/main/java/org/littlewings/jbosslogging/JBossLoggingExample.java
package org.littlewings.jbosslogging; import org.jboss.logging.Logger; public class JBossLoggingExample { public static void main(String... args) { Logger logger = Logger.getLogger(JBossLoggingExample.class); System.out.printf("Logger Class[%s]%n", logger.getClass()); System.out.println("========== Trace start =========="); logger.trace("こんにちは、世界 at Trace"); logger.trace("こんにちは、世界 at Trace", new Exception()); logger.tracev("こんにちは、{0} {1} at Trace", "世界", "!!"); logger.tracef("こんにちは、%s %s at Trace", "世界", "!!"); System.out.println("========== Trace end =========="); System.out.println("========== Debug start =========="); logger.debug("こんにちは、世界 at Debug"); logger.debug("こんにちは、世界 at Debug", new Exception()); logger.debugv("こんにちは、{0} {1} at Debug", "世界", "!!"); logger.debugf("こんにちは、%s %s at Debug", "世界", "!!"); System.out.println("========== Debug end =========="); System.out.println("========== Info start =========="); logger.info("こんにちは、世界 at Info"); logger.info("こんにちは、世界 at Info", new Exception()); logger.infov("こんにちは、{0} {1} at Info", "世界", "!!"); logger.infof("こんにちは、%s %s at Info", "世界", "!!"); System.out.println("========== Info end =========="); System.out.println("========== Warn start =========="); logger.warn("こんにちは、世界 at Warn"); logger.warn("こんにちは、世界 at Warn", new Exception()); logger.warnv("こんにちは、{0} {1} at Warn", "世界", "!!"); logger.warnf("こんにちは、%s %s at Warn", "世界", "!!"); System.out.println("========== Error end =========="); System.out.println("========== Error start =========="); logger.error("こんにちは、世界 at Error"); logger.error("こんにちは、世界 at Error", new Exception()); logger.errorv("こんにちは、{0} {1} at Error", "世界", "!!"); logger.errorf("こんにちは、%s %s at Error", "世界", "!!"); System.out.println("========== Error end =========="); System.out.println("========== Fatal start =========="); logger.fatal("こんにちは、世界 at Fatal"); logger.fatal("こんにちは、世界 at Fatal", new Exception()); logger.fatalv("こんにちは、{0} {1} at Fatal", "世界", "!!"); logger.fatalf("こんにちは、%s %s at Fatal", "世界", "!!"); System.out.println("========== Fatal end =========="); } }
では、簡単に説明を。
まずは、import文。単純に使うのなら、これだけでよさそうです。
immort org.jboss.logging.Logger;
Loggerの取得は、ClassクラスまたはLoggerの名前をStringで渡して行います。
Logger logger = Logger.getLogger(JBossLoggingExample.class);
今回は、Classクラスを使用しました。
使えるログレベルは、
- TRACE
- DEBUG
- INFO
- WARN
- ERROR
- FATAL
となります。Log4jと一緒ですねー。
あとは、ログレベルに合わせてメソッドを呼び出します。こんな感じで。
logger.info("こんにちは、世界 at Info"); logger.info("こんにちは、世界 at Info", new Exception()); logger.infov("こんにちは、{0} {1} at Info", "世界", "!!"); logger.infof("こんにちは、%s %s at Info", "世界", "!!");
infoのようなメソッドは、メッセージとしてObjectを取り、その他Throwableを渡せたりもできます。
infovのような「v」が付くメソッドは、java.text.MessageFormatで解析可能な書式文字列とパラメータを渡すことができます。例外も渡せます。
infovにような「f」が付くメソッドは、String#formatで解析可能な書式文字列を渡すことができます。
実は、「v」が付かない方もMessageFormatを使うことができるみたいですが、FQCNを渡さないものは非推奨になっているようなので、ここでは置いておきます。
java.util.loggingをログ実装として使用する
このまま依存関係を何も追加せず起動すると、java.util.loggingを使用してログ出力を行います。
とりあえず設定ファイルを用意して。
src/main/resources/javalogging.properties
handlers=java.util.logging.ConsoleHandler .level=FINEST java.util.logging.ConsoleHandler.level=FINEST java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.SimpleFormatter.format=[%1$tc] %4$s - %5$s %6$s %n
実行。
$ mvn compile && mvn exec:java -Dexec.mainClass=org.littlewings.jbosslogging.JBossLoggingExample -Djava.util.logging.config.file=src/main/resources/javalogging.properties
利用されるJBoss Loggingのクラスは、JDKLoggerが選択されます。
Logger Class[class org.jboss.logging.JDKLogger]
INFOレベルのものだけ抜き出すと、こんな感じで出力されます。
========== Info start ========== [日 6 08 02:06:47 JST 2014] INFO - こんにちは、世界 at Info [日 6 08 02:06:47 JST 2014] INFO - こんにちは、世界 at Info java.lang.Exception at org.littlewings.jbosslogging.JBossLoggingExample.main(JBossLoggingExample.java:34) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) at java.lang.Thread.run(Thread.java:745) [日 6 08 02:06:47 JST 2014] INFO - こんにちは、世界 !! at Info [日 6 08 02:06:47 JST 2014] INFO - こんにちは、世界 !! at Info ========== Info end ==========
Log4j 2をログ実装として使用する
続いて、Log4j 2。これを使うためには、JBoss Loggingは3.2系である必要があります。
依存関係に、以下を追加。
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.0-rc1</version> </dependency>
設定ファイル。
src/main/resources/log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyy/MM/dd HH:mm:ss.SSS} %-5level - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="trace"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
実行。
$ mvn compile && mvn exec:java -Dexec.mainClass=org.littlewings.jbosslogging.JBossLoggingExample
*今度は、設定ファイルの指定は不要なので
選択されたLogger。
Logger Class[class org.jboss.logging.Log4j2Logger]
出力例。
========== Info start ========== 2014/06/08 02:09:46.944 INFO - こんにちは、世界 at Info 2014/06/08 02:09:46.944 INFO - こんにちは、世界 at Info java.lang.Exception at org.littlewings.jbosslogging.JBossLoggingExample.main(JBossLoggingExample.java:34) [classes/:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_05] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_05] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_05] at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0_05] at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) [exec-maven-plugin-1.3.jar:?] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_05] 2014/06/08 02:09:46.948 INFO - こんにちは、世界 !! at Info 2014/06/08 02:09:46.948 INFO - こんにちは、世界 !! at Info ========== Info end ==========
スタックトレースに、どこからクラスがロードされているか、出力されるんですね…。
Log4jをログ実装として使用する
Log4jを使う場合。
先ほどのLog4j 2の依存関係定義を外して、Log4jを追加します。
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
設定。
src/main/resources/log4j.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" > <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <param name="target" value="System.out" /> <layout class="org.apache.log4j.PatternLayout"> <param name="conversionPattern" value="[%d{yyyy/MM/dd HH:mm:ss,SSS}] %-5p - %m%n" /> </layout> </appender> <root> <priority value="trace" /> <appender-ref ref="CONSOLE" /> </root> </log4j:configuration>
選択されたLogger。
Logger Class[class org.jboss.logging.Log4jLogger]
結果。
========== Info start ========== [2014/06/08 02:12:35,222] INFO - こんにちは、世界 at Info [2014/06/08 02:12:35,222] INFO - こんにちは、世界 at Info java.lang.Exception at org.littlewings.jbosslogging.JBossLoggingExample.main(JBossLoggingExample.java:34) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) at java.lang.Thread.run(Thread.java:745) [2014/06/08 02:12:35,223] INFO - こんにちは、世界 !! at Info [2014/06/08 02:12:35,223] INFO - こんにちは、世界 !! at Info ========== Info end ==========
SLF4J&Logbackをログ実装として使用する
最後は、SLF4JとLogbackです。これらは、JBoss Loggingで使う場合は、合わせて使用します。
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.2</version> </dependency>
設定。
src/main/resources/logback.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy/MM/dd HH:mm:ss.SSS} %-5level - %msg%n</pattern> </encoder> </appender> <root level="trace"> <appender-ref ref="STDOUT" /> </root> </configuration>
選択されたLogger。
Logger Class[class org.jboss.logging.Slf4jLocationAwareLogger]
結果。
========== Info start ========== 2014/06/08 02:15:27.523 INFO - こんにちは、世界 at Info 2014/06/08 02:15:27.525 INFO - こんにちは、世界 at Info java.lang.Exception: null at org.littlewings.jbosslogging.JBossLoggingExample.main(JBossLoggingExample.java:34) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_05] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_05] at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_05] at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) ~[na:na] at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_05] 2014/06/08 02:15:27.526 INFO - こんにちは、世界 !! at Info 2014/06/08 02:15:27.526 INFO - こんにちは、世界 !! at Info ========== Info end ==========
Logbackも、スタックトレースでどこからクラスがロードされたか出力されるんですね。
何気に、SLF4JとLogback、初めて使ってます…。
ところで、SLF4JにFATALがないため、JBoss LoggingでFATALを使用すると、裏のSLF4J&LogbackにはERRORとして出力されてしまいます。
========== Fatal start ========== 2014/06/08 02:15:27.541 ERROR - こんにちは、世界 at Fatal 2014/06/08 02:15:27.548 ERROR - こんにちは、世界 at Fatal java.lang.Exception: null at org.littlewings.jbosslogging.JBossLoggingExample.main(JBossLoggingExample.java:64) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_05] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_05] at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_05] at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) ~[na:na] at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_05] 2014/06/08 02:15:27.549 ERROR - こんにちは、世界 !! at Fatal 2014/06/08 02:15:27.549 ERROR - こんにちは、世界 !! at Fatal ========== Fatal end ==========
まあ、ないものはないですからね…。
ここまでで、JBoss Loggingの触り的な感じで。
JBoss Logging Toolsを使用する
話は変わって、今度はJBoss Logging Toolsを使用してみます。
JBoss Logging Annotation Processor
https://github.com/jboss-logging/jboss-logging-tools
JBoss Logging Toolsは、アノテーションを使用してタイプセーフなログ出力を行うことができるライブラリです。
参考になるものとしては、こちらだそうで。
https://github.com/jboss-developer/jboss-eap-quickstarts/tree/6.3.x/logging-tools
では、使ってみましょう。
Mavenの依存関係に、JBoss Logging Toolsを追加します。
<dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging-processor</artifactId> <version>1.2.0.Final</version> <scope>provided</scope> </dependency>
Scopeは、providedで大丈夫です。
そして、アノテーションを付与したインターフェースを作成します。
src/main/java/org/littlewings/jbosslogging/Log.java
package org.littlewings.jbosslogging; import org.jboss.logging.BasicLogger; import org.jboss.logging.Logger.Level; import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageLogger; @MessageLogger(projectCode = "") public interface Log { // extends BasicLogger { // BasicLoggerインターフェースを実装していれば、普通のLoggerとしても使えそう… @LogMessage(level = Level.INFO) // Default @Message(value = "こんにちは、世界") void helloWorldLog(); @LogMessage(level = Level.ERROR) @Message(value = "例外が発生しました") void exceptionLog(@Cause Exception e); @LogMessage(level = Level.WARN) @Message(value = "引数に誤りがあります。指定値=[%s]") void argsExceptionLog(String value, @Cause IllegalArgumentException e); @LogMessage(level = Level.INFO) @Message(value = "メッセージ=[%s], サイズ=[%d]") void argsLog1(String word, int size); @LogMessage(level = Level.INFO) @Message(value = "サイズ=[%2$d], メッセージ=[%1$s]") void argsLog2(String word, int size); @LogMessage(level = Level.INFO) @Message(value = "メッセージ=[{0}], サイズ=[{1}]、MessageFormat版", format = Message.Format.MESSAGE_FORMAT) void argsLog3(String word, int size); }
インターフェースには@MessageLoggerアノテーションを付与し、メソッドには@LogMessageおよび@Messageアノテーションを付与します。
@LogMessageアノテーションでは主にログレベルを、@Messageでは書式文字列とフォーマットを指定します。デフォルトでは、String#formatです。
ここで@Messageに指定した書式文字列内に、宣言したメソッドの引数を使用することができるため、タイプセーフにログ出力を行うことができます。その他、国際化などあるようですが、今回はパス…。
例外を受け取る場合は、@Causeアノテーションを付与します。
@LogMessage(level = Level.ERROR) @Message(value = "例外が発生しました") void exceptionLog(@Cause Exception e); @LogMessage(level = Level.WARN) @Message(value = "引数に誤りがあります。指定値=[%s]") void argsExceptionLog(String value, @Cause IllegalArgumentException e);
用意するインターフェースは、特に何か別のインターフェースを実装する必要はないみたいですが、org.jboss.logging.BasicLoggerインターフェースを実装しておくと、通常のLoggerとしても使えそうな感じです。
利用側は、こんな感じになります。
System.out.println("========== JBoss Logging Processor start =========="); Log log = Logger.getMessageLogger(Log.class, JBossLoggingExample.class.getName()); log.helloWorldLog(); log.exceptionLog(new Exception("エラー")); log.argsExceptionLog("bad value", new IllegalArgumentException("エラー")); log.argsLog1("JBoss Logging", 10); log.argsLog2("JBoss Logging", 10); log.argsLog3("JBoss Logging", 10); System.out.println("========== JBoss Logging Processor end ==========");
先ほどとは違い、Logger#getMessageLoggerでLoggerを取得します。コンパイル時にJBoss Logging Toolsがクラスを生成するため、メソッドの実装をしていませんが、このまま呼び出すことができます。
実行結果。
*ログ実装は、java.util.loggingです
========== JBoss Logging Processor start ========== [日 6 08 02:34:20 JST 2014] INFO - こんにちは、世界 [日 6 08 02:34:20 JST 2014] ERROR - 例外が発生しました java.lang.Exception: エラー at org.littlewings.jbosslogging.JBossLoggingExample.main(JBossLoggingExample.java:75) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) at java.lang.Thread.run(Thread.java:745) [日 6 08 02:34:20 JST 2014] WARN - 引数に誤りがあります。指定値=[bad value] java.lang.IllegalArgumentException: エラー at org.littlewings.jbosslogging.JBossLoggingExample.main(JBossLoggingExample.java:76) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) at java.lang.Thread.run(Thread.java:745) [日 6 08 02:34:20 JST 2014] INFO - メッセージ=[JBoss Logging], サイズ=[10] [日 6 08 02:34:20 JST 2014] INFO - サイズ=[10], メッセージ=[JBoss Logging] [日 6 08 02:34:20 JST 2014] INFO - メッセージ=[JBoss Logging], サイズ=[10]、MessageFormat版 ========== JBoss Logging Processor end ==========
ちゃんと出力されていますね。
また、@MessageLoggerのprojectCodeに接頭辞を
@MessageLogger(projectCode = "JBL")
@Messageのidに数字を指定するとログ出力のメッセージにID付与を行うことができます。
@LogMessage(level = Level.INFO) // Default @Message(value = "こんにちは、世界", id = 1) void helloWorldLog();
こんな感じに定義して
@MessageLogger(projectCode = "JBL") public interface Log { // extends BasicLogger { // BasicLoggerインターフェースを実装していれば、普通のLoggerとしても使えそう… @LogMessage(level = Level.INFO) // Default @Message(value = "こんにちは、世界", id = 1) void helloWorldLog(); @LogMessage(level = Level.ERROR) @Message(value = "例外が発生しました", id = 2) void exceptionLog(@Cause Exception e); @LogMessage(level = Level.WARN) @Message(value = "引数に誤りがあります。指定値=[%s]", id = 3) void argsExceptionLog(String value, @Cause IllegalArgumentException e); @LogMessage(level = Level.INFO) @Message(value = "メッセージ=[%s], サイズ=[%d]", id = 4) void argsLog1(String word, int size); @LogMessage(level = Level.INFO) @Message(value = "サイズ=[%2$d], メッセージ=[%1$s]", id = 5) void argsLog2(String word, int size); @LogMessage(level = Level.INFO) @Message(value = "メッセージ=[{0}], サイズ=[{1}]、MessageFormat版", format = Message.Format.MESSAGE_FORMAT, id = 6) void argsLog3(String word, int size); }
実行。
========== JBoss Logging Processor start ========== [日 6 08 02:35:27 JST 2014] INFO - JBL000001: こんにちは、世界 [日 6 08 02:35:27 JST 2014] ERROR - JBL000002: 例外が発生しました java.lang.Exception: エラー at org.littlewings.jbosslogging.JBossLoggingExample.main(JBossLoggingExample.java:75) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) at java.lang.Thread.run(Thread.java:745) [日 6 08 02:35:27 JST 2014] WARN - JBL000003: 引数に誤りがあります。指定値=[bad value] java.lang.IllegalArgumentException: エラー at org.littlewings.jbosslogging.JBossLoggingExample.main(JBossLoggingExample.java:76) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) at java.lang.Thread.run(Thread.java:745) [日 6 08 02:35:27 JST 2014] INFO - JBL000004: メッセージ=[JBoss Logging], サイズ=[10] [日 6 08 02:35:27 JST 2014] INFO - JBL000005: サイズ=[10], メッセージ=[JBoss Logging] [日 6 08 02:35:27 JST 2014] INFO - JBL000006: メッセージ=[JBoss Logging], サイズ=[10]、MessageFormat版 ========== JBoss Logging Processor end ==========
こんな感じで、IDが追加されましたね。
[日 6 08 02:35:27 JST 2014] INFO - JBL000001: こんにちは、世界
ロギングライブラリ、なにがいいんでしょうと思うのですが、JBoss Loggingもいいなぁと思う次第です。