logback介紹和配置詳解

logback是java的日志開源組件奔穿,是log4j創(chuàng)始人寫的,性能比log4j要好蔬墩,目前主要分為3個模塊

  1. logback-core:核心代碼模塊
  2. logback-classic:log4j的一個改良版本,同時實現(xiàn)了slf4j的接口,這樣你如果之后要切換其他日志組件也是一件很容易的事
  3. logback-access:訪問模塊與Servlet容器集成提供通過Http來訪問日志的功能

一麻献、logback的使用

依賴(這個依賴直接包含了 logback-core 以及 slf4j-api的依賴)

<dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.11</version>
</dependency>

然后就可以直接在代碼中使用slf4j的接口獲取Logger輸出日志了。(配置在下面的章節(jié)介紹)

//這是slf4j的接口齿桃,由于我們引入了logback-classic依賴,所以底層實現(xiàn)是logback
private static final Logger LOGGER = LoggerFactory.getLogger(Test.class);

public static void main(String[] args) throws InterruptedException {
    LOGGER.info("hello world");
}

二、logback的配置

logback配置獲取順序

logback在啟動的時候,會按照下面的順序加載配置文件

  1. 如果java程序啟動時指定了logback.configurationFile屬性,就用該屬性指定的配置文件炸茧。如java -Dlogback.configurationFile=/path/to/mylogback.xml Test 改备,這樣執(zhí)行Test類的時候就會加載/path/to/mylogback.xml配置
  2. 在classpath中查找 logback.groovy 文件
  3. 在classpath中查找 logback-test.xml 文件
  4. 在classpath中查找 logback.xml 文件
  5. 如果是 jdk6+,那么會調(diào)用ServiceLoader 查找 com.qos.logback.classic.spi.Configurator接口的第一個實現(xiàn)類
  6. 自動使用ch.qos.logback.classic.BasicConfigurator,在控制臺輸出日志
    上面的順序表示優(yōu)先級润脸,使用java -D配置的優(yōu)先級最高倒堕,只要獲取到配置后就不會再執(zhí)行下面的流程铭段。相關代碼可以看ContextInitializer#autoConfig()方法。

關于SLF4j的日志輸出級別

在slf4j中,從小到大的日志級別依舊是trace、debug桐早、info祷膳、warn万哪、error。

logback.xml 配置樣例1

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="1 seconds">

    <contextName>logback</contextName>
    <!--定義參數(shù),后面可以通過${app.name}使用-->
    <property name="app.name" value="logback_test"/>
    <!--ConsoleAppender 用于在屏幕上輸出日志-->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--定義了一個過濾器,在LEVEL之下的日志輸出不會被打印出來-->
        <!--這里定義了DEBUG着撩,也就是控制臺不會輸出比ERROR級別小的日志-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <!-- encoder 默認配置為PatternLayoutEncoder -->
        <!--定義控制臺輸出格式-->
        <encoder>
            <pattern>%d [%thread] %-5level %logger{36} [%file : %line] - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--定義日志輸出的路徑-->
        <!--這里的scheduler.manager.server.home 沒有在上面的配置中設定,所以會使用java啟動時配置的值-->
        <!--比如通過 java -Dscheduler.manager.server.home=/path/to XXXX 配置該屬性-->
        <file>${scheduler.manager.server.home}/logs/${app.name}.log</file>
        <!--定義日志滾動的策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--定義文件滾動時的文件名的格式-->
            <fileNamePattern>${scheduler.manager.server.home}/logs/${app.name}.%d{yyyy-MM-dd.HH}.log.gz
            </fileNamePattern>
            <!--60天的時間周期,日志量最大20GB-->
            <maxHistory>60</maxHistory>
            <!-- 該屬性在 1.1.6版本后 才開始支持-->
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <!--每個日志文件最大100MB-->
            <maxFileSize>100MB</maxFileSize>
        </triggeringPolicy>
        <!--定義輸出格式-->
        <encoder>
            <pattern>%d [%thread] %-5level %logger{36} [%file : %line] - %msg%n</pattern>
        </encoder>
    </appender>

    <!--root是默認的logger 這里設定輸出級別是debug-->
    <root level="trace">
        <!--定義了兩個appender浅役,日志會通過往這兩個appender里面寫-->
        <appender-ref ref="stdout"/>
        <appender-ref ref="file"/>
    </root>

    <!--對于類路徑以 com.example.logback 開頭的Logger,輸出級別設置為warn-->
    <!--這個logger沒有指定appender乳幸,它會繼承root節(jié)點中定義的那些appender-->
    <logger name="com.example.logback" level="warn"/>

    <!--通過 LoggerFactory.getLogger("mytest") 可以獲取到這個logger-->
    <!--由于這個logger自動繼承了root的appender,root中已經(jīng)有stdout的appender了背亥,自己這邊又引入了stdout的appender-->
    <!--如果沒有設置 additivity="false" ,就會導致一條日志在控制臺輸出兩次的情況-->
    <!--additivity表示要不要使用rootLogger配置的appender進行輸出-->
    <logger name="mytest" level="info" additivity="false">
        <appender-ref ref="stdout"/>
    </logger>
    
    <!--由于設置了 additivity="false" 闽颇,所以輸出時不會使用rootLogger的appender-->
    <!--但是這個logger本身又沒有配置appender,所以使用這個logger輸出日志的話就不會輸出到任何地方-->
    <logger name="mytest2" level="info" additivity="false"/>
</configuration>

logback.xml 配置樣例2

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false"> <!--
    %p:輸出優(yōu)先級,即DEBUG,INFO,WARN,ERROR,FATAL    
    %r:輸出自應用啟動到輸出該日志訊息所耗費的毫秒數(shù)    
    %t:輸出產(chǎn)生該日志事件的線程名    
    %f:輸出日志訊息所屬的類別的類別名    
    %c:輸出日志訊息所屬的類的全名    
    %d:輸出日志時間點的日期或時間,指定格式的方式: 
    %d{yyyy-MM-dd HH:mm:ss}    
    %l:輸出日志事件的發(fā)生位置奠涌,即輸出日志訊息的語句在他所在類別的第幾行茴丰。    
    %m:輸出代碼中指定的訊息峦椰,如log(message)中的message    
    %n:輸出一個換行符號-->
    <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度 %msg:日志消息,%logger{50}包名縮寫忿族,%n是換行符 -->
    <property name="log_pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"/>
    <!--定義日志文件的存儲地址 勿在 LogBack 的配置中使用相對路徑-->
    <!-- 日志存儲路徑 -->
    <springProperty
            scope="context"
            name="defaultLogDir"
            source="qy.log.history.logDir"
    />

    <!-- 日志備份保留時長 -->
    <springProperty
            scope="context"
            name="logMaxHistory"
            source="qy.log.history.maxHistory"
    />

    <!-- 日志大小 -->
    <springProperty
            scope="context"
            name="logMaxSize"
            source="qy.log.history.logMaxSize"
    />
    <property name="logMaxSize" value="200MB"/>
    <!--<!–控制臺日志隆豹, 控制臺輸出 –>-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log_pattern}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>


    <!--文件日志献雅, 按照每天生成日志文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日志文件的路徑及文件名 -->
        <!--<file>${defaultLogDir:-/qy/qy-doctorservice/logs}/log/docser-main.log</file>-->
        <!--TimeBasedRollingPolicy 基于時間來定義輪轉(zhuǎn)策略 -->
        <!--SizeAndTimeBasedRollingPolicy 基于大小以及時間的輪轉(zhuǎn)策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件輸出的路徑和文件名-->
            <!--該屬性定義了輪轉(zhuǎn)時的屬性名。它的值應該由文件名加上一個 %d 的占位符。%d 應該包含 java.text.SimpleDateFormat 中規(guī)定的日期格式嫩痰。
            如果省略掉這個日期格式,那么就默認為 yyyy-MM-dd榄笙。輪轉(zhuǎn)周期是通過 fileNamePattern 推斷出來的巨朦。
            注意事項:
            1.如果FileNamePattern中指定多個 %d,只能報留一個%d作為主要的堕扶,用于推斷輪轉(zhuǎn)周期睛挚。其它的 %d 占位符必須通過 'aux' 標記為輔助的。
            2.MaxHistory 用來控制最多保留多少數(shù)量的歸檔文件匠抗,將會異步刪除舊的文件印机。
                         保留日志的量 = 輪轉(zhuǎn)周期 * MaxHistory
            3.FileNamePattern中除了 %d 之外還有 %i。這兩個占位符都是強制要求的聂沙。在當前時間還沒有到達周期輪轉(zhuǎn)之前削樊,日志文件達到了 maxFileSize 指定的大小育叁,
              會進行歸檔谴蔑,遞增索引從 0 開始钦睡。
            -->
            <!--輪詢周期:天-->
            <!--<FileNamePattern>${defaultLogDir:-/qy/qy-doctorservice/logs}/log/%d{yyyy-MM-dd, aux}/credit.%d.%i.log</FileNamePattern>-->
            <!-- 每天輪轉(zhuǎn)(晚上零點)秧秉,自動將歸檔文件壓縮成 GZIP 格式荧嵌,減少日志占用空間-->
            <FileNamePattern>${defaultLogDir:-/qy/qy-doctorservice/logs}/log/%d{yyyy-MM-dd, aux}/credit.%d.%i.zip</FileNamePattern>
            <!--日志文件保留輪詢周期個數(shù)-->
            <MaxHistory>${logMaxHistory:-15}</MaxHistory>
            <!--單個日志文件最大的大小-->
            <MaxFileSize>${logMaxSize:-100MB}</MaxFileSize>
            <!--這個可選屬性用來控制所有歸檔文件總的大小逻族。當達到這個大小后,舊的歸檔文件將會被異步的刪除。使用這個屬性時還需要設置 maxHistory 屬性搏嗡。
            而且窿春,maxHistory 將會被作為第一條件,該屬性作為第二條件采盒。-->
            <!--歸檔文件總的大小-->
            <totalSizeCap>1GB</totalSizeCap>
            <!--cleanHistoryOnStart=true時在 appender 啟動的時候,歸檔文件將會被刪除磅氨。默認的值為 false-->
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <!--<append>:如果是 true尺栖,日志被追加到文件結(jié)尾,如果是 false烦租,清空現(xiàn)存文件延赌,默認是true。-->
        <append>false</append>
        <encoder>
            <pattern>${log_pattern}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>
    <!-- 日志輸出級別 -->
    <root level="INFO">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE"/>
    </root>
</configuration>

配置詳解

configuration節(jié)點相關屬性

屬性名稱 默認值 介紹
debug false 要不要打印 logback內(nèi)部日志信息叉橱,true則表示要打印挫以。
scan true 配置發(fā)送改變時,要不要重新加載
scanPeriod 1 seconds 檢測配置發(fā)生變化的時間間隔窃祝。如果沒給出時間單位掐松,默認時間單位是毫秒

configuration子節(jié)點介紹

1. contextName節(jié)點

設置日志上下文名稱掷倔,后面輸出格式中可以通過定義 %contextName 來打印日志上下文名稱

2.property節(jié)點

用來設置相關變量,通過key-value的方式配置耙饰,然后在后面的配置文件中通過 ${key}來訪問

3.appender 節(jié)點

日志輸出組件缠犀,主要負責日志的輸出以及格式化日志乞旦。常用的屬性有name和class

屬性名稱 默認值 介紹
name 無默認值 appender組件的名稱愈涩,后面給logger指定appender使用
class 無默認值 appender的具體實現(xiàn)類撒顿。常用的有 ConsoleAppender慢显、FileAppender持际、RollingFileAppender

3.1 ConsoleAppender:向控制臺輸出日志內(nèi)容的組件突想,只要定義好encoder節(jié)點就可以使用殴蹄。

3.2 FileAppender:向文件輸出日志內(nèi)容的組件,用法也很簡單猾担,不過由于沒有日志滾動策略袭灯,一般很少使用

FileAppenderOutputStreamAppender 的子類,將日志事件輸出到文件中绑嘹。通過 file 來指定目標文件稽荧。如果該文件存在,根據(jù) append 的值工腋,要么將日志追加到文件中姨丈,要么該文件被截斷畅卓。

3.3 RollingFileAppender:向文件輸出日志內(nèi)容的組件,同時可以配置日志文件滾動策略蟋恬,在日志達到一定條件后生成一個新的日志文件翁潘。

appender節(jié)點中有一個子節(jié)點filter,配置具體的過濾器歼争,比如上面的例子配置了一個內(nèi)置的過濾器ThresholdFilter拜马,然后設置了level的值為DEBUG。這樣用這個appender輸出日志的時候都會經(jīng)過這個過濾器沐绒,日志級別低于DEBUG的都不會輸出來俩莽。
RollingFileAppender 的屬性如下所示:

屬性名 類型 描述
file String 參見 FileAppender
append boolean 參見 FileAppender
encoder Encoder 參見 OutputStreamAppender
rollingPolicy RollingPolicy 當輪轉(zhuǎn)發(fā)生時,指定 RollingFileAppender的行為洒沦。下面將會詳細說明
triggeringPolicy TriggeringPolicy 告訴 RollingFileAppender 什么時候發(fā)生輪轉(zhuǎn)行為豹绪。下面將會詳細說明
prudent boolean FixedWindowRollingPolicy不支持該屬性。
RollingFileAppender 在使用嚴格模式時要與 TimeBasedRollingPolicy結(jié)合使用申眼,但是有兩個限制:
1. 在嚴格模式下,也不支持也不允許文件壓縮(我們不能讓一個 JVM 在寫入文件時蝉衣,另一個 JVM 在壓縮該文件)
2. 不能對 FileAppenderfile 屬性進行設置括尸。實際上,大多數(shù)的操作系統(tǒng)不允許在有進程操作文件的情況下對文件改名病毡。
其它的參考 FileAppender

RollingFileAppender的兩種策略:
RollingPolicy 負責輪轉(zhuǎn)的方式為:移動文件以及對文件改名濒翻。

1.SizeAndTimeBasedRollingPolicy基于大小以及時間的輪轉(zhuǎn)策略。

有時你希望按時輪轉(zhuǎn)啦膜,但同時又想限制每個日志文件的大小有送。特別是如果后期處理工具需要對日志進行大小限制。為了滿足這個需求僧家,logback 配備了 SizeAndTimeBasedRollingPolicy雀摘。

注意,TimeBasedRollingPolicy 可以限制歸檔文件總的大小八拱。所以如果你想要這個限制阵赠,你可以通過設置 totalSizeCap 來達到這個目的。

2.TimeBasedRollingPolicy 是最常用的輪轉(zhuǎn)策略清蚀,它是基于時間來定義輪轉(zhuǎn)策略。
TimeBasedRollingPolicy 是最常用的輪轉(zhuǎn)策略爹谭。它是基于時間來定義輪轉(zhuǎn)策略枷邪。例如按天或者按月。TimeBasedRollingPolicy 既負責輪轉(zhuǎn)的行為诺凡,也負責觸發(fā)輪轉(zhuǎn)东揣。實際上药薯,TimeBasedRollingPolicy 同時實現(xiàn)了 RollingPolicyTriggeringPolicy 接口。
TimeBasedRollingPolicy 的配置需要一個強制的屬性 fileNamePattern 以及其它的可選屬性救斑。

例如按天或者按月童本。TimeBasedRollingPolicy 既負責輪轉(zhuǎn)的行為,也負責觸發(fā)輪轉(zhuǎn)脸候。實際上穷娱,TimeBasedRollingPolicy 同時實現(xiàn)了 RollingPolicyTriggeringPolicy 接口。

屬性名 類型 描述
fileNamePattern String 該屬性定義了輪轉(zhuǎn)時的屬性名运沦。它的值應該由文件名加上一個 %d 的占位符泵额。%d 應該包含 java.text.SimpleDateFormat 中規(guī)定的日期格式。如果省略掉這個日期格式携添,那么就默認為 yyyy-MM-dd嫁盲。輪轉(zhuǎn)周期是通過 fileNamePattern 推斷出來的。

注意:可以選擇對 RollingFileAppenderTimeBasedRollingPolicy的父類)中的 file 屬性進行設置烈掠,也可以忽略羞秤。通過設置 FileAppenderfile 屬性,你可以將當前活動日志的路徑與歸檔日志的路徑分隔開來左敌。當前日志永遠會是通過 file 指定的文件瘾蛋。它的名字不會隨著時間的推移而發(fā)生變化。但是矫限,如果你選擇忽略 file 屬性哺哼,當前活動日志在每個周期內(nèi)將會根據(jù) fileNamePattern 的值變化。稍后的例子將會說明這一點叼风。
%d{} 中的日期格式將會遵循 java.text.SimpleDateFormat 中的約定取董。斜桿 '/' 或者反斜杠 '' 都會被解析成目錄分隔符。

指定多個 %d

可以指定多個 %d无宿,但是只能有一個是主要的茵汰,用于推斷輪轉(zhuǎn)周期。其它的 %d 占位符必須通過 'aux' 標記為輔助的懈贺。見下面的示例:
多個 %d 占位符允許你在文件夾中去管理歸檔文件经窖,這個跟輪轉(zhuǎn)周期不同。如下所示:通過年月來管理日志文件夾梭灿,但是輪轉(zhuǎn)周期是在每天晚上零點画侣。
/var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log

TimeZone

在某些情況下,你可能想要根據(jù)時區(qū)而不是主機的時鐘來輪轉(zhuǎn)日志堡妒。你可以通過如下方式來指定一個時區(qū)配乱,例如:
aFloder/test.%d{yyyy-MM-dd-HH, UTC}.log
如果指定的 timezone 不能被識別或者拼寫錯誤,將會根據(jù) TimeZone.getTimeZone(String) 方法指定為 GMT。
maxHistory int 這個可選的屬性用來控制最多保留多少數(shù)量的歸檔文件搬泥,將會異步刪除舊的文件桑寨。比如,你指定按月輪轉(zhuǎn)忿檩,指定 maxHistory = 6尉尾,那么 6 個月內(nèi)的歸檔文件將會保留在文件夾內(nèi),大于 6 個月的將會被刪除燥透。注意:當舊的歸檔文件被移除時沙咏,當初用來保存這些日志歸檔文件的文件夾也會在適當?shù)臅r候被移除。
totalSizeCap int 這個可選屬性用來控制所有歸檔文件總的大小班套。當達到這個大小后肢藐,舊的歸檔文件將會被異步的刪除。使用這個屬性時還需要設置 maxHistory 屬性吱韭。而且吆豹,maxHistory 將會被作為第一條件,該屬性作為第二條件理盆。
cleanHistoryOnStart boolean 如果設置為 true痘煤,那么在 appender 啟動的時候,歸檔文件將會被刪除熏挎。默認的值為 false速勇。
歸檔文件的刪除通常在輪轉(zhuǎn)期間執(zhí)行。但是坎拐,有些應用的存活時間可能等不到輪轉(zhuǎn)觸發(fā)。對于這種短期應用养匈,可以通過設置該屬性為 true哼勇,在 appender 啟動的時候執(zhí)行刪除操作。

3.4 SMTPAppender
SMTPAppender收集日志事件到一個或多個固定大小的緩沖區(qū)呕乎,當用戶指定的事件發(fā)生時积担,將從緩沖區(qū)中取出適當?shù)膬?nèi)容進行發(fā)送。SMTP 郵件是異步發(fā)送的猬仁。默認情況下帝璧,當日志的級別為 ERROR 時,郵件發(fā)送將會被觸發(fā)湿刽。而且默認的情況下的烁,所有事件都使用同一個緩沖區(qū)。
SMTPAppender 的屬性如下表所示:

屬性名 類型 描述
smtpHost String SMTP 服務器的主機名诈闺。強制性的渴庆。
smtpPort int SMPT 服務監(jiān)聽的端口。默認為 25.
to String 接收者的郵件地址。觸發(fā)事件發(fā)送給接收者襟雷。多個收件人可以使用逗號(,)分隔刃滓,或者使用多個 <to> 元素來指定。
from String SMTPAppender 使用的發(fā)件人耸弄,格式遵循郵件通用格式咧虎,如果你想要包含發(fā)送者的名字,使用這種格式 " Adam Smith <smith@moral.org>"计呈,那么郵件將會顯示收件人為 " Adam Smith <smith@moral.org>"
subject String 郵件的主題砰诵。它可以是通過 PatternLayout 轉(zhuǎn)換后的有效值。關于 Layout 將在接下來的章節(jié)討論震叮。<br />郵件應該有一個主題行胧砰,對應觸發(fā)的郵件信息。<br />假設 subject 的值為:"Log: %Logger - %msg"苇瓣,觸發(fā)事件的 logger 名為 "com.foo.Bar"尉间,并且日志信息為 "Hello world"。那么發(fā)出的郵件信息將會有一個名為 "Log: com.foo.Bar - Hello World" 的主題行击罪。<br />默認情況下哲嘲,這個屬性的值為 "%logger{20} - %m"
discriminator Discriminator 在 Discriminator 的幫助下,SMTPAppender 根據(jù) discriminator 返回的值可以將不同日志事件分散到不同的緩沖區(qū)中媳禁。默認的 discriminator 將返回同一個值眠副,所以所有的事件都使用同一個緩沖區(qū)。
evaluator IEvaluator 通過創(chuàng)建一個新的 <EventEvaluator/> 元素來聲明此選項竣稽。通過 class 屬性指定 class 的名字表示用戶希望通過哪個類來滿足 SMTPAppenderEvaluator 的需要囱怕。<br />如果沒有指定此選項,當觸發(fā)一個大于等于 ERROR 級別的事件時毫别,SMTPAppender 將會被分配一個 OnErrorEvaluator 的實例娃弓。<br />logback 配備了幾個其它的 evaluator,分別叫 OnMarkerEvaluator (將在下面討論)岛宦,一個相對強大的 evaluator 叫 JaninoEventEvaluator(在其它章節(jié)討論) 以及最近版本才有的一個更加強大的 evaluator 叫 GEventEvaluator台丛。
cyclicBufferTracker CyclicBufferTracker 從名字可以看出,是一個 CyclicBufferTracker 的實例追蹤循環(huán)緩沖區(qū)砾肺。它基于 discriminator 返回的 key (見上)挽霉。<br />如果你不想指定一個 cyclicBufferTracker,那么將會自動創(chuàng)建一個 CyclicBufferTracker 的實例变汪。默認的侠坎,這個實例用來保留事件的循環(huán)緩沖區(qū)的大小為 256。你需要改變 bufferSize 選項的大幸唏谩(見下面)
username String 默認為 null
password String 默認為 null
STARTTLS boolean 如果為 true硅蹦,那么 appender 將會發(fā)送 STARTTLS 命令(如果服務器支持)將連接變成 SSL 連接荣德。注意,連接初始的時候是為加密的童芹。默認為 false涮瞻。
SSL boolean 如果為 true,將通過 SSL 連接服務器假褪。默認為 false署咽。
charsetEncoding String 郵件信息將會通過 charset 進行編碼。默認編碼為 "UTF-8"
localhost String 一旦 SMTP 客戶端的主機名沒有配置正確生音,例如客戶端的 hostname 不是全限定的宁否,那么服務端會拒絕客戶端發(fā)送的 HELO/EHLO 命令。為了解決這個問題缀遍,你可以將 localhost 的值設置為客戶端主機的全限定名慕匠。詳情見 com.sun.mail.smtp 包文檔中的 "mail.smtp.localhost" 屬性。(這個網(wǎng)站已經(jīng)關閉了...)
asynchronousSending boolean 決定郵件傳輸是否是異步進行域醇。默認為 'true'台谊。但是,在某些特定的情況下譬挚,異步發(fā)送不怎么合適锅铅。例如,當發(fā)生一個嚴重錯誤時减宣,你的應用使用 SMTPAppender 去發(fā)送一個警告盐须,然后退出。但是相關線程可能沒有時間去發(fā)送警告郵件漆腌。在這種情況下贼邓,你可以設置該屬性的值為 'false'。
includeCallerData boolean 默認為 false闷尿。如果 asynchronousSending 的值為 true立帖,并且你希望在日志中看到調(diào)用者的信息,你可以設置該屬性的值為 true
sessionViaJNDI boolean SMTPAppender 基于 javax.mail.Session 來發(fā)送郵件信息悠砚。默認情況下,該屬性的值為 false堂飞,所以需要用戶指定相關屬性通過 SMTPAppender 來構(gòu)建 javax.mail.Session 實例灌旧。如果設置為 true,javax.mail.Session 實例將會通過 JNDI 來獲取绰筛。參見 jndiLocation 屬性枢泰。<br />通過 JNDI 獲取 Session 實例可以減少需要配置的數(shù)量,使你的應用減少重復(dryer)的工作铝噩。更多關于在 Tomcat 配置 JNDI 的信息請參考 JNDI Resources How-to衡蚂。<br />注意:通過 JNDI 獲取 Session 的時候請移除 web 應用下 WEB-INF/lib 文件夾下的 mail.jaractivation.jar
jndiLocation String JNDI 中放置 javax.mail.Session 的地方。默認為:" java:comp/env/mail/Session "

SMTPAppender 僅僅只在它的循環(huán)緩存區(qū)中保留最后 256 個日志事件毛甲,當緩存區(qū)快要滿的時候丟掉舊的日志事件年叮。因此,通過 SMTPAppender 發(fā)送任何郵件包含的日志事件都不會超過 256 個玻募。這在保留內(nèi)存需求的限制只损,還提供了數(shù)量可觀的應用上下文。

SMTPAppender 基于 JavaMail API七咧。在 JavaMail 1.4 版本做過測試跃惫。JavaMail 需要 JavaBeans Activation Framework 包。你可以去它們各自的網(wǎng)站下載 JavaMail APIJavaBeans Activation Framework艾栋。在運行下面的示例之前先確保將這兩個 jar 包放在 classpath 下爆存。

chapters.appenders.mail.EMail應用會生成多個日志信息,隨后再生成一個錯誤日志信息蝗砾。它接收兩個參數(shù)先较,第一參數(shù)是整形衍锚,表示需要生成多少個日志事件儿咱。第二個參數(shù)表示 logback 的配置文件。Email 最后生成一個錯誤日志渐裂,將會觸發(fā)發(fā)送郵件信息矮锈。

下面是一個 Email 應用的簡單配置信息:

4. logger以及root節(jié)點

root節(jié)點和logger節(jié)點其實都是表示Logger組件霉翔。個人覺的可以把他們之間的關系可以理解為父子關系,root是最頂層的logger苞笨,正常情況getLogger("name/class")沒有找到對應logger的情況下债朵,都是使用root節(jié)點配置的logger。

如果配置了logger瀑凝,并且通過getLogger("name/class")獲取到這個logger序芦,輸出日志的時候,就會使用這個logger配置的appender輸出粤咪,同時還會使用rootLogger配置的appender谚中。我們可以使用logger節(jié)點的additivity="false"屬性來屏蔽rootLogger的appender。這樣就可以不使用rootLogger的appender輸出日志了宪塔。

關于logger的獲取,一般logger是配置name的囊拜。我們再代碼中經(jīng)常通過指定的CLass來獲取Logger某筐,比如這樣LoggerFactory.getLogger(Test.class);,其實這個最后也是轉(zhuǎn)成對應的包名+類名的字符串com.kongtrio.Test.class。假設有一個logger配置的那么是com.kongtrio冠跷,那么通過LoggerFactory.getLogger(Test.class)獲取到的logger就是這個logger南誊。

也就是說身诺,name可以配置包名,也可以配置自定義名稱抄囚。

上面說的logger和root節(jié)點的父子關系只是為了方便理解霉赡,具體的底層實現(xiàn)本人并沒有看,他們之間真正的關系讀者有興趣的話可以去看logback的源碼

三怠苔、SpringBoot中l(wèi)ogback日志配置文件加載順序

springboot加載日志配置文件有兩種同廉,一種是加載logback自身的配置文件,另一種是加載具有spring特性的logback配置文件:

    // @see org.springframework.boot.logging.AbstractLoggingSystem
    private void initializeWithConventions(LoggingInitializationContext initializationContext, LogFile logFile) {
        String config = getSelfInitializationConfig();
        if (config != null && logFile == null) {
            // self initialization has occurred, reinitialize in case of property changes
            reinitialize(initializationContext);
            return;
        }
        if (config == null) {
            config = getSpringInitializationConfig();
        }
        if (config != null) {
            loadConfiguration(initializationContext, config, logFile);
            return;
        }
        loadDefaults(initializationContext, logFile);
    }

其中config 指logback自身的配置文件柑司,logFile 指logging.file.name或者logging.file.path指定的文件

// @See org.springframework.boot.logging.LogFile
public static LogFile get(PropertyResolver propertyResolver) {
        // public static final String FILE_NAME_PROPERTY = "logging.file.name"
        String file = propertyResolver.getProperty(FILE_NAME_PROPERTY);
        // public static final String FILE_PATH_PROPERTY = "logging.file.path"
        String path = propertyResolver.getProperty(FILE_PATH_PROPERTY);
        if (StringUtils.hasLength(file) || StringUtils.hasLength(path)) {
            return new LogFile(file, path);
        }
        return null;
    }

1.加載logback自身的配置文件按(二迫肖、logback的配置--logback配置獲取順序)順序加載;
2.如果上述配置文件都不存在攒驰,則加載springboot自身具有spring特性的logback配置文件蟆湖,加載順序和logback自身配置文件一致。只是在每種配置文件的末尾加上“-spring”玻粪。

Spring Boot官方推薦優(yōu)先使用帶有-spring的文件名作為你的日志配置(如使用logback-spring.xml隅津,而不是logback.xml),因為logback.xml加載早于application.properties劲室,所以如果你在logback.xml使用了變量時伦仍,而恰好這個變量是寫在application.properties時,那么就會獲取不到很洋,只要改成logback-spring.xml就可以解決充蓝。

  • logging.file.name:設置具體輸出的日志名稱,可以是絕對路徑或者基于當前運行目錄的相對路徑喉磁,例如:logging.file.name=app.log谓苟、logging.file.name=/var/log/app.log
  • logging.file.path:設置輸出的日志被寫入到的目錄,默認文件名為 spring.log协怒,例如:logging.file.path=/var/log/
    如果你兩個都同時設置涝焙,則以 logging.file.name 為準,建議直接使用 logging.file.name孕暇。

具有spring特性的logback的配置文件--logback-spring.xml

  • springProfile
    <springProfile>標簽允許我們更加靈活配置文件仑撞,可選地包含或排除配置部分。使用該name屬性指定哪個配置文件接受配置妖滔∨刹荩可以使用逗號分隔列表指定多個配置文件。
<springProfile name="dev">
    <!-- 開發(fā)環(huán)境時激活 -->
</springProfile>

<springProfile name="dev,test">
    <!-- 開發(fā)铛楣,測試的時候激活-->
</springProfile>

<springProfile name="!prod">
    <!-- 當 "生產(chǎn)" 環(huán)境時,該配置不激活-->
</springProfile>

例子

<!-- 開發(fā)環(huán)境日志級別為DEBUG -->
<springProfile name="dev">
    <root level="DEBUG">
        <appender-ref ref="FILE"/>
        <appender-ref ref="STDOUT"/>
    </root>
</springProfile> 

<!-- 測試環(huán)境日志級別為INFO -->
<springProfile name="test">
    <root level="INFO">
        <appender-ref ref="FILE"/>
        <appender-ref ref="STDOUT"/>
    </root>
</springProfile>
  • springProperty
    <springProperty>標簽允許我們從Spring中顯示屬性艺普,Environment 以便在Logback中使用簸州。如果你想將 application.properties在回讀配置中訪問文件中的值鉴竭,這將非常有用。
屬性名字 描述
scope 作用域(設置屬性的范圍岸浑,例local(默認)搏存、context、system)
name 變量名字
source 需要引用的yml文件中配置名稱
  1. local--從配置文件中定義其屬性的位置到該配置文件的解釋/執(zhí)行結(jié)束為止矢洲,都存在具有本地范圍的屬性璧眠。因此,每次解析和執(zhí)行配置文件時读虏,都會重新定義本地作用域中的變量责静。

  2. context--具有上下文范圍的屬性被插入到上下文中,并且持續(xù)時間與上下文一樣長盖桥,直到被清除為止灾螃。一旦定義,上下文范圍內(nèi)的屬性就是上下文的一部分揩徊。這樣腰鬼,它在所有日志記錄事件中都可用,包括那些通過序列化發(fā)送到遠程主機的事件塑荒。

  3. system--具有系統(tǒng)范圍的屬性被插入 JVM 的系統(tǒng)屬性中熄赡,并且持續(xù)時間與 JVM 一樣長,或者直到被清除為止齿税。
    例子

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="app"/>
    <property name="LOG_FILE" value="${LOG_FILE:-${user.home}/logs/${APP_NAME}.log}"/>
    <property name="LOG_ERROR_FILE" value="${LOG_ERROR_FILE:-${user.home}/logs/${APP_NAME}-error.log}"/>
    <!-- 控制臺輸出 -->
    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
    <!-- 日志輸出文件 -->
    <include resource="org/springframework/boot/logging/logback/file-appender.xml"/>
    <!-- 錯誤日志輸出文件 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${FILE_LOG_CHARSET}</charset>
        </encoder>
        <file>${LOG_ERROR_FILE}</file>
        <!-- 只輸出ERROR級別的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_ERROR_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
            <cleanHistoryOnStart>false</cleanHistoryOnStart>
            <maxFileSize>10MB</maxFileSize>
            <totalSizeCap>0</totalSizeCap>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- root級別 INFO-->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="ERROR_FILE"/>
    </root>
</configuration>

參考:26. Logging (spring.io)

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末彼硫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子偎窘,更是在濱河造成了極大的恐慌乌助,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陌知,死亡現(xiàn)場離奇詭異他托,居然都是意外死亡,警方通過查閱死者的電腦和手機仆葡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門赏参,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沿盅,你說我怎么就攤上這事把篓。” “怎么了腰涧?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵韧掩,是天一觀的道長。 經(jīng)常有香客問我窖铡,道長疗锐,這世上最難降的妖魔是什么坊谁? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮滑臊,結(jié)果婚禮上口芍,老公的妹妹穿的比我還像新娘。我一直安慰自己雇卷,他們只是感情好鬓椭,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著关划,像睡著了一般小染。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上祭玉,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天氧映,我揣著相機與錄音,去河邊找鬼脱货。 笑死岛都,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的振峻。 我是一名探鬼主播臼疫,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼扣孟!你這毒婦竟也來了烫堤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凤价,失蹤者是張志新(化名)和其女友劉穎鸽斟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體利诺,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡富蓄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了慢逾。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片立倍。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖侣滩,靈堂內(nèi)的尸體忽然破棺而出口注,到底是詐尸還是另有隱情,我是刑警寧澤君珠,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布寝志,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏澈段。R本人自食惡果不足惜悠菜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望败富。 院中可真熱鬧,春花似錦摩窃、人聲如沸兽叮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鹦聪。三九已至,卻和暖如春蒂秘,著一層夾襖步出監(jiān)牢的瞬間泽本,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工姻僧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留规丽,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓撇贺,卻偏偏與公主長得像赌莺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子松嘶,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容