spring mvc+logback日志(2)--日志規(guī)則技巧

參考資料

logback 中文手冊

一、基本規(guī)則

使用
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
//logger定義
package org.slf4j; 
public interface Logger { 
  public void trace(String message);
  public void debug(String message);
  public void info(String message); 
  public void warn(String message); 
  public void error(String message); 
}
logger打印規(guī)則

如果一條的日志的打印級別大于 logger 的有效級別,該條日志才可以被打印出來。這條規(guī)則總結如下:
日志的打印級別為 p,Logger 實例的級別為 q,如果 p >= q,則該條日志可以打印出來。
這條規(guī)則是 logbakc 的核心。各級別的排序為:TRACE < DEBUG < INFO < WARN < ERROR。
舉例

        ch.qos.logback.classic.Logger logger = 
                (ch.qos.logback.classic.Logger)LoggerFactory.getLogger("com.foo");
        // 設置 logger 的級別為 INFO
        logger.setLevel(Level.INFO);

        // 這條日志可以打印,因為 WARN >= INFO
        logger.warn("警告信息");
        // 這條日志不會打印,因為 DEBUG < INFO
        logger.debug("調試信息");
appender疊加規(guī)則

如果 root logger 添加了一個 console appender,所有允許輸出的日志至少會在控制臺打印出來。如果再給一個叫做 L 的 logger 添加了一個 file appender,那么 L 以及 L 的子級 logger 都可以在文件和控制臺打印日志??梢酝ㄟ^設置 additivity = false 來改寫默認的設置,這樣 appender 將不再具有疊加性。

提前判定,避免損耗
if(logger.isDebugEnabled()) { 
  logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
更優(yōu)的日志格式化

下面兩行輸出的結果是一樣的,但是一旦禁止日志打印,第二個變量的性能至少比第一個變量好上 30 倍。

logger.debug("The new entry is " + entry + ".");  //不推薦
logger.debug("The new entry is {}", entry);
logger.debug("The new entry is {}, It replaces {}.", entry, oldEntry);//使用兩個參數(shù)的例子
Object[] paramArray = {newVal, below, above};
logger.debug("Value {} was inserted between {} and {}.", paramArray);//使用三個或三個以上的參數(shù)

一、配置相關

自動化配置logback.xml

以下是 logback 的初始化步驟:

  1. logback 會在類路徑下尋找名為 logback-test.xml 的文件。
  2. 如果沒有找到,logback 會繼續(xù)尋找名為 logback.groovy 的文件。
  3. 如果沒有找到,logback 會繼續(xù)尋找名為 logback.xml 的文件。
  4. 如果沒有找到,將會通過 JDK 提供的 ServiceLoader 工具在類路徑下尋找文件 META-INFO/services/ch.qos.logback.classic.spi.Configurator,該文件的內容為實現(xiàn)了 Configurator 接口的實現(xiàn)類的全限定類名。
  5. 如果以上都沒有成功,logback 會通過BasicConfigurator為自己進行配置,并且日志將會全部在控制臺打印出來。

最后一步的目的是為了保證在所有的配置文件都沒有被找到的情況下,提供一個默認的(但是是非常基礎的)配置。

下面的配置等同于通過 BasicConfigurator進行配置

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
在警告或錯誤的情況下自動打印狀態(tài)信息

編碼方式實現(xiàn)

        LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
        StatusPrinter.print(lc);

配置方式實現(xiàn),增加debug="true"

<configuration debug="true"></configuration>

等效配置

<configuration>
    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
    <!-- 剩下的配置跟之前的相同 -->
</configuration>

區(qū)別:
但是,如果配置文件沒有被找到,logback 不會打印它的內部狀態(tài)信息,因為沒有檢測到錯誤。通過編碼方式調用 StatusPrinter.print() 方法會在任何情況下都打印狀態(tài)信息。

當配置文件更改時,自動加載
 <!-- 默認情況下,一分鐘掃描一次配置文件,看是否有更改。通過 <configuration> 標簽上的 scanPeriod 屬性可以指定掃描周期。掃描周期的時間單位可以是毫秒、秒、分鐘或者小時-->
<configuration scan="true" scanPeriod="30 seconds">
</configuration>

當設置了 scan="true",會新建一個 ReconfigureOnChangeTask 任務用于監(jiān)視配置文件是否變化。ReconfigureOnChangeTask 也會自動監(jiān)視外部文件的變化。

查看內部狀態(tài)信息

logback-classic 包含一個名叫 ViewStatusMessagesServlet 的 servlet。這個 servlet 打印當前 LoggerContext 的 StatusManager 的內容,通過 html 進行輸出。
在 WEB-INF/web.xml 中添加如下代碼:

<servlet>
    <servlet-name>ViewStatusMessages</servlet-name>
    <servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>ViewStatusMessages</servlet-name>
    <url-pattern>/lbClassicStatus</url-pattern>
</servlet-mapping>

然后可以通過 http://host/yourWebapp/lbClassicStatus 進行訪問。

配置 <logger> 標簽

【must】 name 屬性
【option】 level 屬性
【option】 additivity 屬性
【0-n】<appender-ref> 元素

配置<root> 元素

【option】 level 屬性
【0-n】<appender-ref> 元素

    <logger name="chapters.configuration" level="INFO" />

    <logger name="chapters.configuration.Foo" level="DEBUG" />

    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
    </root>

與 log4j 不同的是,logbakc-classic 不會關閉或移除任何之前在 logger 上定義好的的 appender。


配置<appender> 元素

【must】 name】、class 屬性
【0-n】<layout>、<filter>、<encoder> 元素

<layout> 元素強制一個 class 屬性去指定一個類的全限定名,用于實例化。與 <appender> 元素一樣,<layout> 元素也可以包含與 layout 實例相關的屬性。如果 layout 的 class 是 PatternLayout,那么 class 屬性可以被隱藏掉(參考:默認類映射),因為這個很常見。.
<encoder 元素強制一個 class 屬性去指定一個類的全限定名,用于實例化。如果 encoder 的 class 是 PatternLayoutEncoder,那么基于默認類映射,class 屬性可以被隱藏。

錯誤示范,會導致重復打印chapters.configuration包下的類容

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="chapters.configuration">
        <appender-ref ref="STDOUT" />
    </logger>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
設置 context 的名字

默認這個 logger context 的名字為 "default"。但是你可以通過 <contextName> 設置其它的名字。

<configuration>
    <contextName>myAppName</contextName>
</configuration>
變量的定義
<configuration>
      <!-- 定義方式一 -->
    <property name="USER_NAME" value="/data/logs" />
     <!-- 定義方式二 -->
    <property file="F:\project\logback-examples\src\main\resources\variables1.properties"/>
     <!-- 定義方式三 -->
   <property resource="resource1.properties" />

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${USER_NAME}/myApp.log</file>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="FILE" />
    </root>    
</configuration>
變量的作用域

屬性的作用域分別為本地(local scope)、上下文(context scope)、系統(tǒng)(system scope)。默認為本地作用域。

在進行變量替換的時候,會先從本地范圍去找,再從上下文去找,再從系統(tǒng)屬性中去找,最后會去系統(tǒng)的環(huán)境變量中去找。

可以通過 <property>、<define>、<insertFromJNDI> 元素的 scope 屬性來設置變量的作用范圍。scope 屬性可能的值為:local,context,system。如果沒有指定,則默認為 local。

<property scope="context" name="nodeId" value="firstNode"/>
變量的默認值

。在 bash shell 中,默認值可以通過 ":-" 來指定。例如:假設變量 aName 沒有被定義,"${aNme:-golden}" 會被解釋成 "golden" 。

<file>${USER_NAME:-jack js}/myApp.log</file>
變量的嵌套
USER_HOME=/data/logs
fileName=myApp.log
destination=${USER_HOME}/${fileName}
系統(tǒng)預定義屬性
<pattern>${HOSTNAME} - %msg%n</pattern>
<pattern>${CONTEXT_NAME} - %msg%n</pattern>
引入文件

通過 <include> 元素可以引入外部的配置文件。

<configuration>
    <include file="src/main/resources/includedConfig.xml" />

    <root level="DEBUG">
        <appender-ref ref="includedConsole" />
    </root>
</configuration>

目標文件必須是由 <included> 元素包裹的。

<included>
    <appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d - %m%n</pattern>
        </encoder>
    </appender>
</included>

如果 logback 沒有通過 include 元素找到指定的配置文件,會在控制臺打印出內部狀態(tài)信息。如果引入的外部配置文件是可選的,可以設置 optional=true。

<include optional="true" ..../>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容