目錄
前言
我們先來簡單瞭解一下Logback,它是log4j的升級版,都是同一個作者。
Logback超輕量級日誌框架,性能是老版log4j的10倍以上,佔用內存更小。
Logback 的架構非常的通用,適用不同的使用場景。Logback 被分成三個不同的模塊:logback-core,logback-classic,logback-access。
logback-core 是其它兩個模塊的基礎。logback-classic 模塊可以看作是 log4j 的一個優化版本,它天然的支持 SLF4J,所以你可以隨意的從其它日誌框架(例如:log4j 或者 java.util.logging)切回到 logack。
logback-access 可以與 Servlet 容器進行整合,例如:Tomcat、Jetty。它提供了 http 訪問日誌的功能。
本文將集成到現有項目中,採用Lombok+Logback+slf4j
將實現日誌輸出:郵件,數據庫,控制檯,文件
以及動態加載日誌配置內容,無需重啓項目
Coding
Maven
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
無需單獨再引入slf4j-api,logback-classic裏面已經有了
logback配置文件
以下是 logback 的初始化步驟:
- logback 會在類路徑下尋找名爲 logback-test.xml 的文件。
- 如果沒有找到,logback 會繼續尋找名爲 logback.groovy 的文件。
- 如果沒有找到,logback 會繼續尋找名爲 logback.xml 的文件。
- 如果沒有找到,將會通過 JDK 提供的 ServiceLoader 工具在類路徑下尋找文件 META-INFO/services/ch.qos.logback.classic.spi.Configurator,該文件的內容爲實現了
Configurator
接口的實現類的全限定類名。- 如果以上都沒有成功,logback 會通過 BasicConfigurator 爲自己進行配置,並且日誌將會全部在控制檯打印出來。
最後一步的目的是爲了保證在所有的配置文件都沒有被找到的情況下,提供一個默認的(但是是非常基礎的)配置。
logback.xml
<?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>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
將日誌信息打印到控制檯,格式化時間,級別爲debug,作用是針對大於等於debug級別的log內容。
默認就是debug,所以level="debug"可寫可不寫,但爲了閱讀性還是寫上。
Test
package com.finance.www.log;
import lombok.extern.slf4j.Slf4j;
/**
* @author 954L
* @create 2020/4/30 10:55
*/
@Slf4j
public class LogbackTest {
public static void main(String[] args) {
log.trace("trace");
log.debug("debug");
log.info("info");
log.warn("warn");
log.error("error");
}
}
package com.finance.www.log;
import lombok.extern.slf4j.Slf4j;
/**
* @author 954L
* @create 2020/4/30 10:55
*/
@Slf4j
public class LogbackTest {
public static void main(String[] args) {
try {
System.out.println(1/0);
} catch (Exception e) {
log.error("程序異常", e);
}
}
}
@Slf4j註解是lombok裏的,等同於:
public static final Logger log = LoggerFactory.getLogger(LogbackTest.class);
輸出到文件
這也是目前最廣泛的做法了,一天一個log文件,可以指定查看某天的日誌文件內容,排查線上問題利器!優點就不具體說了。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--輸出到控制檯-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--輸出到文件地址 ${catalina.base}:tomcat目錄-->
<substitutionProperty name="logbase" value="${catalina.base}/logs/myLog/"/>
<!--輸出到info文件配置-->
<appender name="logInfoFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--error級別-->
<level>ERROR</level>
<!--onMatch="ACCEPT" 表示匹配該級別及以上
onMatch="DENY" 表示不匹配該級別及以上-->
<onMatch>DENY</onMatch>
<!-- onMismatch="ACCEPT" 表示匹配該級別以下
onMismatch="DENY" 表示不匹配該級別以下的-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!--
通過rollingPolicy設置日誌滾動的策略,這是使用按照時間滾動
fileNamePattern屬性設置滾動生成文件的格式,這裏設置的精確到天,也就是按照天滾動,如果時間設置精確到秒,就按秒來滾動
maxHistory屬性設定最大的文件數,比如按天滾動,這裏設置了30天,在第31天日誌生成的時候,第一天的日誌就會被刪掉
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件名策略-->
<FileNamePattern>${logbase}info/%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日誌文件保留天數-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<!--輸出到error文件配置-->
<appender name="logErrorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--error級別-->
<level>ERROR</level>
<!--onMatch="ACCEPT" 表示匹配該級別及以上
onMatch="DENY" 表示不匹配該級別及以上-->
<onMatch>ACCEPT</onMatch>
<!-- onMismatch="ACCEPT" 表示匹配該級別以下
onMismatch="DENY" 表示不匹配該級別以下的-->
<onMismatch>DENY</onMismatch>
</filter>
<!--
通過rollingPolicy設置日誌滾動的策略,這是使用按照時間滾動
fileNamePattern屬性設置滾動生成文件的格式,這裏設置的精確到天,也就是按照天滾動,如果時間設置精確到秒,就按秒來滾動
maxHistory屬性設定最大的文件數,比如按天滾動,這裏設置了30天,在第31天日誌生成的時候,第一天的日誌就會被刪掉
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件名策略-->
<FileNamePattern>${logbase}error/%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日誌文件保留天數-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="logInfoFile" />
<appender-ref ref="logErrorFile" />
</root>
</configuration>
上述將info級別及以下跟error級別的日誌區分在不同的文件裏,方便我們針對性處理,因爲你可不想以後在一堆debug日誌裏找一個error
Test
我們在web接口添加如下代碼
try {
System.out.println(1/0);
} catch (Exception e) {
log.info("測試異常", e);
log.error("測試異常", e);
}
效果符合預期,堆棧信息均有打印
輸出到郵件
與其等出bug再看異常日誌還不如直接在發生異常的時候就發送郵件到郵箱,這樣就能快速發現解決問題。
這裏就還是用網易爹的郵箱了,我幾乎所有發送郵件都是用網易的....
發送郵件是用logback的SMTPAppender,依賴javax.mail
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
SMTPAppender的屬性如下表所示:
屬性名 | 類型 | 描述 |
---|---|---|
smtpHost | String | SMTP 服務器的主機名。強制性的。 |
smtpPort | int | SMPT 服務監聽的端口。默認爲 25. |
to | String | 接收者的郵件地址。觸發事件發送給接收者。多個收件人可以使用逗號(,)分隔,或者使用多個 <to> 元素來指定。 |
from | String | SMTPAppender 使用的發件人,格式遵循郵件通用格式,如果你想要包含發送者的名字,使用這種格式 " Adam Smith <[email protected]>",那麼郵件將會顯示收件人爲 " Adam Smith \[email protected]\" |
subject | String | 郵件的主題。它可以是通過 PatternLayout 轉換後的有效值。關於 Layout 將在接下來的章節討論。 郵件應該有一個主題行,對應觸發的郵件信息。 假設 subject 的值爲:"Log: %Logger - %msg",觸發事件的 logger 名爲 "com.foo.Bar",並且日誌信息爲 "Hello world"。那麼發出的郵件信息將會有一個名爲 "Log: com.foo.Bar - Hello World" 的主題行。默認情況下,這個屬性的值爲 "%logger{20} - %m" |
discriminator | Discriminator | 在 Discriminator 的幫助下,SMTPAppender 根據 discriminator 返回的值可以將不同日誌事件分散到不同的緩衝區中。默認的 discriminator 將返回同一個值,所以所有的事件都使用同一個緩衝區。 |
evaluator | IEvaluator | 通過創建一個新的 元素來聲明此選項。通過 class 屬性指定 class 的名字表示用戶希望通過哪個類來滿足 SMTPAppender 的 Evaluator 的需要。如果沒有指定此選項,當觸發一個大於等於 ERROR 級別的事件時, SMTPAppender 將會被分配一個 OnErrorEvaluator 的實例。logback 配備了幾個其它的 evaluator,分別叫 OnMarkerEvaluator (將在下面討論),一個相對強大的 evaluator 叫 JaninoEventEvaluator (在其它章節討論) 以及最近版本纔有的一個更加強大的 evaluator 叫 GEventEvaluator 。 |
cyclicBufferTracker | CyclicBufferTracker |
從名字可以看出,是一個 CyclicBufferTracker 的實例追蹤循環緩衝區。它基於 discriminator 返回的 key (見上)。如果你不想指定一個 cyclicBufferTracker,那麼將會自動創建一個 CyclicBufferTracker 的實例。默認的,這個實例用來保留事件的循環緩衝區的大小爲 256。你需要改變 bufferSize 選項的大小(見下面) |
username | String | 默認爲 null |
password | String | 默認爲 null |
STARTTLS | boolean | 如果爲 true,那麼 appender 將會發送 STARTTLS 命令(如果服務器支持)將連接變成 SSL 連接。注意,連接初始的時候是爲加密的。默認爲 false。 |
SSL | boolean | 如果爲 true,將通過 SSL 連接服務器。默認爲 false。 |
charsetEncoding | String | 郵件信息將會通過 charset]https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html) 進行編碼。默認編碼爲 "UTF-8" |
localhost | String | 一旦 SMTP 客戶端的主機名沒有配置正確,例如客戶端的 hostname 不是全限定的,那麼服務端會拒絕客戶端發送的 HELO/EHLO 命令。爲了解決這個問題,你可以將 localhost 的值設置爲客戶端主機的全限定名。詳情見 com.sun.mail.smtp 包文檔中的 "mail.smtp.localhost" 屬性。(這個網站已經關閉了...) |
asynchronousSending | boolean | 決定郵件傳輸是否是異步進行。默認爲 'true'。但是,在某些特定的情況下,異步發送不怎麼合適。例如,當發生一個嚴重錯誤時,你的應用使用 SMTPAppender 去發送一個警告,然後退出。但是相關線程可能沒有時間去發送警告郵件。在這種情況下,你可以設置該屬性的值爲 'false'。 |
includeCallerData | boolean | 默認爲 false。如果 asynchronousSending 的值爲 true,並且你希望在日誌中看到調用者的信息,你可以設置該屬性的值爲 true |
sessionViaJNDI | boolean | SMTPAppender 基於 javax.mail.Session 來發送郵件信息。默認情況下,該屬性的值爲 false,所以需要用戶指定相關屬性通過 SMTPAppender 來構建 javax.mail.Session 實例。如果設置爲 true,javax.mail.Session 實例將會通過 JNDI 來獲取。參見 jndiLocation 屬性。通過 JNDI 獲取 Session 實例可以減少需要配置的數量,使你的應用減少重複(dryer)的工作。更多關於在 Tomcat 配置 JNDI 的信息請參考 JNDI Resources How-to。注意 :通過 JNDI 獲取 Session 的時候請移除 web 應用下 WEB-INF/lib 文件夾下的 mail.jar 與 activation.jar。 |
jndiLocation | String | JNDI 中放置 javax.mail.Session 的地方。默認爲:" java:comp/env/mail/Session " |
使用網易郵箱需單獨配置一下,我這輕車熟路了,就不再說了,附帶一篇我以前的blog,裏面有步驟
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--輸出到控制檯-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--輸出到文件地址 ${catalina.base}:tomcat目錄-->
<substitutionProperty name="logbase" value="${catalina.base}/logs/myLog/"/>
<!--輸出到info文件配置-->
<appender name="logInfoFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--error級別-->
<level>ERROR</level>
<!--onMatch="ACCEPT" 表示匹配該級別及以上
onMatch="DENY" 表示不匹配該級別及以上-->
<onMatch>DENY</onMatch>
<!-- onMismatch="ACCEPT" 表示匹配該級別以下
onMismatch="DENY" 表示不匹配該級別以下的-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!--
通過rollingPolicy設置日誌滾動的策略,這是使用按照時間滾動
fileNamePattern屬性設置滾動生成文件的格式,這裏設置的精確到天,也就是按照天滾動,如果時間設置精確到秒,就按秒來滾動
maxHistory屬性設定最大的文件數,比如按天滾動,這裏設置了30天,在第31天日誌生成的時候,第一天的日誌就會被刪掉
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件名策略-->
<FileNamePattern>${logbase}info/%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日誌文件保留天數-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<!--輸出到error文件配置-->
<appender name="logErrorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--error級別-->
<level>ERROR</level>
<!--onMatch="ACCEPT" 表示匹配該級別及以上
onMatch="DENY" 表示不匹配該級別及以上-->
<onMatch>ACCEPT</onMatch>
<!-- onMismatch="ACCEPT" 表示匹配該級別以下
onMismatch="DENY" 表示不匹配該級別以下的-->
<onMismatch>DENY</onMismatch>
</filter>
<!--
通過rollingPolicy設置日誌滾動的策略,這是使用按照時間滾動
fileNamePattern屬性設置滾動生成文件的格式,這裏設置的精確到天,也就是按照天滾動,如果時間設置精確到秒,就按秒來滾動
maxHistory屬性設定最大的文件數,比如按天滾動,這裏設置了30天,在第31天日誌生成的時候,第一天的日誌就會被刪掉
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件名策略-->
<FileNamePattern>${logbase}error/%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日誌文件保留天數-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<!--輸出到郵箱-->
<appender name="logErrorEmail" class="ch.qos.logback.classic.net.SMTPAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--error級別-->
<level>ERROR</level>
<!--onMatch="ACCEPT" 表示匹配該級別及以上
onMatch="DENY" 表示不匹配該級別及以上-->
<onMatch>ACCEPT</onMatch>
<!-- onMismatch="ACCEPT" 表示匹配該級別以下
onMismatch="DENY" 表示不匹配該級別以下的-->
<onMismatch>DENY</onMismatch>
</filter>
<smtpHost>smtp.163.com</smtpHost>
<To>[email protected]</To>
<To>[email protected]</To>
<username>xxx</username>
<password>password</password>
<From>[email protected]</From>
<asynchronousSending>false</asynchronousSending>
<Subject>TESTING Email Function: %logger{20} - %m</Subject>
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
</layout>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="logInfoFile" />
<appender-ref ref="logErrorFile" />
<appender-ref ref="logErrorEmail" />
</root>
</configuration>
- smtpHost:郵件服務器地址,網易固定值:smtp.163.com
- To:收件人郵箱地址,可配置多個
- username:發件人名稱(非郵箱地址)
- password:郵箱授權碼(非賬號登錄密碼)
- From:發送方郵箱地址
- asynchronousSending:是否異步發送郵件(默認:true)
- Subject:郵件內容
效果圖:
輸出到數據庫
個人不是很喜歡這種方式,但是有提供的話,順帶嘗試一下把
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--輸出到控制檯-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--輸出到文件地址 ${catalina.base}:tomcat目錄-->
<substitutionProperty name="logbase" value="${catalina.base}/logs/myLog/"/>
<!--輸出到info文件配置-->
<appender name="logInfoFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--error級別-->
<level>ERROR</level>
<!--onMatch="ACCEPT" 表示匹配該級別及以上
onMatch="DENY" 表示不匹配該級別及以上-->
<onMatch>DENY</onMatch>
<!-- onMismatch="ACCEPT" 表示匹配該級別以下
onMismatch="DENY" 表示不匹配該級別以下的-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!--
通過rollingPolicy設置日誌滾動的策略,這是使用按照時間滾動
fileNamePattern屬性設置滾動生成文件的格式,這裏設置的精確到天,也就是按照天滾動,如果時間設置精確到秒,就按秒來滾動
maxHistory屬性設定最大的文件數,比如按天滾動,這裏設置了30天,在第31天日誌生成的時候,第一天的日誌就會被刪掉
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件名策略-->
<FileNamePattern>${logbase}info/%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日誌文件保留天數-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<!--輸出到error文件配置-->
<appender name="logErrorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--error級別-->
<level>ERROR</level>
<!--onMatch="ACCEPT" 表示匹配該級別及以上
onMatch="DENY" 表示不匹配該級別及以上-->
<onMatch>ACCEPT</onMatch>
<!-- onMismatch="ACCEPT" 表示匹配該級別以下
onMismatch="DENY" 表示不匹配該級別以下的-->
<onMismatch>DENY</onMismatch>
</filter>
<!--
通過rollingPolicy設置日誌滾動的策略,這是使用按照時間滾動
fileNamePattern屬性設置滾動生成文件的格式,這裏設置的精確到天,也就是按照天滾動,如果時間設置精確到秒,就按秒來滾動
maxHistory屬性設定最大的文件數,比如按天滾動,這裏設置了30天,在第31天日誌生成的時候,第一天的日誌就會被刪掉
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件名策略-->
<FileNamePattern>${logbase}error/%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日誌文件保留天數-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
</appender>
<!--輸出到郵箱-->
<appender name="logErrorEmail" class="ch.qos.logback.classic.net.SMTPAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--error級別-->
<level>ERROR</level>
<!--onMatch="ACCEPT" 表示匹配該級別及以上
onMatch="DENY" 表示不匹配該級別及以上-->
<onMatch>ACCEPT</onMatch>
<!-- onMismatch="ACCEPT" 表示匹配該級別以下
onMismatch="DENY" 表示不匹配該級別以下的-->
<onMismatch>DENY</onMismatch>
</filter>
<smtpHost>smtp.163.com</smtpHost>
<To>[email protected]</To>
<username>18121419497</username>
<password>HCNWVDYOBDPTBYHN</password>
<From>[email protected]</From>
<asynchronousSending>false</asynchronousSending>
<Subject>財稅金結算平臺告警: %logger{20} - %m</Subject>
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger [%msg]%n</pattern>
</layout>
</appender>
<!--輸出到數據庫-->
<appender name="logInfoDb" class="ch.qos.logback.classic.db.DBAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--error級別-->
<level>ERROR</level>
<!--onMatch="ACCEPT" 表示匹配該級別及以上
onMatch="DENY" 表示不匹配該級別及以上-->
<onMatch>DENY</onMatch>
<!-- onMismatch="ACCEPT" 表示匹配該級別以下
onMismatch="DENY" 表示不匹配該級別以下的-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://localhost:3306/test</url>
<user>root</user>
<password>passw0rd</password>
</connectionSource>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="logInfoFile" />
<appender-ref ref="logErrorFile" />
<appender-ref ref="logErrorEmail" />
<appender-ref ref="logInfoDb" />
</root>
</configuration>
需要注意的是:<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
這裏使用的DriverManagerConnectionSource是ConnectionSource的一個實現,使用傳統JDBC的方式與DB交互。
它在每次獲取db連接的時候都會重新建立一條新連接,所以建議改爲內置連接池,示例:
<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource"> <dataSource class="com.alibaba.druid.pool.DruidDataSource"> <driverClassName>com.mysql.jdbc.Driver</driverClassName> <url>jdbc:mysql://localhost:3306/test</url> <username>root</username> <password>passw0rd</password> </dataSource> </connectionSource>
用阿里druid的話,記得加入maven
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>
之後需要初始化一下數據庫,創建表。logback不支持自動創建表,附帶sql
/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 50728
Source Host : localhost:3306
Source Database : test
Target Server Type : MYSQL
Target Server Version : 50728
File Encoding : 65001
Date: 2020-04-30 15:46:49
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for logging_event
-- ----------------------------
DROP TABLE IF EXISTS `logging_event`;
CREATE TABLE `logging_event` (
`timestmp` bigint(20) NOT NULL,
`formatted_message` text NOT NULL,
`logger_name` varchar(254) NOT NULL,
`level_string` varchar(254) NOT NULL,
`thread_name` varchar(254) DEFAULT NULL,
`reference_flag` smallint(6) DEFAULT NULL,
`arg0` varchar(254) DEFAULT NULL,
`arg1` varchar(254) DEFAULT NULL,
`arg2` varchar(254) DEFAULT NULL,
`arg3` varchar(254) DEFAULT NULL,
`caller_filename` varchar(254) NOT NULL,
`caller_class` varchar(254) NOT NULL,
`caller_method` varchar(254) NOT NULL,
`caller_line` char(4) NOT NULL,
`event_id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`event_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Table structure for logging_event_exception
-- ----------------------------
DROP TABLE IF EXISTS `logging_event_exception`;
CREATE TABLE `logging_event_exception` (
`event_id` bigint(20) NOT NULL,
`i` smallint(6) NOT NULL,
`trace_line` varchar(254) NOT NULL,
PRIMARY KEY (`event_id`,`i`),
CONSTRAINT `logging_event_exception_ibfk_1` FOREIGN KEY (`event_id`) REFERENCES `logging_event` (`event_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Table structure for logging_event_property
-- ----------------------------
DROP TABLE IF EXISTS `logging_event_property`;
CREATE TABLE `logging_event_property` (
`event_id` bigint(20) NOT NULL,
`mapped_key` varchar(254) NOT NULL,
`mapped_value` text,
PRIMARY KEY (`event_id`,`mapped_key`),
CONSTRAINT `logging_event_property_ibfk_1` FOREIGN KEY (`event_id`) REFERENCES `logging_event` (`event_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
效果圖: