tomcat(7)日志记录器
生活随笔
收集整理的這篇文章主要介紹了
tomcat(7)日志记录器
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
【0】README
0.1)本文部分文字描述轉自:“深入剖析tomcat”,旨在學習 “tomcat的日志記錄器”?的基礎知識;
0.2)intro to 日志記錄器:日志記錄器是用來記錄消息的組件;
0.3)for complete source code, please visit?https://github.com/pacosonTang/HowTomcatWorks/tree/master/chapter7
0.4)溫馨建議:建議閱讀本文之前,已閱讀過 tomcat(1~6)的系列文章,因為它們是環(huán)環(huán)相扣的;
【1】Logger接口(日志記錄器都必須實現(xiàn) org.apache.catalina.Logger接口) 1)Logger接口提供了一些log() 方法來寫日志; 2)Logger的某些log() 方法接受一個日志級別,定義了5種日志級別:FATAL, ERROR, WARNING, INFORMATION , DEBUG; 3)獲取和設置日志級別:getVerbosity() and setVerbosity(); 4)將日志記錄器和某servlet容器關聯(lián):?getContainer() and setContainer(); 5)添加或移除PropertyChangeListener:addPropertyChangeListener() and removePropertyChangeListener();
【2】Tomcat的日志記錄器 1)Tomcat提供了3種日志記錄器,分別是:FileLogger, SystemErrorLogger, SystemOutLogger;類圖如下:(干貨——Tomcat提供了3種日志記錄器)
【2.1】LoggerBase類(以tomcat4的 LoggerBase為例) 1)LoggerBase類:實現(xiàn)了Logger接口中的除log(String name)外的所有方法; 2)LoggerBase類的日志等級設置:日志等級使用一個名為 verbosity來設置,默認值為 ERROR; protected int verbosity = ERROR; // LoggerBase.java 3)接收日志等級的兩個log重載方法:只有當傳入的日志等級比當前實例中verbosity變量指定的等級低時,才會調用重載方法log(String msg)來記錄日志; public void log(String message, int verbosity) { // LoggerBase.javaif (this.verbosity >= verbosity)log(message);}public void log(String message, Throwable throwable, int verbosity) { // LoggerBase.javaif (this.verbosity >= verbosity)log(message, throwable);} 【2.2】SystemOutLogger類 1)該類的特點:接收到的每條日志消息都會傳遞給 System.out.println(); 【2.3】SystemErrLogger類 1)該類的特點:接收到的每條日志消息都會傳遞給 System.err.println();
【2.4】FileLogger類 1)intro:?它將servlet容器中接收到的日志消息寫到一個文件,并且可以選擇是否要為每條消息添加時間戳; 2)LoggerBase.start() 方法 和?LoggerBase.stop()方法:Tomcat4中,LoggerBase() 類的start方法和stop方法只負責啟動和關閉文件日志記錄器時觸發(fā)觸發(fā)生命周期事件,并不做其他事情,源代碼如下: 3)FileLogger.log()方法(最重要的方法):該方法會將接收到的日志消息寫到一個日志文件中,(當日期發(fā)生變化時,log方法會關閉當前日志文件,并打開一個新文件),下面看一下open方法,close方法和log方法的具體實現(xiàn): 3.1)open()方法: step1)檢查要創(chuàng)建的日志文件所在的目錄是否存在,不存在,就創(chuàng)建該目錄。目錄位置是存儲在類變量 directory中的; step2)根據(jù)目錄路徑,創(chuàng)建位于指定位置的日志文件,并添加相應的前綴,當前日志和后綴; step3)創(chuàng)建 java.io.PrintWriter實例,具體執(zhí)行寫路徑名操作的是 java.io.FileWriter對象的實例; step4)將PrintWriter實例賦值給 writer變量; private void open() { // FileLogger.open() 方法// Create the directory if necessaryFile dir = new File(directory);if (!dir.isAbsolute()) // step1dir = new File(System.getProperty("catalina.base"), directory);dir.mkdirs();// Open the current log filetry {String pathname = dir.getAbsolutePath() + File.separator +prefix + date + suffix; // step2writer = new PrintWriter(new FileWriter(pathname, true), true); //step3,4} catch (IOException e) {writer = null;}} 3.2)close()方法: step1)intro:close方法負責確保將 PrintWriter 實例中所有的日志消息都寫到文件中,關閉 PrintWriter 實例,將其引用設置為null,并將日期字符串清空; private void close() { // FileLogger.close() 方法if (writer == null)return;writer.flush();writer.close();writer = null;date = "";} 3.3)log()方法: step1)該方法會先創(chuàng)建 java.sql.Timestamp類 的一個實例;(使用 Timestamp類的toString() 方法可以獲取當前日期的字符串表示形式,toString() 方法返回的日期格式為 yyyy-mm-dd hh:mm: ss.fffffffff, fffffffff 表示從00:00:00 起經過的納秒數(shù),若是只想要獲取日期和小時,可以調用 subString方法,String substr = ts.toString().substring(0,19)) step2)獲取日期部分; String tsDate = tsString.substring(0,10); step3)log方法將tsDate與 字符串形式的變量date 相比較。若不等,則log方法會關閉當前日志文件,并打開一個新日志文件; step4)log方法將日志信息寫到 PrintWriter實例中,而PrintWriter實例將輸出流寫入到日志文件中。(是否加上時間戳,依據(jù)布爾變量 timestamp) public void log(String msg) { FileLogger.log() 方法// Construct the timestamp we will use, if requestedTimestamp ts = new Timestamp(System.currentTimeMillis()); // step1String tsString = ts.toString().substring(0, 19); // step1String tsDate = tsString.substring(0, 10); // step2// If the date has changed, switch log filesif (!date.equals(tsDate)) { // step3synchronized (this) {if (!date.equals(tsDate)) {close();date = tsDate;open(); // this highlight line.}}}// Log this message, timestamped if necessaryif (writer != null) { // step4if (timestamp) {writer.println(tsString + " " + msg);} else {writer.println(msg);}}}
【3】應用程序 1)本文的應用程序同章節(jié)6的應用程序相似,區(qū)別在于, SimpleContext 對象關聯(lián)了一個 FileLogger 組件。 public final class Bootstrap {public static void main(String[] args) {Connector connector = new HttpConnector();Wrapper wrapper1 = new SimpleWrapper(); // 創(chuàng)建Wrapper容器wrapper1.setName("Primitive"); // 填充容器wrapper1.setServletClass("servlet.PrimitiveServlet");Wrapper wrapper2 = new SimpleWrapper();wrapper2.setName("Modern");wrapper2.setServletClass("servlet.ModernServlet");Loader loader = new SimpleLoader(); // 創(chuàng)建類加載器Context context = new SimpleContext(); // 創(chuàng)建Context容器,可以包含多個Wrapper容器context.addChild(wrapper1);context.addChild(wrapper2);Mapper mapper = new SimpleContextMapper(); // 創(chuàng)建映射器,提供請求資源的 URI到 請求資源(servlet)名稱的映射mapper.setProtocol("http");LifecycleListener listener = new SimpleContextLifecycleListener();((Lifecycle) context).addLifecycleListener(listener);context.addMapper(mapper);context.setLoader(loader);// context.addServletMapping(pattern, name);context.addServletMapping("/Primitive", "Primitive");context.addServletMapping("/Modern", "Modern");// ------ add logger -------- highlightSystem.setProperty("catalina.base", System.getProperty("user.dir")); // 設置日志目錄FileLogger logger = new FileLogger(); // 創(chuàng)建文件日志記錄器logger.setPrefix("FileLog_");logger.setSuffix(".txt"); logger.setTimestamp(true);logger.setDirectory("webroot");context.setLogger(logger);//--------------------------- highlight over.connector.setContainer(context);try {connector.initialize(); // 獲得服務器套接字((Lifecycle) connector).start(); // 接收client發(fā)出的 http請求,并做處理。((Lifecycle) context).start(); // 觸發(fā)生命周期事件// make the application wait until we press a key.System.in.read();((Lifecycle) context).stop();}catch (Exception e) {e.printStackTrace();} }}
Attention)照慣例,本文總結了上述測試用例的調用過程示例圖 A1)寫在前面:在SimpleContext的start() 方法中調用了 log方法; A2)log方法的調用steps 如下圖所示:
2)運行參數(shù) E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java -cp .;lib/servlet.jar;lib/catalina_4_1_24.jar;E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\webroot com.tomcat.chapter7.startup.B ootstrap SimpleContextLifecycleListener's event before_start Starting SimpleLoader Starting Wrapper Primitive Starting Wrapper Modern SimpleContextLifecycleListener's event start Starting context. SimpleContextLifecycleListener's event after_start ModernServlet -- init
3)運行結果
3.1)生成的日志文件為(日志路徑在 SystemgetProperty("user.dir") + “/webroot”): 2016-04-17 17:16:58 HttpConnector Opening server socket on all host IP addresses 2016-04-17 17:16:58 HttpConnector[8080] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][0] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][1] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][2] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][3] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][4] Starting background thread 2016-04-17 17:16:58 starting Context 2016-04-17 17:16:58 Context started 3.2)訪問記錄
【1】Logger接口(日志記錄器都必須實現(xiàn) org.apache.catalina.Logger接口) 1)Logger接口提供了一些log() 方法來寫日志; 2)Logger的某些log() 方法接受一個日志級別,定義了5種日志級別:FATAL, ERROR, WARNING, INFORMATION , DEBUG; 3)獲取和設置日志級別:getVerbosity() and setVerbosity(); 4)將日志記錄器和某servlet容器關聯(lián):?getContainer() and setContainer(); 5)添加或移除PropertyChangeListener:addPropertyChangeListener() and removePropertyChangeListener();
【2】Tomcat的日志記錄器 1)Tomcat提供了3種日志記錄器,分別是:FileLogger, SystemErrorLogger, SystemOutLogger;類圖如下:(干貨——Tomcat提供了3種日志記錄器)
【2.1】LoggerBase類(以tomcat4的 LoggerBase為例) 1)LoggerBase類:實現(xiàn)了Logger接口中的除log(String name)外的所有方法; 2)LoggerBase類的日志等級設置:日志等級使用一個名為 verbosity來設置,默認值為 ERROR; protected int verbosity = ERROR; // LoggerBase.java 3)接收日志等級的兩個log重載方法:只有當傳入的日志等級比當前實例中verbosity變量指定的等級低時,才會調用重載方法log(String msg)來記錄日志; public void log(String message, int verbosity) { // LoggerBase.javaif (this.verbosity >= verbosity)log(message);}public void log(String message, Throwable throwable, int verbosity) { // LoggerBase.javaif (this.verbosity >= verbosity)log(message, throwable);} 【2.2】SystemOutLogger類 1)該類的特點:接收到的每條日志消息都會傳遞給 System.out.println(); 【2.3】SystemErrLogger類 1)該類的特點:接收到的每條日志消息都會傳遞給 System.err.println();
【2.4】FileLogger類 1)intro:?它將servlet容器中接收到的日志消息寫到一個文件,并且可以選擇是否要為每條消息添加時間戳; 2)LoggerBase.start() 方法 和?LoggerBase.stop()方法:Tomcat4中,LoggerBase() 類的start方法和stop方法只負責啟動和關閉文件日志記錄器時觸發(fā)觸發(fā)生命周期事件,并不做其他事情,源代碼如下: 3)FileLogger.log()方法(最重要的方法):該方法會將接收到的日志消息寫到一個日志文件中,(當日期發(fā)生變化時,log方法會關閉當前日志文件,并打開一個新文件),下面看一下open方法,close方法和log方法的具體實現(xiàn): 3.1)open()方法: step1)檢查要創(chuàng)建的日志文件所在的目錄是否存在,不存在,就創(chuàng)建該目錄。目錄位置是存儲在類變量 directory中的; step2)根據(jù)目錄路徑,創(chuàng)建位于指定位置的日志文件,并添加相應的前綴,當前日志和后綴; step3)創(chuàng)建 java.io.PrintWriter實例,具體執(zhí)行寫路徑名操作的是 java.io.FileWriter對象的實例; step4)將PrintWriter實例賦值給 writer變量; private void open() { // FileLogger.open() 方法// Create the directory if necessaryFile dir = new File(directory);if (!dir.isAbsolute()) // step1dir = new File(System.getProperty("catalina.base"), directory);dir.mkdirs();// Open the current log filetry {String pathname = dir.getAbsolutePath() + File.separator +prefix + date + suffix; // step2writer = new PrintWriter(new FileWriter(pathname, true), true); //step3,4} catch (IOException e) {writer = null;}} 3.2)close()方法: step1)intro:close方法負責確保將 PrintWriter 實例中所有的日志消息都寫到文件中,關閉 PrintWriter 實例,將其引用設置為null,并將日期字符串清空; private void close() { // FileLogger.close() 方法if (writer == null)return;writer.flush();writer.close();writer = null;date = "";} 3.3)log()方法: step1)該方法會先創(chuàng)建 java.sql.Timestamp類 的一個實例;(使用 Timestamp類的toString() 方法可以獲取當前日期的字符串表示形式,toString() 方法返回的日期格式為 yyyy-mm-dd hh:mm: ss.fffffffff, fffffffff 表示從00:00:00 起經過的納秒數(shù),若是只想要獲取日期和小時,可以調用 subString方法,String substr = ts.toString().substring(0,19)) step2)獲取日期部分; String tsDate = tsString.substring(0,10); step3)log方法將tsDate與 字符串形式的變量date 相比較。若不等,則log方法會關閉當前日志文件,并打開一個新日志文件; step4)log方法將日志信息寫到 PrintWriter實例中,而PrintWriter實例將輸出流寫入到日志文件中。(是否加上時間戳,依據(jù)布爾變量 timestamp) public void log(String msg) { FileLogger.log() 方法// Construct the timestamp we will use, if requestedTimestamp ts = new Timestamp(System.currentTimeMillis()); // step1String tsString = ts.toString().substring(0, 19); // step1String tsDate = tsString.substring(0, 10); // step2// If the date has changed, switch log filesif (!date.equals(tsDate)) { // step3synchronized (this) {if (!date.equals(tsDate)) {close();date = tsDate;open(); // this highlight line.}}}// Log this message, timestamped if necessaryif (writer != null) { // step4if (timestamp) {writer.println(tsString + " " + msg);} else {writer.println(msg);}}}
【3】應用程序 1)本文的應用程序同章節(jié)6的應用程序相似,區(qū)別在于, SimpleContext 對象關聯(lián)了一個 FileLogger 組件。 public final class Bootstrap {public static void main(String[] args) {Connector connector = new HttpConnector();Wrapper wrapper1 = new SimpleWrapper(); // 創(chuàng)建Wrapper容器wrapper1.setName("Primitive"); // 填充容器wrapper1.setServletClass("servlet.PrimitiveServlet");Wrapper wrapper2 = new SimpleWrapper();wrapper2.setName("Modern");wrapper2.setServletClass("servlet.ModernServlet");Loader loader = new SimpleLoader(); // 創(chuàng)建類加載器Context context = new SimpleContext(); // 創(chuàng)建Context容器,可以包含多個Wrapper容器context.addChild(wrapper1);context.addChild(wrapper2);Mapper mapper = new SimpleContextMapper(); // 創(chuàng)建映射器,提供請求資源的 URI到 請求資源(servlet)名稱的映射mapper.setProtocol("http");LifecycleListener listener = new SimpleContextLifecycleListener();((Lifecycle) context).addLifecycleListener(listener);context.addMapper(mapper);context.setLoader(loader);// context.addServletMapping(pattern, name);context.addServletMapping("/Primitive", "Primitive");context.addServletMapping("/Modern", "Modern");// ------ add logger -------- highlightSystem.setProperty("catalina.base", System.getProperty("user.dir")); // 設置日志目錄FileLogger logger = new FileLogger(); // 創(chuàng)建文件日志記錄器logger.setPrefix("FileLog_");logger.setSuffix(".txt"); logger.setTimestamp(true);logger.setDirectory("webroot");context.setLogger(logger);//--------------------------- highlight over.connector.setContainer(context);try {connector.initialize(); // 獲得服務器套接字((Lifecycle) connector).start(); // 接收client發(fā)出的 http請求,并做處理。((Lifecycle) context).start(); // 觸發(fā)生命周期事件// make the application wait until we press a key.System.in.read();((Lifecycle) context).stop();}catch (Exception e) {e.printStackTrace();} }}
Attention)照慣例,本文總結了上述測試用例的調用過程示例圖 A1)寫在前面:在SimpleContext的start() 方法中調用了 log方法; A2)log方法的調用steps 如下圖所示:
2)運行參數(shù) E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java -cp .;lib/servlet.jar;lib/catalina_4_1_24.jar;E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\webroot com.tomcat.chapter7.startup.B ootstrap SimpleContextLifecycleListener's event before_start Starting SimpleLoader Starting Wrapper Primitive Starting Wrapper Modern SimpleContextLifecycleListener's event start Starting context. SimpleContextLifecycleListener's event after_start ModernServlet -- init
3)運行結果
3.1)生成的日志文件為(日志路徑在 SystemgetProperty("user.dir") + “/webroot”): 2016-04-17 17:16:58 HttpConnector Opening server socket on all host IP addresses 2016-04-17 17:16:58 HttpConnector[8080] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][0] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][1] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][2] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][3] Starting background thread 2016-04-17 17:16:58 HttpProcessor[8080][4] Starting background thread 2016-04-17 17:16:58 starting Context 2016-04-17 17:16:58 Context started 3.2)訪問記錄
總結
以上是生活随笔為你收集整理的tomcat(7)日志记录器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win10卡顿严重完美解决的方法
- 下一篇: follow 开源项目关于NoClass