日誌是系統開發過程當中用於排查問題重要的記錄。一般使用日誌來記錄系統運行的行爲,什麼時間點發生了什麼 事情。Java中經常使用的莫過於Log4j框架了。下面主要圍繞Log4j的基礎知識、Log4j的使用方式以及實際開發過程當中使用slf4j+log4j作日誌等幾方面進行展開:java
(一)Log4j的基礎知識web
log4j是java中經常使用的一種日誌框架,能夠用來控制日誌的輸出格式、輸出位置等。輸出位置能夠是控制檯、文件、數據庫、指定服務器等。下面介紹的內容,主要是經常使用的一些配置方式。spring
(1)經常使用日誌級別數據庫
log4j中提供了不一樣的日誌級別,所謂日誌級別,就是能夠在不一樣的場景下控制日誌的輸出。經過日誌級別的控制,能夠將不一樣級別的日誌輸出到不一樣的位置。經常使用的日誌級別主要有如下四種:apache
DEBUG、INFO、WARN、ERROR服務器
他們的級別從左到右依次是從低到高。若是輸出DEBUG級別的日誌,那麼DEBUG、INFO、WARN、ERROR級別的日誌都會輸出。app
一般經過控制日誌級別將日誌輸出到不一樣的文件,便於異常狀況的排查。框架
(2)Log4j的配置方法ide
使用Log4j須要配置log4j.properties配置文件(還能夠使用xml格式配置,該部分以properties格式介紹)。佈局
下面介紹一下配置文件的配置方法,經過該部分的介紹,能夠輕鬆讀懂別人的配置文件,亦能本身配置配置文件。
log4j.rootLogger=WARN, Console, File1
經過log4j.rootLogger配置整個應用的日誌輸出級別和輸出位置。
WARN指定了日誌的輸出級別,Console和File1指定了日誌輸出的位置,名稱隨便起,可是通常起的要有意義,以加強可讀性。
若是須要對具體的包、或者類單獨控制日誌的輸出,能夠按包進行配置,配置方式以下:
log4j.logger.com.iot=DEBUG, File2
改配置的意思是com.iot包下的全部類的日誌輸出級別是DEBUG,輸出位置是File2。
appender是配置文件的輸出位置,在根配置中,指定了文件的輸出位置名字,那麼該部分就是指定具體輸出位置的形式
log4j提供了四種經常使用的輸出位置控制,他們是:
一般使用第一種、第三種和第四種,第二種使用較少,由於只能往一個文件中寫日誌,日誌會愈來愈大,查看不方便。
使用方式:
#Console log4j.appender.Console=org.apache.log4j.ConsoleAppender #RollingFile log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender log4j.appender.RollingFile.File=../logs/jeesite/jeesite.log
其中加紅表粗的字體是根配置中指定的輸出位置名,在這裏具體指定了是用的輸出實現。若是是輸出到文件,須要指定文件的路徑。
這裏特別強調,若是使用RollingFileAppender,須要指定文件的大小,和文件的個數;
使用MaxFileSize指定文件的大小,即當日志文件大小大於1KB時,就會產生新的日誌文件。可是硬盤空間有限,日誌文件不能無限量的增長,因此須要限制文件的個數。
使用MaxBackupIndex指定文件的個數,達到該個數以後,再次產生的日誌文件會覆蓋掉老的日誌文件。
一個好的日誌格式,能夠一眼能發現關鍵信息所在。log4j提供了集中日誌格式實現:
一般使用第二種自定義佈局格式,經過layout指定具體的佈局格式,使用方式:
log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout
使用了自定義佈局格式,就須要自定義佈局格式,經過layout.ConversionPattern指定日誌格式,以下所示:
log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
注:-5表明佔5個字符,爲了輸出對齊使用。
其中各字母的含義以下:
在根配置中,指定了日誌級別,該級別是對全部的輸出位置進行控制的。可是好比咱們須要將ERROR級別的日誌輸出到一個文件中,那麼就須要經過Threshold來指定了。使用方法:
log4j.appender.RollingFile.Threshold=ERROR
(二)Log4j的使用方式
上面介紹了Log4j的基礎知識和經常使用的配置方式,那麼在使用的過程當中,有如下幾個步驟:
(1)導入log4j的jar包
(2)按照需求編寫log4j.properties配置文件
例如:
log4j.rootLogger=DEBUG, Console, File #Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d %-5p [%c{5}] - %m%n #File log4j.appender.File=org.apache.log4j.FileAppender log4j.appender.File.File=E://servlet.log log4j.appender.File.layout=org.apache.log4j.PatternLayout log4j.appender.File.layout.ConversionPattern=%d %-5p [%c{5}] - %m%n
(3)在web.xml中配置log4j
編寫一個servlet,令其隨web應用的啓動而啓動。
直接代碼:
web.xml配置:
<servlet> <servlet-name>log4jServlet</servlet-name> <servlet-class>Log4jServlet</servlet-class> <init-param> <param-name>log4j</param-name> <param-value>WEB-INF/log4j.properties</param-value> </init-param> <load-on-startup>1</load-on-startup><!-- 指定servlet隨web應用部署而自啓動,值越小,優先級越高 --> </servlet> <servlet-mapping> <servlet-name>log4jServlet</servlet-name> <url-pattern>/log4jServlet.do</url-pattern> </servlet-mapping>
Log4jServlet代碼:
public class Log4jServlet extends HttpServlet { @Override public void init() throws ServletException { super.init(); String prefix = getServletContext().getRealPath("/"); String log4jFile = getServletConfig().getInitParameter("log4j"); String log4jConfigPath = prefix + log4jFile; PropertyConfigurator.configure(log4jConfigPath); } }
直接上代碼:
web.xml文件:
<context-param> <param-name>log4j</param-name> <param-value>WEB-INF/log4j.properties</param-value> </context-param> <listener> <listener-class>LogListener</listener-class> </listener>
listener監聽器實現代碼:
public class LogListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { } @Override public void contextInitialized(ServletContextEvent servletContextEvent) { ServletContext ctx = servletContextEvent.getServletContext(); String prefix = ctx.getRealPath("/"); String log4jFile = ctx.getInitParameter("log4j"); String log4jConfigPath = prefix + log4jFile; PropertyConfigurator.configure(log4jConfigPath); System.out.println("initialized log4j finish"); } }
若是使用spring,那麼能夠直接使用spring提供的log4j加載監聽器,具體使用可查資料。
(4)日誌使用
配置好上面的過程以後,就能夠在代碼中直接使用了,使用代碼:
private final static Logger logger = Logger.getLogger(LogServlet.class); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.debug("執行servlet"); logger.info("執行servlet"); logger.warn("執行servlet"); logger.error("執行servlet"); }
上面的代碼執行完,就會根據日誌的配置,在預期的位置輸出日誌
(三)實際開發過程當中使用slf4j+log4j作日誌
上面內容講完以後,就能夠在開發過程當中使用log4j框架進行日誌輸出了。可是一般在開發中咱們常常會見到slf4j。
SLF4J:即簡單日誌門面(Simple Logging Facade for Java),不是具體的日誌解決方案,它只服務於各類各樣的日誌系統。按照官方的說法,SLF4J是一個用於日誌系統的簡單Facade,容許最終用戶在部署其應用時使用其所但願的日誌系統。
在使用SLF4J的時候,不須要在代碼中或配置文件中指定你打算使用那個具體的日誌系統,SLF4J提供了統一的記錄日誌的接口,只要按照其提供的方法記錄便可,最終日誌的格式、記錄級別、輸出方式等經過具體日誌系統的配置來實現,所以能夠在應用中靈活切換日誌系統。
有關slf4j的詳細東西,這裏不作過多介紹,只介紹如何使用slf4j+log4j實現日誌記錄。
基本的配置和使用log4j相同,可是須要導入下面三個包
使用的過程當中,Logger類的定義以下:
private final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LogServlet.class);
其餘的和單獨使用log4j沒有什麼區別。