1. 程式人生 > >ssm框架使用logback管理日誌,滿足每天輸出想儲存的日誌檔案,且檔案大於10M時會建立新的.

ssm框架使用logback管理日誌,滿足每天輸出想儲存的日誌檔案,且檔案大於10M時會建立新的.

    由於專案需要滿足每天輸出想儲存的日誌檔案,且檔案大於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日誌管理的效果是完成了,以後遇到新東西,我都會記錄下來.