學(xué)院網(wǎng)站建設(shè)管理規(guī)章制度谷歌瀏覽器官網(wǎng)入口
JUL全稱Java util logging
入門(mén)案例
先來(lái)看著入門(mén)案例,直接創(chuàng)建logger對(duì)象,然后傳入日志級(jí)別和打印的信息,就能在控制臺(tái)輸出信息。
?可以看出只輸出了部分的信息,其實(shí)默認(rèn)的日志控制器是有一個(gè)默認(rèn)的日志級(jí)別的,默認(rèn)就是info 所以最多優(yōu)先級(jí)比info低的都不能輸出。
?
@Testpublic void testQuick() {System.out.println("hello");//傳入唯一標(biāo)識(shí),一般為當(dāng)前的類(lèi)名Logger logger= Logger.getLogger("com.itheima.julTest");logger.severe("severe logger message");//logger.log(Level.severe,"logger message");logger.warning("warning logger message");logger.info("info logger message"); //默認(rèn)日志級(jí)別logger.config("config logger message");logger.fine("fine logger message");logger.finer("finer logger message");logger.finest("finest logger message");}
自定義日志級(jí)別
設(shè)置handler,設(shè)置handler和logger的級(jí)別
- Handler:日志處理器,每個(gè)Logger會(huì)關(guān)聯(lián)持有多個(gè)Handler,Logger會(huì)把日志交給Handler進(jìn)行處理,由Handler負(fù)責(zé)日志記錄。Handler在這里是一個(gè)抽象,其具體實(shí)現(xiàn)決定了日志輸出的位置,比如控制臺(tái),文件等
也就是說(shuō),通過(guò)使用不同的handler可以將日志輸出到文件或者控制臺(tái)。
下面這個(gè)地方:
? ? ? ? ? ? //logger設(shè)置不使用父logger的handler,不然日志會(huì)重復(fù)記錄。此處后面會(huì)講
? ? ? ? ? ? logger.setUseParentHandlers(false);如果不設(shè)置,將會(huì)輸出兩邊日志信息
@Testpublic void loggerLevel() {//創(chuàng)建日志記錄器,傳入?yún)?shù)是日志記錄器的名稱Logger logger = Logger.getLogger("com.itheima");//創(chuàng)建一個(gè)輸出到控制臺(tái)的handlerConsoleHandler consoleHandler = new ConsoleHandler();//設(shè)置handler的日志級(jí)別為ALL,輸出全部日志。consoleHandler.setLevel(Level.ALL);//把handler添加到logger中l(wèi)ogger.addHandler(consoleHandler);//logger也設(shè)置日志級(jí)別為ALLlogger.setLevel(Level.ALL);//logger設(shè)置不使用父logger的handler,不然日志會(huì)重復(fù)記錄。此處后面會(huì)講logger.setUseParentHandlers(false);//記錄severe級(jí)別信息logger.severe("severe信息");//記錄warning級(jí)別信息logger.warning("warning信息");logger.info("info信息");logger.config("config信息");logger.fine("fine信息");logger.finer("finer信息");logger.finest("finest信息");}
父子關(guān)系
一開(kāi)始以為是繼承,后來(lái)發(fā)現(xiàn)并不是,只是通過(guò)設(shè)置可以復(fù)用一些配置
默認(rèn)父子關(guān)系通過(guò)名稱的層級(jí)關(guān)系來(lái)確定的。層級(jí)關(guān)系用 . 號(hào)分開(kāi)。
也可以通過(guò)手動(dòng)設(shè)置。
JUL在初始化時(shí)會(huì)創(chuàng)建一個(gè)頂層的RootLogger作為所有Logger的父Logger。
下面的代碼中就是:rootlogger->logger1->logger2logger3.
@Testpublic void testLoggerParent(){//創(chuàng)建一個(gè)名稱為aaa的loggerLogger logger1 = Logger.getLogger("aaa");//創(chuàng)建一個(gè)名稱為aaa.bbb的loggerLogger logger2 = Logger.getLogger("aaa.bbb");//創(chuàng)建一個(gè)名稱為aaa.bbb.ccc的loggerLogger logger3 = Logger.getLogger("aaa.bbb.ccc");//此時(shí)logger3的父Logger是logger2, logger2的父logger是logger1//判斷l(xiāng)ogger3的父Logger是不是logger2System.out.println(logger3.getParent() == logger2);//判斷l(xiāng)ogger2的父logger是不是logger1System.out.println(logger2.getParent() == logger1);//logger1的父節(jié)點(diǎn)是頂級(jí)Logger RootLoggerSystem.out.println("logger1的父logger是 " + logger1.getParent());//RootLogger的父LoggerSystem.out.println("RootLogger的父Logger是 " + logger1.getParent().getParent());//手動(dòng)設(shè)置父Loggerlogger3.setParent(logger1);//判斷設(shè)置是否成功System.out.println(logger3.getParent() == logger1);}
子Logger默認(rèn)會(huì)使用父Logger的Handler對(duì)象
如果使用addHandler添加新的handler,也會(huì)使用新添加的handler再輸出一次
?
@Testpublic void testUserParentHandler() {//創(chuàng)建一個(gè)名為aaa的loggerLogger logger1 = Logger.getLogger("aaa");//創(chuàng)建一個(gè)名為aaa.bbb的logger,父Logger是handlerLogger logger2 = Logger.getLogger("aaa.bbb");//創(chuàng)建一個(gè)handlerConsoleHandler consoleHandler = new ConsoleHandler();//把handler添加到logger1和logger2中。logger1.addHandler(consoleHandler);logger2.addHandler(consoleHandler);//使用logger進(jìn)行日志輸出//記錄severe級(jí)別信息logger2.severe("severe信息");//記錄warning級(jí)別信息logger2.warning("warning信息");logger2.info("info信息");logger2.config("config信息");logger2.fine("fine信息");logger2.finer("finer信息");logger2.finest("finest信息");}
分析:
每個(gè)級(jí)別的日志信息輸出了三次,因?yàn)閘ogger2使用了父Logger logger1 ,父Logger的父Logger RootLogger、還有自身的handler共三個(gè)handler,所以日志會(huì)輸出三倍。?
使用logger2.setUseParentHandlers(false); 設(shè)置不使用父Logger的Handler。
FileHandler和SimpleFormatter
前面說(shuō)到了通過(guò)設(shè)置handler可以將日志輸出到文件,這里就測(cè)試一下
?
@Testpublic void testFileHandler(){Logger logger = Logger.getLogger("juldemo.JULDemo");logger.setLevel(Level.ALL);try {//創(chuàng)建一個(gè)輸出到文件的handler,第一個(gè)參數(shù)是生成文件名的pattern,第二個(gè)參數(shù)是是否已追加的方式輸出到文件,默認(rèn)falseFileHandler fileHandler = new FileHandler("D:\\project\\idea\\log_learning\\jul_demo\\logs\\java%u.log",true);//創(chuàng)建一個(gè)SimpleFormatter,輸出格式SimpleFormatter formatter = new SimpleFormatter();//設(shè)置formatterfileHandler.setFormatter(formatter);//設(shè)置日志級(jí)別fileHandler.setLevel(Level.ALL);//把handler添加到loggerlogger.addHandler(fileHandler);//設(shè)置不使用父Logger的handlerlogger.setUseParentHandlers(false);logger.severe("severe信息");//記錄warning級(jí)別信息logger.warning("warning信息");logger.info("info信息");logger.config("config信息");logger.fine("fine信息");logger.finer("finer信息");logger.finest("finest信息");} catch (IOException e) {e.printStackTrace();}}
通過(guò)配置文件配置
#配置RootLogger的Handler,有java.util.logging.ConsoleHandler,java.util.logging.FileHandler
handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler#配置RootLogger的日志級(jí)別ALL
.level= ALLjava.util.logging.FileHandler.pattern = D:\\project\\idea\\log_learning\\jul_demo\\logs\\java%u.log
#默認(rèn)一個(gè)文件最多50000條日志記錄
java.util.logging.FileHandler.limit = 50000
#設(shè)置FileHandle的日志級(jí)別為ALL
java.util.logging.FileHandler.level= ALL#配置生成一個(gè)文件
java.util.logging.FileHandler.count = 1
#配置使用SimpleFormatter格式器
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
#配置追加模式
java.util.logging.FileHandler.append=true#ConsoleHandler的日志級(jí)別默認(rèn)是INFO
java.util.logging.ConsoleHandler.level = ALL
#ConsoleHandler的默認(rèn)格式化器時(shí)SimpleFormatter
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter#設(shè)置日志格式
java.util.logging.SimpleFormatter.format= %1$tc %2$s%n%4$s: %5$s%6$s%n
@Testpublic void testCustomConfig(){LogManager logManager = LogManager.getLogManager();try {logManager.readConfiguration(this.getClass().getClassLoader().getResourceAsStream("logging.properties"));Logger logger = Logger.getLogger("juldemo.JULDemo");logger.severe("severe信息");//記錄warning級(jí)別信息logger.warning("warning信息");logger.info("info信息");logger.config("config信息");logger.fine("fine信息");logger.finer("finer信息");logger.finest("finest信息");} catch (IOException e) {e.printStackTrace();}}