一、JAVA日志框架發展歷程
- 1996年,歐洲安全電子市場項目組編寫了自己的程序跟蹤API,后發展成為Log4j,并成為Apache基金會項目成員;
- 2002年Java1.4,Sun推出Java Util Loggin(JUL),模仿了Log4j的實現;
- 2002年Apache推出Jakarta Commons Logging(JCL),定義了一套日志接口和簡單的Simple Log實現,支持運行時動態加載日志組件。從官網看,2014年1.2版本后就沒在更新了。
- 2006年,Ceki Gülcü創建了slf4j和Logback(也是Log4j的作者);
- 2012年,Apache開發Log4j 2,其與Log4j1不兼容。
二、一些基本概念
1. 接口與實現
- Commons Logging和Slf4j定義的是接口,需要給出具體的實現再使用;
- 一般Slf4j與Logback組合使用,Commons Logging與Log4j組合使用。
2. 日志信息輸出目的地
- 控制臺
- 打印到文件
- 打印到網絡
- 寫入數據庫
三、Jakarta Commons Logging(JCL)
1. 框架結構
JCL由Apache提供的一個通用日志API,包名: org.apache.commons.logging,有兩個抽象類:
- Log:基本記錄器
- LogFactory:負責創建Log實例
2. LogFactory查找日志工具的順序
- 尋找當前factory中名叫org.apache.commons.logging.Log配置屬性的值;
- 尋找系統中屬性中名叫org.apache.commons.logging.Log的值;
- 如果應用程序的classpath中有log4j,則使用相關的包裝(wrApper)類(Log4JLogger);
- 如果應用程序運行在jdk1.4的系統中,使用相關的包裝類(Jdk14Logger);
- 使用簡易日志包裝類(SimpleLog)。
3. 日志嚴重性排序
// 非常嚴重的錯誤
log.fatal(Object message);
log.fatal(Object message, Throwable t);
// 一般運行期間錯誤log.error(Object message);
log.error(Object message, Throwable t);
// 警告性錯誤log.warn(Object message);
log.warn(Object message, Throwable t);
// 有意義的日志信息log.info(Object message);
log.info(Object message, Throwable t);
// 調試信息log.debug(Object message);
log.debug(Object message, Throwable t);
// 更完整的跟蹤鏈信息log.trace(Object message);
log.trace(Object message, Throwable t);
4. 基本使用示例
3.4.1 maven引用
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
12345
3.4.2 java示例
// 引用import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;// 創建日志對象// 沒有其它日志實現的時候,會自動實現jdk自帶的日志JULprivate static Log log = LogFactory.getLog(Test.class);
// 調用,建議調用日志時都使用is...Enabled進行判斷 if (log.isDebugEnabled()) {
log.debug("debug test");
}
3.4.3 運行結果

5. 使用JCL+Log4j
3.5.1 maven引用
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
1234567891011
3.5.2 創建commons-loggin.properties文件
org.apache.commons.logging.Log = org.apache.commons.logging.impl.Log4JLogger
1
3.5.3 創建log4j.properties
#配置根 Loggers控制日志的輸出級別與日志是否輸出
log4j.rootLogger=trace,console
#配置輸出到控制臺 Appenders是指定日志的輸出方式
log4j.appender.console=org.apache.log4j.ConsoleAppender
#指定輸出控制臺
log4j.appender.console.Target = System.out
#指定布局,輸出日志的格式
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#指定布局的參數
log4j.appender.console.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
3.5.4 java示例
@Test
public void test() throws Exception{
// 獲取log日志記錄器對象
Log log = LogFactory.getLog(JCLTest.class);
if(log.isInfoEnabled()){
log.info("hello jcl");
}
}
3.5.5 運行結果

四、slf4j
1. 功能介紹
slf4j類似JCL提供日志接口,可以選用的實現有:NLOG4J、SimpleLogger、logback、log4j等,也可以通過slf4j提供的API實現來開發相應的適配器,如:Log4jLoggerAdapter、JDK14LoggerAdapter。
2. 使用slf4j+log4j
log4j是apache實現的一個開源日志組件。(Wrapped implementations)
4.2.1 maven引用
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
1234567
4.2.2 java示例
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Cade on 2020-10-14
*/
public class test {
private static final Logger logger = LoggerFactory.getLogger(test.class);
public static void main(String[] args){
if(logger.isInfoEnabled()){
logger.info("hello");
} }}
4.2.3 運行結果

3. slf4j+log4j 日志寫MySQL數據庫
4.3.1 maven引用
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
</dependencies>
123456789101112
4.3.2 log4j.properties
# 日記級別(單個級別) 文件/控制臺
log4j.rootLogger=debug, stdout,file,datasource
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Rirect log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppenderlog4j.appender.file.File=test.loglog4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayoutlog4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
#下面是配置將日志信息插入數據庫,#配置輸出目標為數據庫(假如要將日志在控制臺輸出,配置為log4j.appender. stdout =org.apache.log4j.ConsoleAppender;將日志寫入文件,配置為log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
#這樣的配置在許多地方都要有,需要可查有關資料),當然你也可以自己擴展org.apache.log4j.jdbc.JDBCAppender這個類,只需要在這里配置就可以了例如我們配置我自己擴展的MyJDBCAppender,配置為#log4j.appender.db=com.neam.commons.MyJDBCAppenderlog4j.appender.datasource=org.apache.log4j.jdbc.JDBCAppenderlog4j.appender.datasource.layout=org.apache.log4j.PatternLayoutlog4j.appender.datasource.driver=com.mysql.jdbc.Driver#定義什么級別的錯誤將寫入到數據庫中log4j.appender.datasource.BufferSize=1
#設置緩存大小,就是當有1條日志信息是才忘數據庫插一次,我設置的數據庫名和表名均為user
log4j.appender.datasource.URL=jdbc:mysql://數據庫ip:3306/數據庫名稱?characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull
log4j.appender.datasource.user=數據庫賬號log4j.appender.datasource.password=數據庫密碼log4j.appender.datasource.sql=insert into logs (class,method,create_time,log_level,log_line,msg) values ('%C','%M','%d{yyyy-MM-dd HH:mm:ss}','%p','%l','%m')
4.3.3 數據庫建表
CREATE TABLE `logs` (
`class` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`method` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`create_time` datetime(0) NULL DEFAULT NULL,
`log_level` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`log_line` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`msg` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
4.3.4 java代碼
//注意導入的包都是slf4j的包
import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class test { private static final Logger log = LoggerFactory.getLogger(test.class);
public static void main(String[] args) { if(log.isInfoEnabled()){
log.info("logback的--info日志--輸出了");
} }}
4.3.5 運行結果

4. 使用slf4j+logback
logback同樣是由log4j的作者設計完成的,擁有更好的特性,用來取代log4j的一個日志框架。是slf4j的原生實現。(Native implementations)
logback特點:
- 更快的執行速度
- 充分的測試
- 自動重新載入配置文件
- 優雅地從I/O錯誤中恢復
- 自動清除舊的日志歸檔文件
- 自動壓縮歸檔日志文件
…
4.4.1 maven引用
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
12345
4.4.2 配置文件logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
scan:當此屬性設置為true時,配置文件如果發生改變,將會被重新加載,默認值為true。
scanPeriod:設置監測配置文件是否有修改的時間間隔,如果沒有給出時間單位,默認單位是毫秒當scan為true時,此屬性生效。默認的時間間隔為1分鐘。
debug:當此屬性設置為true時,將打印出logback內部日志信息,實時查看logback運行狀態。默認值為false。
-->
<configuration scan="false" scanPeriod="60 seconds" debug="false">
<!-- 定義日志的根目錄 -->
<property name="LOG_HOME" value="/app/log" />
<!-- 定義日志文件名稱 -->
<property name="appName" value="netty"></property>
<!-- ch.qos.logback.core.ConsoleAppender 表示控制臺輸出 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<Encoding>UTF-8</Encoding>
<!--
日志輸出格式:%d表示日期時間,%thread表示線程名,%-5level:級別從左顯示5個字符寬度
%logger{50} 表示logger名字最長50個字符,否則按照句點分割。 %msg:日志消息,%n是換行符
-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</layout>
</appender>
<!-- 滾動記錄文件,先將日志記錄到指定文件,當符合某個條件時,將日志記錄到其他文件 -->
<appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<Encoding>UTF-8</Encoding>
<!-- 指定日志文件的名稱 -->
<file>${LOG_HOME}/${appName}.log</file>
<!--
當發生滾動時,決定 RollingFileAppender 的行為,涉及文件移動和重命名
TimeBasedRollingPolicy: 最常用的滾動策略,它根據時間來制定滾動策略,既負責滾動也負責出發滾動。
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--
滾動時產生的文件的存放位置及文件名稱 %d{yyyy-MM-dd}:按天進行日志滾動
%i:當文件大小超過maxFileSize時,按照i進行文件滾動
-->
<fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!--
可選節點,控制保留的歸檔文件的最大數量,超出數量就刪除舊文件。假設設置每天滾動,
且maxHistory是365,則只保存最近365天的文件,刪除之前的舊文件。注意,刪除舊文件是,
那些為了歸檔而創建的目錄也會被刪除。
-->
<MaxHistory>365</MaxHistory>
<!--
當日志文件超過maxFileSize指定的大小是,根據上面提到的%i進行日志文件滾動 注意此處配置SizeBasedTriggeringPolicy是無法實現按文件大小進行滾動的,必須配置timeBasedFileNamingAndTriggeringPolicy
-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!--
日志輸出格式:%d表示日期時間,%thread表示線程名,%-5level:級別從左顯示5個字符寬度 %logger{50} 表示logger名字最長50個字符,否則按照句點分割。 %msg:日志消息,%n是換行符
-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
</layout>
</appender>
<!--
logger主要用于存放日志對象,也可以定義日志類型、級別
name:表示匹配的logger類型前綴,也就是包的前半部分
level:要記錄的日志級別,包括 TRACE < DEBUG < INFO < WARN < ERROR
additivity:作用在于children-logger是否使用 rootLogger配置的appender進行輸出,false:表示只用當前logger的appender-ref,true:表示當前logger的appender-ref和rootLogger的appender-ref都有效
-->
<!-- hibernate logger -->
<logger name="org.hibernate" level="error" />
<!-- Spring framework logger -->
<logger name="org.springframework" level="error" additivity="false"></logger>
<logger name="com.creditease" level="info" additivity="true">
<appender-ref ref="appLogAppender" />
</logger>
<!--
root與logger是父子關系,沒有特別定義則默認為root,任何一個類只會和一個logger對應,
要么是定義的logger,要么是root,判斷的關鍵在于找到這個logger,然后判斷這個logger的appender和level。
-->
<root level="info">
<appender-ref ref="stdout" />
<appender-ref ref="appLogAppender" />
</root>
</configuration>
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
4.4.3 java代碼
//注意導入的包都是slf4j的包
import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class test {
private static final Logger LOGGER = LoggerFactory.getLogger(test.class); public static void main(String[] args) { if(LOGGER.isInfoEnabled()){
LOGGER.info("logback的--info日志--輸出了");
} }}
4.4.4 運行結果

五、日志組件沖突
如果在引用的項目里使用了log4j,如:zookeeper使用了log4j,在pom中解決沖突:
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
123456789101112131415
可以使用
mvn dependecy:tree
查看依賴情況,或者在idea 的Maven窗口可以方便地看到引用情況。

六、Spring中使用Log4j
在web.xml設置:
<!-- 設置根目錄 -->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.root</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<!-- 3000表示 開一條watchdog線程每60秒掃描一下配置文件的變化;這樣便于日志存放位置的改變 -->
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>3000</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
123456789101112131415161718
七、SpringBoot2 使用 logback
1. 引用
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xundh</groupId>
<artifactId>javalearn</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
</dependencies>
</project>
1234567891011121314151617181920212223
添加Springboot的引用后,可以在idea中查看已經包含了log的幾個組件:

2. 創建logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設置為WARN,則低于WARN的信息都不會輸出 -->
<!-- scan:當此屬性設置為true時,配置文件如果發生改變,將會被重新加載,默認值為true -->
<!-- scanPeriod:設置監測配置文件是否有修改的時間間隔,如果沒有給出時間單位,默認單位是毫秒。當scan為true時,此屬性生效。默認的時間間隔為1分鐘。 -->
<!-- debug:當此屬性設置為true時,將打印出logback內部日志信息,實時查看logback運行狀態。默認值為false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logback</contextName>
<!-- name的值是變量的名稱,value的值時變量定義的值。通過定義的值會被插入到logger上下文中。定義變量后,可以使“${}”來使用變量。 -->
<property name="log.path" value="./logs" />
<!-- 彩色日志 -->
<!-- 彩色日志依賴的渲染類 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--輸出到控制臺-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是為開發使用,只配置最底級別,控制臺輸出的日志級別是大于或等于此級別的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>info</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 設置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--輸出到文件-->
<!-- 時間滾動輸出 level為 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日志文件的路徑及文件名 -->
<file>${log.path}/log_debug.log</file>
<!--日志文件輸出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 設置字符集 -->
</encoder>
<!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志歸檔 -->
<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天數-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只記錄debug級別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 時間滾動輸出 level為 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日志文件的路徑及文件名 -->
<file>${log.path}/log_info.log</file>
<!--日志文件輸出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志歸檔路徑以及格式 -->
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天數-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只記錄info級別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 時間滾動輸出 level為 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日志文件的路徑及文件名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文件輸出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此處設置字符集 -->
</encoder>
<!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天數-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只記錄warn級別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 時間滾動輸出 level為 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在記錄的日志文件的路徑及文件名 -->
<file>${log.path}/log_error.log</file>
<!--日志文件輸出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此處設置字符集 -->
</encoder>
<!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天數-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只記錄ERROR級別的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
<logger>用來設置某一個包或者具體的某一個類的日志打印級別、
以及指定<appender>。<logger>僅有一個name屬性,
一個可選的level和一個可選的addtivity屬性。
name:用來指定受此logger約束的某一個包或者具體的某一個類。
level:用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
還有一個特俗值INHERITED或者同義詞NULL,代表強制執行上級的級別。
如果未設置此屬性,那么當前logger將會繼承上級的級別。
addtivity:是否向上級logger傳遞打印信息。默認是true。
-->
<!--<logger name="org.springframework.web" level="info"/>-->
<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>-->
<!--
使用mybatis的時候,sql語句是debug下才會打印,而這里我們只配置了info,所以想要查看sql語句的話,有以下兩種操作:
第一種把<root level="info">改成<root level="DEBUG">這樣就會打印sql,不過這樣日志那邊會出現很多其他消息
第二種就是單獨給dao下目錄配置debug模式,代碼如下,這樣配置sql語句會打印,其他還是正常info級別:
-->
<!--
root節點是必選節點,用來指定最基礎的日志輸出級別,只有一個level屬性
level:用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
不能設置為INHERITED或者同義詞NULL。默認是DEBUG
可以包含零個或多個元素,標識這個appender將會添加到這個logger。
-->
<!--開發環境:打印控制臺-->
<springProfile name="dev">
<logger name="com.xundh.view" level="debug"/>
</springProfile>
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<!--生產環境:輸出到文件-->
<!--<springProfile name="pro">-->
<!--<root level="info">-->
<!--<appender-ref ref="CONSOLE" />-->
<!--<appender-ref ref="DEBUG_FILE" />-->
<!--<appender-ref ref="INFO_FILE" />-->
<!--<appender-ref ref="ERROR_FILE" />-->
<!--<appender-ref ref="WARN_FILE" />-->
<!--</root>-->
<!--</springProfile>-->
</configuration>
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
3. 運行效果

六、Lombok 日志注解
Lombok可以用來創建 slf4j+logback的日志
1. 使用方法
6.1.1 maven引用
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.14</version>
<scope>provided</scope>
</dependency>
</dependencies>
12345678910111213
6.1.2 java代碼
//注意導入的包都是slf4j的包
import lombok.extern.slf4j.Slf4j;@Slf4jpublic class test { public static void main(String[] args) { if(log.isInfoEnabled()){
log.info("logback的--info日志--輸出了");
} }}
其它配置與slf4j+logback類似。
6.1.3 運行效果

八、logback+redis
1. 依賴
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.cwbase</groupId>
<artifactId>logback-redis-appender</artifactId>
<version>1.1.5</version>
</dependency>
12345678910
2. logback.xml
<configuration>
<property name="type.name" value="" />
<appender name="TEST" class="com.cwbase.logback.RedisAppender">
<source>test-application</source>
<!--type 可定為項目類型-->
<type>${type.name}</type>
<!--redis ip-->
<host>你的redis ip</host>
<!--redis存放的key-->
<key>logstash:redis</key>
<tags>test-2</tags>
<mdc>true</mdc>
<location>true</location>
<callerStackIndex>0</callerStackIndex>
<!--additionalField添加附加字段 用于head插件顯示-->
<additionalField>
<key>MyKey</key>
<value>MyValue</value>
</additionalField>
<additionalField>
<key>MySecondKey</key>
<value>MyOtherValue</value>
</additionalField>
</appender>
<!--日志輸出-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!--日志回滾周期30天-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- <encoder>
<pattern>%logger{15} - %message%n%xException{5}</pattern>
</encoder>-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-4relative [%thread] %-5level %logger{35} %caller{3} - %msg%n%xException{5}</pattern>
</encoder>
</appender>
<logger name="application" level="DEBUG" />
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="TEST" />
</root>
</configuration>
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
九、logback+logstash
可以在第七條基礎上,讓logstash從redis獲取數據,或直接使用logstash-logback插件。
1. 依賴
<!-- Logstash encoder -->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.4</version>
</dependency>
123456
2. logback.xml添加內容
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are by default assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<param name="Encoding" value="UTF-8"/>
<remoteHost>logstash ip</remoteHost>
<port>4567</port>
<!-- encoder is required -->
<encoder class="net.logstash.logback.encoder.LogstashEncoder" />
</appender>
<root level="info">
<appender-ref ref="logstash" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
1234567891011121314151617181920212223242526
十、日志上阿里云
使用阿里云的日志服務,可以避免自行搭建ELK的復雜配置。對于云上分布式的應用來說,使用阿里云是一個比較好的選擇方案。
文檔地址: https://github.com/aliyun/aliyun-log-logback-appender/blob/master/README_CN.md
1. 申請阿里云日志服務
- 按提示申請服務后,創建Project
- 按提示創建logstore
- 點擊logstore、數據接入后的加號,可以看到有很多接入方式,這里選擇logback-sdk寫入:
2. 添加依賴
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>aliyun-log-logback-appender</artifactId>
<version>0.1.15</version>
</dependency>
12345678910
3. logback.xml配置文件
<!--為了防止進程退出時,內存中的數據丟失,請加上此選項-->
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
<appender name="aliyun" class="com.aliyun.openservices.log.logback.LoghubAppender">
<!--必選項-->
<!-- 賬號及網絡配置 -->
<endpoint>your project endpoint</endpoint>
<accessKeyId>your accesskey id</accessKeyId>
<accessKeySecret>your accesskey</accessKeySecret>
<!-- sls 項目配置 -->
<project>your project</project>
<logStore>your logStore</logStore>
<!--必選項 (end)-->
<!-- 可選項 -->
<topic>your topic</topic>
<source>your source</source>
<!-- 可選項 詳見 '參數說明'-->
<totalSizeInBytes>104857600</totalSizeInBytes>
<maxBlockMs>60000</maxBlockMs>
<ioThreadCount>8</ioThreadCount>
<batchSizeThresholdInBytes>524288</batchSizeThresholdInBytes>
<batchCountThreshold>4096</batchCountThreshold>
<lingerMs>2000</lingerMs>
<retries>10</retries>
<baseRetryBackoffMs>100</baseRetryBackoffMs>
<maxRetryBackoffMs>100</maxRetryBackoffMs>
<!-- 可選項 通過配置 encoder 的 pattern 自定義 log 的格式 -->
<encoder>
<pattern>%d %-5level [%thread] %logger{0}: %msg</pattern>
</encoder>
<!-- 可選項 設置 time 字段呈現的格式 -->
<timeFormat>yyyy-MM-dd'T'HH:mmZ</timeFormat>
<!-- 可選項 設置 time 字段呈現的時區 -->
<timeZone>UTC</timeZone>
</appender>
<!-- 可用來獲取StatusManager中的狀態
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/>
-->
1234567891011121314151617181920212223242526272829303132333435363738394041424344
4. java代碼
package com.aliyun.openservices.log.logback.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
/**
* Created by brucewu on 2018/1/8.
*/
public class LogbackAppenderExample {
private static final Logger LOGGER = LoggerFactory.getLogger(LogbackAppenderExample.class);
public static void main(String[] args) {
MDC.put("MDC_KEY","MDC_VALUE");
MDC.put("THREAD_ID", String.valueOf(Thread.currentThread().getId()));
LOGGER.trace("trace log");
LOGGER.debug("debug log");
LOGGER.info("info log");
LOGGER.warn("warn log");
LOGGER.error("error log");
}}
5. 查詢示例

十一、idea 彩色日志插件
1. 安裝插件Grep Console

2. 運行效果
