由於項目需要滿足每天輸出想保存的日誌文件,且文件大於10M時會創建新的這個條件,且我用的是idea的maven項目,ssm框架,
所以我採用了logback的日誌框架.爲什麼會選擇logback框架?是因爲logback比log4j效率更高,更利於管理.
爲什麼我會記錄這個經歷,是因爲這個日誌管理確實蠻重要,而且還是我在學習logback的時候報了n多的錯.我當時在百度找資料的時候,基本每個網頁都閱讀了一遍,苦不堪言.最後還是靠自己在百度上學習2天總結的經驗,自己弄了一個.
好了,我們開始弄,
一 首先我們引入maven依賴
<!-- Log4j start --> <!--<dependency>--> <!--<groupId>log4j</groupId>--> <!--<artifactId>log4j</artifactId>--> <!--<version>1.2.17</version>--> <!--</dependency>--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>0.9.28</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-access</artifactId> <version>0.9.28</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>0.9.28</version> </dependency> <!-- https://mvnrepository.com/artifact/org.logback-extensions/logback-ext-spring --> <dependency> <groupId>org.logback-extensions</groupId> <artifactId>logback-ext-spring</artifactId> <version>0.1.1</version> </dependency>
因爲要讓spring監測,所以有最後面的那個依賴, 最初我引入的依賴,版本不是現在這個版本,我在百度上看到的依賴會報倆個監測的錯,其實是SLF4J的版本跟logback版本的不兼容,SLF4J的版本高了,或者logback版本低了.這個錯是啓動報錯.解決完開始下一步
二 我們可以先在web.xml裏添加logback的監測
<context-param> <param-name>logbackConfigLocation</param-name> <param-value>classpath:logback.xml</param-value> </context-param> <listener> <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class> </listener>
這步沒報什麼錯,開始下一步
三 在mybatis-config.xml添加一些配置,我不知道爲什麼mybatis裏會有日誌配置,但沒關係,我只需要知道可以配置選擇哪種日誌框架,
<setting name="logImpl" value="STDOUT_LOGGING"/>
這個設置是說,它會自動去找日誌框架,這個必須要,以前我配的是
<setting name="logImpl" value="LOG4J"/>
到這一步的時候,我還出過一些問題,當時我找的是logback的資料,而這個logImpl設置裏沒logback的值,可選的值只有:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING這些.後來看的資料多了,就知道logback要配合SLF4J使用,所以我設置了
<setting name="logImpl" value="SLF4J"/>
到了這一步,環境是沒什麼問題,現在我們來配置logback.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 說明: 1、日誌級別及文件 日誌記錄採用分級記錄,級別與日誌文件名相對應,不同級別的日誌信息記錄到不同的日誌文件中 例如:error級別記錄到log_error_xxx.log或log_error.log(該文件爲當前記錄的日誌文件),而log_error_xxx.log爲歸檔日誌, 日誌文件按日期記錄,同一天內,若日誌文件大小等於或大於2M,則按0、1、2...順序分別命名 例如log-level-2013-12-21.0.log 其它級別的日誌也是如此。 3、Appender FILEERROR對應error級別,文件名以log-error-xxx.log形式命名 FILEWARN對應warn級別,文件名以log-warn-xxx.log形式命名 FILEINFO對應info級別,文件名以log-info-xxx.log形式命名 stdout將日誌信息輸出到控制上,爲方便開發測試使用 --> <contextName>自己的項目名字</contextName> <property name="LOG_PATH" value="G:\\JavaWebLogs"/> <!--設置系統日誌目錄--> <property name="APPDIR" value="aaa"/> <!-- 日誌記錄器,日期滾動記錄 錯誤--> <appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌文件的路徑及文件名 --> <file>${LOG_PATH}/${APPDIR}/log_error.log</file> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 歸檔的日誌文件的路徑,例如今天是2013-12-21日誌,當前寫的日誌文件路徑爲file節點指定, 可以將此文件與file指定文件路徑設置爲不同路徑,從而將當前日誌文件或歸檔日誌文件置不同的目錄。 而2013-12-21的日誌文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 除按日誌記錄之外,還配置了日誌文件不能超過2M,若超過2M,日誌文件會以索引0開始, 命名日誌文件,例如log-error-2013-12-21.0.log --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>2MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 追加方式記錄日誌 --> <append>true</append> <!-- 日誌文件的格式 --> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>11===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern> <charset>utf-8</charset> </encoder> <!-- 此日誌文件只記錄info級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!--111111111111111111111111111111111111111111111111111111111111111111111111111--> <!-- 日誌記錄器,日期滾動記錄 警告--> <appender name="FILEWARN" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌文件的路徑及文件名 --> <file>${LOG_PATH}/${APPDIR}/log_warn.log</file> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 歸檔的日誌文件的路徑,例如今天是2013-12-21日誌,當前寫的日誌文件路徑爲file節點指定,可以將此文件與file指定文件路徑設置爲不同路徑,從而將當前日誌文件或歸檔日誌文件置不同的目錄。 而2013-12-21的日誌文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 除按日誌記錄之外,還配置了日誌文件不能超過2M,若超過2M,日誌文件會以索引0開始, 命名日誌文件,例如log-error-2013-12-21.0.log --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>2MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 追加方式記錄日誌 --> <append>true</append> <!-- 日誌文件的格式 --> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>22===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern> <charset>utf-8</charset> </encoder> <!-- 此日誌文件只記錄info級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!--222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222--> <!-- 日誌記錄器,日期滾動記錄 信息--> <appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌文件的路徑及文件名 --> <file>${LOG_PATH}/${APPDIR}/log_info.log</file> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 歸檔的日誌文件的路徑,例如今天是2013-12-21日誌,當前寫的日誌文件路徑爲file節點指定,可以將此文件與file指定文件路徑設置爲不同路徑,從而將當前日誌文件或歸檔日誌文件置不同的目錄。 而2013-12-21的日誌文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 除按日誌記錄之外,還配置了日誌文件不能超過2M,若超過2M,日誌文件會以索引0開始, 命名日誌文件,例如log-error-2013-12-21.0.log --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>2MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- 追加方式記錄日誌 --> <append>true</append> <!-- 日誌文件的格式 --> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>33==%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern> <charset>utf-8</charset> </encoder> <!-- 此日誌文件只記錄info級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>debug</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!--33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333--> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--encoder 默認配置爲PatternLayoutEncoder--> <encoder> <pattern>44==%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern> <charset>utf-8</charset> </encoder> <!--此日誌appender是爲開發使用,只配置最底級別,控制檯輸出的日誌級別是大於或等於此級別的日誌信息--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>info</level> </filter> </appender> <!--44444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444--> <!--就是這個監控了mybatis日誌輸出,配合上面的“dao”--> <logger name="dao" level="debug" additivity="false"> <appender-ref ref="FILEINFO"/> </logger> <logger name="dao" level="debug" additivity="false"> <appender-ref ref="FILEWARN"/> </logger> <logger name="dao" level="debug" additivity="false"> <appender-ref ref="FILEERROR"/> </logger> <!--這個是管理mybatis映射類的加載的跟事物管理的--> <logger name="org.mybatis" level="debug" additivity="false"> <appender-ref ref="FILEINFO"/> <appender-ref ref="STDOUT"/> <!--<appender-ref ref="FILEERROR"/>--> <!--<appender-ref ref="FILEWARN"/>--> </logger> <root level="info"> <appender-ref ref="FILEERROR"/> <appender-ref ref="FILEWARN"/> <appender-ref ref="FILEINFO"/> <!-- 生產環境將請stdout去掉 --> <appender-ref ref="STDOUT"/> </root> </configuration>
裏面有些東西是調試的時候弄的,估計你們可能也需要,這個設置李的level真的是煩,那個appender有,logger有, root有很難懂它們之間的規律,起什麼作用,互相有什麼影響,我是用死辦法,一個一個測試,來讓它輸出我想要的日誌文件,都是淚,你知道你剛以爲了解它們的規律,結果測試的時候立馬就是另外一個結果,無語,反正能獲得自己想要的日誌文件就好.那個
<!--就是這個監控了mybatis日誌輸出,配合上面的“dao”--> <logger name="dao" level="debug" additivity="false"> <appender-ref ref="FILEINFO"/> </logger> <logger name="dao" level="debug" additivity="false"> <appender-ref ref="FILEWARN"/> </logger> <logger name="dao" level="debug" additivity="false"> <appender-ref ref="FILEERROR"/> </logger>
這個是輸出sql的,只要調用了dao裏的sql,就會輸出,下面這個是配合上面使用的,在mybatis-config.xml的配置SLF4J的下面添加
<setting name="logImpl" value="SLF4J"/>
<setting name="logPrefix" value="dao."/>
還有就是運行時error是logback.xml是捕獲不到的,需要寫一個幫助類GlobalExceptionHandler
import com.alibaba.fastjson.JSONObject; import org.codehaus.plexus.util.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice public class GlobalExceptionHandler { private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); @ResponseBody @ExceptionHandler(Exception.class) public Object handleException(Exception e) { logger.error(ExceptionUtils.getFullStackTrace(e)); // 記錄錯誤信息 String msg = e.getMessage(); if (msg == null || msg.equals("")) { msg = "服務器出錯"; } JSONObject jsonObject = new JSONObject(); jsonObject.put("message", msg); return jsonObject; } }
這是捕獲運行時error的,還可配置將control的輸入參數,輸出結果,保存到info裏,就是可以記錄一次完整的請求, 就是將數據保存到logger.info(數據) 就行,這樣調用的logger.info(數據)
所以我保存的日誌是sql (主要是看sql參數跟sql語句),error (錯誤),warn(警告) ,control的輸入參數跟輸出結果 這4個
所以效果是這樣的
因爲沒有超過10M的文件,所以就沒有那個同名的_0 _1 _2 _3這種格式的文件
所以這個logback日誌管理的效果是完成了,以後遇到新東西,我都會記錄下來.