JAvaログ編(2)-JUL(java.util.logging)

10219 ワード

ゆっくりして比較的に速くて、謙虚に技術を学びます
前言:前文java日志篇(1)-日志概説で述べた日志発展史に沿って文章を書いていないのは、JULがjdkが持参した日志実現であり、その他の日誌実現原理は大きく異なり、理解も比較的簡単であるため、興味があれば先に前の文章を見てみることができる
目次
 
JULって何?
JUL基本使用
JUL使用分析
一、ロガー
二、Handler
三、Formatter
まとめ
コメント
JULって何?
JULはjdkが持参した1つのログ実装で、使用は簡単で、制御は柔軟で、もし小型システムあるいはテストプログラムならば、明らかにJULはlog 4 jなどより良い選択です
JUL基本使用
Java.util.logging.Loggerの静的メソッドgetLogger(loggerName)を使用してログログを取得または作成
import java.io.IOException;
import java.util.logging.*;

public class JULTest {
    
     public static Logger log = Logger.getLogger("TestLog");  //      

    public static void main(String[] args) throws IOException {
        log.info("info");    //    
        log.warning("warning"); //    
        log.log(Level.SEVERE,"server"); //    
        log.fine("fine");
    }
}

ログを使用すると、log.info(「****」)などのデフォルトのレベル実装方法や、log.log(レベル、出力情報)などの特定のレベルを使用して出力できます.
上記のコード出力ログの結果は次のとおりです.
   14, 2019 9:20:32    JULTest main
  : info
   14, 2019 9:20:32    JULTest main
  : warning
   14, 2019 9:20:32    JULTest main
  : server

JUL使用分析
一、ロガー
なぜlog.fine(「fine」);出力はありませんか?
まず最初の質問を見て、JULのログの等級区分を理解する必要があります.
JULログの等級区分(優先順位の減少)と内蔵代表の整数は以下の通りである.
  • OFF(Integer.MAX_VALUE)
  • SEVERE(1000)
  • WARNING(900)
  • INFO(800)
  • CONFIG(700)
  • FINE(500)
  • FINER(400)
  • FINEST(300)
  • ALL(Integer.MIN_VALUE)

  •  ログの出力をより柔軟に制御するために、julは上記の9つのレベルをログレベル区分として使用します.通常のログレベルは主にserver、warning、infoです.Loggerに現在の指定レベルとより高いレベルのログが含まれている場合、loggerのデフォルトレベルはINFOであり、INFOより低いログは表示されません.上記の出力結果から、info以上のレベルのログを出力するだけで、infoレベル以下のログ内容を自動的に無視するのは、なぜこのような実現があるのだろうか.ここでは、jdkインストールディレクトリのlibパッケージの下にあるJULのデフォルトプロファイルloging.propertiesについて説明します.
    handlers= java.util.logging.ConsoleHandler
    
    .level= INFO
    
    java.util.logging.FileHandler.pattern = %h/java%u.log
    java.util.logging.FileHandler.limit = 50000
    java.util.logging.FileHandler.count = 1
    java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
    
    java.util.logging.ConsoleHandler.level = INFO
    java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
    
    com.xyz.foo.level = SEVERE

    logger.log(Level.FINE,"file");呼び出し方法は次のとおりです. 
    public void log(Levellevel, String msg) {
              if (level.intValue() < levelValue ||levelValue == offValue) {
                  return;
              }
              LogRecord lr = new LogRecord(level, msg);
              doLog(lr);
    }

    ここで、.levelプロパティはloggerのデフォルトのログ・レベルをinfoと指定し、loggerクラスはデフォルトのログ・レベルを先に読み込み、選択したログ・レベルの整数値がデフォルト値を下回るとログ出力は行われません.
    したがって、loggerの出力レベルを変更するには、対応する構成項目のレベルレベルレベルを変更したり、コードでloggerのレベルを動的に設定したりすることができます.
    結果はすべてのログ情報として出力されます.
    import java.io.IOException;
    import java.util.logging.*;
    
    public class JULTest {
        
         public static Logger log = Logger.getLogger("TestLog");  //      
    
        public static void main(String[] args) throws IOException {
            
            log.setLevel(Level.ALL);//  logger        ,            
    
            log.info("info");    //    
            log.warning("warning"); //    
            log.log(Level.SEVERE,"server"); //    
            log.fine("fine");
        }
    }
    
    
        :
       15, 2019 12:12:23    JULTest main
      : info
       15, 2019 12:12:23    JULTest main
      : warning
       15, 2019 12:12:23    JULTest main
      : server
       15, 2019 12:12:23    JULTest main
       : fine

    二、Handler
    logging.propertiesファイルが引き出されたので、分析の入り口として使用します.
    ファイルの内容から、前の記事で説明したhandlerコンポーネントの構成がわかります.
    デフォルトHandler:   
    JULで多く使われているのは2つのHandlerクラス:ConsoleHandlerとFileHandler
    ここで、ConsoleHandlerはコンソール出力のデフォルト処理クラスであり、FileHandlerはファイル出力のデフォルト処理クラスである
     プロファイルを変更してシステムログの処理方法を変更できますが、コードから変更する方が柔軟です.
    例:1、コンソールHandler処理クラスのデフォルトレベルを変更する
    import java.io.IOException;
    import java.util.logging.*;
    
    public class JULTest {
        
         public static Logger log = Logger.getLogger("TestLog");  //      
    
        public static void main(String[] args) throws IOException {
            
            log.setLevel(Level.ALL);//  logger        ,            
    
            log.setUseParentHandlers(false); //         
    
            ConsoleHandler consoleHandler = new ConsoleHandler(); //         Handler
            consoleHandler.setLevel(Level.INFO); //         
            log.addHandler(consoleHandler); // Handler  logger 
    
            log.info("info");    //    
            log.warning("warning"); //    
            log.log(Level.SEVERE,"server"); //    
            log.fine("fine");
        }
    }
    
    
        :
       15, 2019 12:03:56    JULTest main
      : info
       15, 2019 12:03:56    JULTest main
      : warning
       15, 2019 12:03:56    JULTest main
      : server

    上のコードはコンソールHandlerを新規作成し、レベルがINFOに設定されているため、結果としてINFO以上のレベルのみを出力するログになります.
    注意:log.setuUseParentHandlers(false)がない場合.親Handlerと子Handlerの両方が有効になり、ログの内容が2パス出力されます.
    2、ファイルFileHandler処理類の処理方式を変更する
    import java.io.IOException;
    import java.util.logging.*;
    
    public class JULTest {
        
         public static Logger log = Logger.getLogger("TestLog");  //      
    
        public static void main(String[] args) throws IOException {
            
            log.setLevel(Level.ALL);//  logger        ,            
    
            log.setUseParentHandlers(false); //         
    
            FileHandler fileHandler = new FileHandler("    /testJUL.log");
            fileHandler.setLevel(Level.ALL); //    
            log.addHandler(fileHandler); //  Handler
    
            log.info("info");    //    
            log.warning("warning"); //    
            log.log(Level.SEVERE,"server"); //    
            log.fine("fine");
        }
    }

     testJUL.logの内容は以下の通りです
    
    
    
    
      2019-01-15T00:22:58
      1547482978598
      0
      TestLog
      INFO
      JULTest
      main
      1
      info
    
    
      2019-01-15T00:22:58
      1547482978622
      1
      TestLog
      WARNING
      JULTest
      main
      1
      warning
    
    
      2019-01-15T00:22:58
      1547482978622
      2
      TestLog
      SEVERE
      JULTest
      main
      1
      server
    
    
      2019-01-15T00:22:58
      1547482978622
      3
      TestLog
      FINER
      JULTest
      main
      1
      fine
    
    
    

    3、カスタムHandler
    ログでカスタム操作を行う場合があります.カスタムHandlerを作成し、loggerのHandlersに追加する必要があります.
    //  Handler      Handler
    public class MyHandler extends Handler {
    
        private LogRecord record;
        
        //
        @Override
        public void publish(LogRecord record) {
            this.record = record;
            ........(     )
        }
    
        @Override
        public void flush() {
            System.out.println("logger:"+this.record.getLoggerName()+"flush");
        }
    
        @Override
        public void close() throws SecurityException {
            System.out.println("logger:"+this.record.getLoggerName()+"close");
        }
    }
    
    public class JULTest {
        
         public static Logger log = Logger.getLogger("TestLog");  //      
    
        public static void main(String[] args) throws IOException {
            
            log.setLevel(Level.ALL);//  logger        ,            
    
            log.setUseParentHandlers(false); //         
    
            MyHandler myHandler = new MyHandler();  //            
            log.addHandler(myHandler); //         
    
            log.info("info");    //    
            log.warning("warning"); //    
            log.log(Level.SEVERE,"server"); //    
            log.fine("fine");
        }
    }
    

     
    三、Formatter
    上記のログファイルのデフォルト出力はxml形式であり、明らかに表示に不利であることがわかります.コードを使用して実装できるように、ログ出力スタイルを変更する必要があります.
    //  Formatter         
    public class MyFormate extends Formatter {
    
        @Override
        public String format(LogRecord record) {
            return new Date()+"-["+record.getSourceClassName()+"."+record.getSourceMethodName()+"]"+record.getLevel()+":"+record.getMessage()+"
    "; } } public class JULTest { public static Logger log = Logger.getLogger("TestLog"); // public static void main(String[] args) throws IOException { log.setLevel(Level.ALL);// logger , log.setUseParentHandlers(false); // FileHandler fileHandler = new FileHandler(" /testJUL.log"); fileHandler.setLevel(Level.ALL); // fileHandler.setFormatter(new MyFormate()); // log.addHandler(fileHandler); // Handler log.info("info"); // log.warning("warning"); // log.log(Level.SEVERE,"server"); // log.fine("fine"); } }

    このときtestJUL.logの出力スタイルはより直感的で簡潔になりました.
    Tue Jan 15 00:36:09 CST 2019-[JULTest.main]INFO:info
    Tue Jan 15 00:36:09 CST 2019-[JULTest.main]WARNING:warning
    Tue Jan 15 00:36:09 CST 2019-[JULTest.main]SEVERE:server
    Tue Jan 15 00:36:09 CST 2019-[JULTest.main]FINER:fine

    まとめ
           1、JULはレベルの整数比でログを出力するかどうかを決定し、対外的には分かりやすいレベル名を使用する設計で、システム設計を明確かつ簡便にし、学習に値する.
           2、JULのlogging.propertiseは基本的なログ制御属性を配置して、このプロファイルを変更してシステムログの出力を制御することができる
           3、JULのHandlerはJULのログ制御を非常に柔軟にさせるが、loggerは複数のHandlerを備えることができ、Handler間の干渉と冗長性を考慮する必要がある.
          4、JULのFormatterはJULのログの出力をもっと優雅で美しくして、学習の過程の中で、私達は更に多くログの必要な情報を正確に出力することを考慮することができて、例えば類名、方法名など
    コメント
    多く先辈を参考にして、ソースコードは深く理解していないで、また多く検讨することを望んで、文章の构造はあまり厳格ではありませんて、后で引き続き改善して、ありがとうございます
    一部内容参考文章:qingkangxu-JDK Logging深く分析する