Log4Jソースコードリーディング
                ライティング
                 2012.10.06 (sat) at PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    Log4Jライティング

    今日やりたいこと

                        ログレベルでフィルタリングしたい




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    Log4Jライティング


                                             まずは 前回のおさらい




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    Log4J 2




                                             http://logging.apache.org/log4j/2.x/manual/architecture.html


              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    ログ出力までの流れ

                            package com.plugram.log4j.foo;

                            import org.apache.logging.log4j.LogManager;
                            import org.apache.logging.log4j.Logger;

                            import com.plugram.log4j.bar.MyNewApp;

                            public class Main {

                            	      static Logger logger = LogManager.getLogger(Main.class.getName());

                            	      public static void main(String[] args) {
                            	      	    new Main().run();
                            	      }

                            	      public void run() {
                            	      	    logger.trace("Entering application.");
                            	      	    MyNewApp bar = new MyNewApp();
                            	      	    if (bar.doIt()) {
                            	      	    	    logger.error("Just do it.");
                            	      	    }
                            	      	    logger.trace("Exiting application.");
                            	      }

                            }




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    ログ出力までの流れ

                            package com.plugram.log4j.foo;

                            import org.apache.logging.log4j.LogManager;
                            import org.apache.logging.log4j.Logger;

                            import com.plugram.log4j.bar.MyNewApp;

                            public class Main {

                            	      static Logger logger = LogManager.getLogger(Main.class.getName());

                       	  public static void main(String[]          args) {
                   LogManager new Main().run();
                       	  	
                           	    }
                         public static Logger getLogger(String name) {
                             return factory.getContext(LogManager.class.getName(), null, false).getLogger(name);
                           	    public void run() {
                         }
                           	    	    logger.trace("Entering application.");
                           	    	    MyNewApp bar = new MyNewApp();
                           	    	    if (bar.doIt()) {
                                org.apache.logging.log4j.core.LoggerContext
                           	    	    	    logger.error("Just do it.");
                           	    	    }
                           	    	    logger.trace("Exiting application.");        org.apache.logging.log4j.core.Logger
                           	    }

                            }




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    ログ出力までの流れ

                            package com.plugram.log4j.foo;

                            import org.apache.logging.log4j.LogManager;
                            import org.apache.logging.log4j.Logger;

                            import com.plugram.log4j.bar.MyNewApp;

                            public class Main {

                            	      static Logger logger = LogManager.getLogger(Main.class.getName());

                            	      public static void main(String[] args) {
                            	      	    new Main().run();
                            	      }

                            	      public void run() {
                            	      	    logger.trace("Entering application.");
                            	      	    MyNewApp bar = new MyNewApp();
                            	      	    if (bar.doIt()) {
                            	      	    	    logger.error("Just do it.");
                            	      	    }
                            	      	    logger.trace("Exiting application.");
                            	      }

                            }




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    ログ出力までの流れ

                            package com.plugram.log4j.foo;

                            import org.apache.logging.log4j.LogManager;
                            import org.apache.logging.log4j.Logger;

                            import com.plugram.log4j.bar.MyNewApp;

                            public class Main {

                            	      static Logger logger = LogManager.getLogger(Main.class.getName());

                            	      public static void main(String[] args) {
                            	      	    new Main().run();
                            	      }

                         	    public void run() {
                         	    	    logger.trace("Entering application.");
                         	    	    MyNewApp bar = new MyNewApp();
                       AbstractLogger
                         	    	    if (bar.doIt()) {
                         	    	    	    logger.error("Just do it.");
                          public void trace(String message) {
                         	    	    }
                              if (isEnabled(Level.TRACE, null, message)) {
                         	    	    logger.trace("Exiting application.");
                                  log(null, FQCN, Level.TRACE, new SimpleMessage(message), null);
                         	    }
                              }
                          }
                         }




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    ログ出力までの流れ


                          AbstractLogger
                                public void trace(String message) {
                                    if (isEnabled(Level.TRACE, null, message)) {
                                        log(null, FQCN, Level.TRACE, new SimpleMessage(message), null);
                                    }
                                }




                  core.Logger

                       @Override
                       public void log(Marker marker, String fqcn, Level level, Message data, Throwable t) {
                           if (data == null) {
                               data = new SimpleMessage("");
                           }
                           config.config.getConfigurationMonitor().checkConfiguration();
                           config.loggerConfig.log(name, marker, fqcn, level, data, t);
                       }



                         org.apache.logging.log4j.core.Logger$PrivateConfig



              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    ログ出力までの流れ

                   core.Logger

                        @Override
                        public void log(Marker marker, String fqcn, Level level, Message data, Throwable t) {
                            if (data == null) {
                                data = new SimpleMessage("");
                            }
                            config.config.getConfigurationMonitor().checkConfiguration();
                            config.loggerConfig.log(name, marker, fqcn, level, data, t);
                        }




                core.LoggerConfig

                    public void log(String loggerName, Marker marker, String fqcn, Level level,
                            Message data, Throwable t) {
                        LogEvent event = logEventFactory.createEvent(loggerName, marker, fqcn, level, data, t);
                        log(event);
                    }




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    ログ出力までの流れ

                                             core.LoggerConfig

                                                 public void log(LogEvent event) {

                                                     counter.incrementAndGet();
                                                     try {
                                                         if (isFiltered(event)) {
                                                             return;
                                                         }

                                                         callAppenders(event);

                                                         if (additive && parent != null) {
                                                             parent.log(event);
                                                         }
                                                     } finally {
                                                         if (counter.decrementAndGet() == 0) {
                                                             synchronized (this) {
                                                                 if (shutdown) {
                                                                     notifyAll();
                                                                 }
                                                             }

                                                         }
                                                     }
                                                 }




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    主な登場人物
                                                  LogManager
                                                       Logger
                                                   LogContext
                                                 Configuration

                       とゆかいな仲間たち(関連クラス)
                                               AbstractLogger は Logger の親クラス
                                             LoggerConfig は Logger の処理を委譲してる

              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    LoggerContext
      ・起動ポイント
      ・設定とかロガーとか持ってる


                   private volatile Configuration config = new DefaultConfiguration();


                   private final ConcurrentMap<String, Logger> loggers =
                       new ConcurrentHashMap<String, Logger>();




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    LogManager

     ・こいつが持ってるFactory経由でLoggerを呼び出す


         private static final String LOGGER_CONTEXT_FACTORY = "LoggerContextFactory";



                      クラス名から設定できるようにしておけばデフォルトのFactoryクラスも変えられる




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    Configuration
      ・Logger(LoggerConfig)、Appenderを持ってる
      ・あとはプラグインとかリスナーとか

              Configurationクラスはインターフェースなので
              BaseConfigurationクラスを参考に・・・
              →自分でConfiguration作るときはこれを拡張すればよい




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    Logger
      ・このクラス経由でログ出力を行う
       実際の処理はLoggerConfigに委譲




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    今日やりたいこと


                       ログレベルでフィルタリングしたい




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    ログレベルでフィルタリング
         org.apache.logging.log4j.core.config.AppenderControl

               /**
                * Call the appender.
                * @param event The event to process.
                */
               public void callAppender(LogEvent event) {
                   ・・・
                     if (level != null) {
                         if (intLevel < event.getLevel().intLevel()) {
                             return;
                         }
                     }
                     ・・・
                     try {
                         ・・・


                            try {
                                appender.append(event);
                            } catch (RuntimeException ex) {
                              ・・・
                            }
                     }
               }


              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    ログレベルでフィルタリング

     org.apache.logging.log4j.core.config.LoggerConfig

         /**
           * Add an Appender to the LoggerConfig.
           * @param appender The Appender to add.
           * @param level The Level to use.
           * @param filter A Filter for the Appender reference.
           */
         public void addAppender(Appender appender, Level level, Filter filter) {
                appenders.put(appender.getName(),
                  new AppenderControl(appender, level, filter));
         }




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    書くときの注意
     ・どういった意図を持ってクラス設計を行っているか
      →各クラスの責務はなにか
      →パッケージ分けのルール
      →どこからPlugin化しているか

     ・JDK5で入ったjava.util.concurrentを使っているところ
      →なぜそのクラスを使っているか
      → synchronizedやvolatileとはどう違う?
              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    書くときの注意
     ・テストも書こう
      →TDD(テスト駆動開発)で書いてみよう
      →Mockライブラリ使おう
      →Eclipse使ってるならQuick JUnit Plugin

     ・必要なライブラリはMaven(Gradle)で管理してね
      → 使い方は説明します

      → Jenkins使ってたら連携してもいいよ
              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




    書くときの注意

     ・書いたコードはGitHubにアップすること
      →Gitは常識レベルとして知っておくと便利
      →他の人のコードでバグなどがあったらissue登録
      →いきなりプルリクエストしてもおk




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日
社内勉強会 Log4J




                                     ありがとうございました




              COPYRIGHT 2012 PLUGRAM, Inc.




12年10月7日日曜日

Log4j 2 writing

  • 1.
    Log4Jソースコードリーディング ライティング 2012.10.06 (sat) at PLUGRAM, Inc. 12年10月7日日曜日
  • 2.
    社内勉強会 Log4J Log4Jライティング 今日やりたいこと ログレベルでフィルタリングしたい COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 3.
    社内勉強会 Log4J Log4Jライティング まずは 前回のおさらい COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 4.
    社内勉強会 Log4J Log4J 2 http://logging.apache.org/log4j/2.x/manual/architecture.html COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 5.
    社内勉強会 Log4J ログ出力までの流れ package com.plugram.log4j.foo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.plugram.log4j.bar.MyNewApp; public class Main { static Logger logger = LogManager.getLogger(Main.class.getName()); public static void main(String[] args) { new Main().run(); } public void run() { logger.trace("Entering application."); MyNewApp bar = new MyNewApp(); if (bar.doIt()) { logger.error("Just do it."); } logger.trace("Exiting application."); } } COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 6.
    社内勉強会 Log4J ログ出力までの流れ package com.plugram.log4j.foo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.plugram.log4j.bar.MyNewApp; public class Main { static Logger logger = LogManager.getLogger(Main.class.getName()); public static void main(String[] args) { LogManager new Main().run(); } public static Logger getLogger(String name) { return factory.getContext(LogManager.class.getName(), null, false).getLogger(name); public void run() { } logger.trace("Entering application."); MyNewApp bar = new MyNewApp(); if (bar.doIt()) { org.apache.logging.log4j.core.LoggerContext logger.error("Just do it."); } logger.trace("Exiting application."); org.apache.logging.log4j.core.Logger } } COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 7.
    社内勉強会 Log4J ログ出力までの流れ package com.plugram.log4j.foo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.plugram.log4j.bar.MyNewApp; public class Main { static Logger logger = LogManager.getLogger(Main.class.getName()); public static void main(String[] args) { new Main().run(); } public void run() { logger.trace("Entering application."); MyNewApp bar = new MyNewApp(); if (bar.doIt()) { logger.error("Just do it."); } logger.trace("Exiting application."); } } COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 8.
    社内勉強会 Log4J ログ出力までの流れ package com.plugram.log4j.foo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.plugram.log4j.bar.MyNewApp; public class Main { static Logger logger = LogManager.getLogger(Main.class.getName()); public static void main(String[] args) { new Main().run(); } public void run() { logger.trace("Entering application."); MyNewApp bar = new MyNewApp(); AbstractLogger if (bar.doIt()) { logger.error("Just do it."); public void trace(String message) { } if (isEnabled(Level.TRACE, null, message)) { logger.trace("Exiting application."); log(null, FQCN, Level.TRACE, new SimpleMessage(message), null); } } } } COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 9.
    社内勉強会 Log4J ログ出力までの流れ AbstractLogger public void trace(String message) { if (isEnabled(Level.TRACE, null, message)) { log(null, FQCN, Level.TRACE, new SimpleMessage(message), null); } } core.Logger @Override public void log(Marker marker, String fqcn, Level level, Message data, Throwable t) { if (data == null) { data = new SimpleMessage(""); } config.config.getConfigurationMonitor().checkConfiguration(); config.loggerConfig.log(name, marker, fqcn, level, data, t); } org.apache.logging.log4j.core.Logger$PrivateConfig COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 10.
    社内勉強会 Log4J ログ出力までの流れ core.Logger @Override public void log(Marker marker, String fqcn, Level level, Message data, Throwable t) { if (data == null) { data = new SimpleMessage(""); } config.config.getConfigurationMonitor().checkConfiguration(); config.loggerConfig.log(name, marker, fqcn, level, data, t); } core.LoggerConfig public void log(String loggerName, Marker marker, String fqcn, Level level, Message data, Throwable t) { LogEvent event = logEventFactory.createEvent(loggerName, marker, fqcn, level, data, t); log(event); } COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 11.
    社内勉強会 Log4J ログ出力までの流れ core.LoggerConfig public void log(LogEvent event) { counter.incrementAndGet(); try { if (isFiltered(event)) { return; } callAppenders(event); if (additive && parent != null) { parent.log(event); } } finally { if (counter.decrementAndGet() == 0) { synchronized (this) { if (shutdown) { notifyAll(); } } } } } COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 12.
    社内勉強会 Log4J 主な登場人物 LogManager Logger LogContext Configuration とゆかいな仲間たち(関連クラス) AbstractLogger は Logger の親クラス LoggerConfig は Logger の処理を委譲してる COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 13.
    社内勉強会 Log4J LoggerContext ・起動ポイント ・設定とかロガーとか持ってる private volatile Configuration config = new DefaultConfiguration(); private final ConcurrentMap<String, Logger> loggers = new ConcurrentHashMap<String, Logger>(); COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 14.
    社内勉強会 Log4J LogManager ・こいつが持ってるFactory経由でLoggerを呼び出す private static final String LOGGER_CONTEXT_FACTORY = "LoggerContextFactory"; クラス名から設定できるようにしておけばデフォルトのFactoryクラスも変えられる COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 15.
    社内勉強会 Log4J Configuration ・Logger(LoggerConfig)、Appenderを持ってる ・あとはプラグインとかリスナーとか Configurationクラスはインターフェースなので BaseConfigurationクラスを参考に・・・ →自分でConfiguration作るときはこれを拡張すればよい COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 16.
    社内勉強会 Log4J Logger ・このクラス経由でログ出力を行う  実際の処理はLoggerConfigに委譲 COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 17.
    社内勉強会 Log4J 今日やりたいこと ログレベルでフィルタリングしたい COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 18.
    社内勉強会 Log4J ログレベルでフィルタリング org.apache.logging.log4j.core.config.AppenderControl /** * Call the appender. * @param event The event to process. */ public void callAppender(LogEvent event) { ・・・ if (level != null) { if (intLevel < event.getLevel().intLevel()) { return; } } ・・・ try { ・・・ try { appender.append(event); } catch (RuntimeException ex) { ・・・ } } } COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 19.
    社内勉強会 Log4J ログレベルでフィルタリング org.apache.logging.log4j.core.config.LoggerConfig /** * Add an Appender to the LoggerConfig. * @param appender The Appender to add. * @param level The Level to use. * @param filter A Filter for the Appender reference. */ public void addAppender(Appender appender, Level level, Filter filter) { appenders.put(appender.getName(), new AppenderControl(appender, level, filter)); } COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 20.
    社内勉強会 Log4J 書くときの注意 ・どういった意図を持ってクラス設計を行っているか  →各クラスの責務はなにか  →パッケージ分けのルール  →どこからPlugin化しているか ・JDK5で入ったjava.util.concurrentを使っているところ  →なぜそのクラスを使っているか  → synchronizedやvolatileとはどう違う? COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 21.
    社内勉強会 Log4J 書くときの注意 ・テストも書こう  →TDD(テスト駆動開発)で書いてみよう  →Mockライブラリ使おう  →Eclipse使ってるならQuick JUnit Plugin ・必要なライブラリはMaven(Gradle)で管理してね  → 使い方は説明します  → Jenkins使ってたら連携してもいいよ COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 22.
    社内勉強会 Log4J 書くときの注意 ・書いたコードはGitHubにアップすること  →Gitは常識レベルとして知っておくと便利  →他の人のコードでバグなどがあったらissue登録  →いきなりプルリクエストしてもおk COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日
  • 23.
    社内勉強会 Log4J ありがとうございました COPYRIGHT 2012 PLUGRAM, Inc. 12年10月7日日曜日