ログ出力 "したい" 時と "したくない" 時を実装
log4jでログ出力してて、例えばコンソールアプリケーションを作ってる時に、
あるアプリではコンソール+ログファイル両方出力したいけど、
もう一方のアプリではコンソールには出さなくて、ログファイルにだけ出したい、ってときがある。
そしてその2つのアプリは同じロジックを呼ぶ、つまり呼ばれるロジックはログを出力する時としない時がある。
うーん、log4jの標準機能ではクラス単位での切替くらいしかできないよなー、ってことで、こんな感じにしたらできたのでご紹介。
# もっとCoolにできるなら教えてください。
MyLoggerクラスを作って、
public class MyLogger { private Logger logger = null; private static final String NoConsole = "NoConsole"; private MyLogger(Class<?> clazz){ logger = Logger.getLogger(clazz.getName()); } private MyLogger(String prefix, Class<?> clazz){ logger = Logger.getLogger(prefix+"."+clazz.getName()); } public static MyLogger getInstans(Class<?> clazz){ return new MyLogger(clazz); } public static MyLogger getInstansNoConsole(Class<?> clazz){ return new MyLogger(NoConsole, clazz); } public void info(String msg){ logger.info(msg); } ~~~ }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="stdout" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %5p %c - %m%n" /> </layout> </appender> <appender name="file" class="org.apache.log4j.FileAppender"> <param name="File" value="target/App.log" /> <param name="Append" value="true"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %5p %c - %m%n" /> </layout> </appender> <category name="log4j_mute"> <priority value="info"/> <appender-ref ref="stdout"/> <appender-ref ref="file"/> </category> <category name="NoConsole"> <priority value="info"/> <appender-ref ref="file"/> </category> </log4j:configuration>
こんなロジッククラスを作る。
LogicA
public class LogicA { private static MyLogger logger = MyLogger.getInstans(LogicA.class); public static void process(){ logger.info("処理A!!"); } }
LogicB
public class LogicB { private static MyLogger logger = MyLogger.getInstans(LogicB.class); public static void process(){ logger.info("処理B!!"); } public static void mute(){ logger = MyLogger.getInstansNoConsole(LogicB.class); } }
そしてロジックを利用するアプリケーションでこんな風にする。
public class App{ public static void main( String[] args ) { LogicA.process(); LogicB.process(); LogicB.mute(); LogicB.process(); } }
処理結果:コンソール
$ java -cp "src/main/resources;target/log4j_mute-1.0-SNAPSHOT-jar-with-dependencies.jar" log4j_mute.App
2012-12-18 14:39:29,461 INFO log4j_mute.LogicA - 処理A!!
2012-12-18 14:39:29,462 INFO log4j_mute.LogicB - 処理B!!
処理結果:ログファイル
$ cat target/App.log
2012-12-18 14:39:29,461 INFO log4j_mute.LogicA - 処理A!!
2012-12-18 14:39:29,462 INFO log4j_mute.LogicB - 処理B!!
2012-12-18 14:39:29,463 INFO NoConsole.log4j_mute.LogicB - 処理B!!
カテゴリを使ってログ出力方法を変えてるわけです。