濰坊知名網(wǎng)站建設服務商娃哈哈軟文推廣
目錄
1.概述
2.切換日志實現(xiàn)
3.使用
3.1.日志級別
3.3.日志離線
3.4.詳細定制
1.概述
由一些歷史原因,JAVA領域存在有很多日志框架,如Log4j、Logback、log4j2。
log4j是Java日志框架的元老,在log4j被Apache Foundation收入門下之后,由于理念不合,log4j的作者Ceki離開并開發(fā)了slf4j和logback。這幾個框架都很熱門,這就造成了不同系統(tǒng)、不同開源框架使用的日志框架都不同。
因為不同日志框架的日志輸出格式、API均不同,所以當系統(tǒng)中存在多種日志框架被混用就會出現(xiàn)沖突,最直接的現(xiàn)象就是——日志格式不統(tǒng)一,這對項目的日志排查來說是極不方便的,甚至有時候還會因為日志框架的沖突而報錯。因此同一個項目中統(tǒng)一日志框架是十分有必要的,但是如果只是單純的保留一個日志框架,移除其余日志框架,由于各日志系統(tǒng)API的不同很可能系統(tǒng)根本就起不來,所以需要一個中間層來進行適配,從而解決這個問題。
這個中間層就是——日志門面。日志門面使用門面模式屏蔽掉了不同日志實現(xiàn)之間的不同,對外暴露統(tǒng)一的API。
2.切換日志實現(xiàn)
SpringBoot默認使用SLF4J作為日志門面,LogBack作為日志實現(xiàn)來記錄日志。
這里我們不去細究SLF4J是怎么去完成適配的,只需要知道SpringBoot自帶了日志門面,使用日志門面來輸出日志,當想要切換日志實現(xiàn)的時候,排掉LogBack,引入新的實現(xiàn)即可。
以切換為log4j2為例:
<dependency>
? ? <groupId>org.springframework.boot</groupId>
? ? <artifactId>spring-boot-starter-web</artifactId>
? ? <!--1. 排除掉依賴 ,以此排除掉logback+slf4j引用-->
? ? <exclusions>
? ? ? ? ?<exclusion>
? ? ? ? ? ? ?<groupId>org.springframework.boot</groupId>
? ? ? ? ? ? ?<artifactId>spring-boot-starter-logging</artifactId>
? ? ? ? ? </exclusion>
? ? ?</exclusions>
</dependency>
<!--2. 添加log4j2依賴 -->
<dependency>
? ? ?<groupId>org.springframework.boot</groupId>
? ? ?<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
3.使用
3.1.日志級別
配置:
可以指定全局日志等級,也可以以方法為粒度指定日志等級,支持*作為通配符
#全局日志等級 logging.level.root=trace #單都指定日志等級 logging.level.com.eryi.controller.MyRunner.*=trace
代碼:
package com.eryi.controller;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class MyRunner implements CommandLineRunner {//特別注意,要使用slf4j的Logger和LoggerFactoryLogger logger= LoggerFactory.getLogger(MyRunner.class);@Overridepublic void run(String... args) throws Exception {//日志級別:error<warn<info<debug<tracelogger.trace("trace......");logger.debug("debug......");//Spring Boot默認使用info級別logger.info("info......");logger.warn("warn......");logger.error("error......");}
}
3.3.日志離線
不指定路徑,日志文件只會在控制臺輸出,不會離線為本地文件。
使用path可以指定路徑,文件名默認使用springlog.log
使用file可以指定路徑+文件名,不指定路徑會默認離現(xiàn)在工程目錄下。
file和path是兩個沖突設置,如果同時配置,只有file會生效。
3.4.詳細定制
spring boot的配置文件中的日志配置項只能進行粗粒度的配置,想對日志進行細粒度的定制需要在類路徑下(一般是在resources下)編寫xml配置文件。命名規(guī)則為XXX-spring.xml,XXX是日志框架的名稱。
以下為一個logback-spring.xml的模板:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
? ? <!--
? ? ?configuration中有appender、logger、root三個節(jié)點
? ? ? appender:表示的是定義了一種文件的輸出格式 ?就有點類似于 變量進行了定義 但是沒有來得及使用
? ? ? logger:這個就表示的是我們定義了這個變量在哪一個局部能夠使用
? ? ? ? ? ? ? 我們的日志原本是針對于整個工程的配置 ?但是你可以定義在哪一個包里面 ?使用什么日志輸出格式 以及 輸出到哪些地方
? ? ? root:相當于定義的是整個項目 的日志輸出級別 ?以及 輸出日志到哪些地方
? ? -->? ? <!--
? ? ? ?定義了日志的輸出 ?ConsoleAppender ?這個類表示的是輸出到控制臺
? ? -->
? ? <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
? ? ? ? <!--設置輸出到控制臺的編碼和格式? ? ? ? %d{yyyy-MM-dd-HH:mm:ss.SSS}:這個表示的是時間的引用
? ? ? ? %level:當前輸出的日志級別
? ? ? ? [%thread]:表示當前是哪一個線程
? ? ? ? %class:這個表示的是這個日志是在哪一個類中打印出來的
? ? ? ? %line:這個表示的是打印這個日志是在這個類的 哪一行打印出來的
? ? ? ? %msg:這個表示的是打印的消息是什么
? ? ? ? %n:這個表示的是換行
? ? ? ? -->
? ? ? ? <encoder>
? ? ? ? ? ? <pattern>%d{yyyy-MM-dd-HH:mm:ss.SSS}------->%level--------->[%thread]-%class:%line----->%msg%n</pattern>
? ? ? ? ? ? <!--設置了打印到控制臺的編碼-->
? ? ? ? ? ? <charset>UTF-8</charset>
? ? ? ? </encoder>
? ? </appender>
? ? <!--
? ? ? ?定義日志輸出到文件的格式
? ? ? ?name:是可以隨便寫的 ? FileAppender:輸出到文件
? ? -->
? ? <appender name="file" class="ch.qos.logback.core.FileAppender">? ? ? ? <!--這個表示的是日志文件輸出的路徑 ?這個默認表示的是輸出到當前項目的根目錄下 叫做file.log-->
? ? ? ? <file>log/file.log</file>
? ? ? ? <!--這個表示的是 每一次寫日志的時候是在上一次的基礎上進行追加-->
? ? ? ? <append>true</append>
? ? ? ? <encoder>
? ? ? ? ? ? <!--定義了輸出的格式-->
? ? ? ? ? ? <pattern>%d{yyyy-MM-dd-HH:mm:ss.SSS} %level ? ?[%thread]-%class:%line>>%msg%n</pattern>
? ? ? ? ? ? <charset>UTF-8</charset>
? ? ? ? </encoder>
? ? ? ? <!--
? ? ? ? ? ? prudent=true:表示的是日志的寫入是線程安全的、但是線程安全會降低效率 ?一般默認設置為false
? ? ? ? -->
? ? ? ? <prudent>false</prudent>
? ? </appender>? ? <!--
? ? ? ?RollingFileAppender:表示的是日志要滾動輸出? ? -->
? ? <appender name="timeFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
? ? ? ? <!--
? ? ? ? ? ? rollingPolicy滾動的策略
? ? ? ? ? ? TimeBasedRollingPolicy:最常用的一個、根據(jù)時間進行滾動 當達到一定的時間的時候、就會自動開辟一個新的日志文件
? ? ? ? ? ? FixedWindowRollingPolicy:根據(jù)固定窗口的算法重命名文件的滾動策略
? ? ? ? ? ? TriggeringPolicy:根據(jù)當前活動文件的大小來來確定是否滾動
? ? ? ? -->
? ? ? ? <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
? ? ? ? ? ? <!--日志文件的名字 ?引用了當前的日期-->
? ? ? ? ? ? <fileNamePattern>log/logFile%d{yyyy-MM-dd}.log</fileNamePattern>
? ? ? ? ? ? <!--生成這個日志文件 保留多少天-->
? ? ? ? ? ? <maxHistory>30</maxHistory>
? ? ? ? </rollingPolicy>
? ? ? ? <!--編碼的格式-->
? ? ? ? <encoder>
? ? ? ? ? ? <pattern>%d{yyyy-MM-dd-HH:mm:ss.SSS} %level ? ?[%thread]-%class:%line>>%msg%n</pattern>
? ? ? ? ? ? <charset>UTF-8</charset>
? ? ? ? </encoder>
? ? </appender>? ? <!--
? ? ? ?RollingFileAppender:這個是滾動輸出
? ? ? ?FixedWindowRollingPolicy:根據(jù)活動窗口算法的大小來滾動輸出? ? -->
? ? <appender name="fixedFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
? ? ? ? <!--日志的名字-->
? ? ? ? <file>log/fixedFile.log</file>
? ? ? ? <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
? ? ? ? ? ? <fileNamePattern>log/fixedFile%i.log.zip</fileNamePattern>
? ? ? ? ? ? <!--最少生成一個日志文件-->
? ? ? ? ? ? <minIndex>1</minIndex>
? ? ? ? ? ? <!--最多生成3個日志文件-->
? ? ? ? ? ? <maxIndex>3</maxIndex>
? ? ? ? </rollingPolicy>? ? ? ? <!--根據(jù)文件的大小來設置滾動輸出的-->
? ? ? ? <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
? ? ? ? ? ? <!--日志文件的最大的大小-->
? ? ? ? ? ? <maxFileSize>5MB</maxFileSize>
? ? ? ? </triggeringPolicy>
? ? ? ? <!--日志輸出的格式-->
? ? ? ? <encoder>
? ? ? ? ? ? <pattern>%d{yyyy-MM-dd-HH:mm:ss.SSS} %level ? ?[%thread]-%class:%line>>%msg%n
? ? ? ? ? ? </pattern>
? ? ? ? ? ? <charset>UTF-8</charset>
? ? ? ? </encoder>
? ? </appender>
? ? <!--文件輸出-->
? ? <appender name="filter" class="ch.qos.logback.core.FileAppender">
? ? ? ? <file>log/filter.log</file>
? ? ? ? <append>true</append>
? ? ? ? <!--
? ? ? ? ? ? LevelFilter:的意思是添加了一個日志級別的過濾器
? ? ? ? ? ? 如果日志的級別等于配置的級別。那么則執(zhí)行onMatch里面的配置
? ? ? ? ? ? 否則執(zhí)行 onMismatch中的內容
? ? ? ? -->
? ? ? ? <filter class="ch.qos.logback.classic.filter.LevelFilter">
? ? ? ? ? ? <level>INFO</level>
? ? ? ? ? ? <!--
? ? ? ? ? ? ? ? ?ACCEPT:當前的日志會立即被執(zhí)行不經(jīng)過其他的過濾器了
? ? ? ? ? ? ? ? ?DENY:日志立即被拋棄、也不再經(jīng)過其他的過濾器了
? ? ? ? ? ? ? ? ?NEUTRAL:下一個過濾器將繼續(xù)執(zhí)行、如果是最后一個過濾器的話那么就會被執(zhí)行
? ? ? ? ? ? -->
? ? ? ? ? ? <onMatch>ACCEPT</onMatch>
? ? ? ? ? ? <onMismatch>DENY</onMismatch>
? ? ? ? </filter>
? ? ? ? <!--臨界值過濾器:如果你輸出的日志級別 是低于下面定義的這個級別的話那么 就會被過濾掉-->
? ? ? ? <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
? ? ? ? ? ? <level>INFO</level>
? ? ? ? </filter>? ? ? ? <encoder>
? ? ? ? ? ? <pattern>%d{yyyy-MM-dd-HH:mm:ss.SSS} %level ? ?[%thread]-%class:%line>>%msg%n
? ? ? ? ? ? </pattern>
? ? ? ? ? ? <charset>UTF-8</charset>
? ? ? ? </encoder>
? ? ? ? <prudent>false</prudent>
? ? </appender>? ? <!--設置局部的 這個日志的輸出級別 或者 是 在哪里輸出日志-->
? ? ? ? ? ? ? ? <!--測試的路徑-->
? ? <!-- ? ?<logger name="com.project.controller" level="trace" addtivity="false">
? ? ? ? ? ? <appender-ref ref="stdout" />
? ? ? ? ? ? <appender-ref ref="file" />
? ? ? ? ? ? <appender-ref ref="timeFile" />
? ? ? ? </logger>-->? ? <!--這個是給全局設置一個日志級別 ?所有的都適用
? ? ? ? appender-ref :全局的日志我們要打印到哪些地方? ? -->
? ? <root level="error">
<!-- ? ? ? ?打印到控制臺-->
? ? ? ? <appender-ref ref="stdout" />
<!-- ? ? ? ?打印到file文件里-->
? ? ? ? <appender-ref ref="file" />
? ? ? ? <appender-ref ref="timeFile" />
? ? ? ? <!--<appender-ref ref="fixedFile" />-->
? ? ? ? <!--<appender-ref ref="filter" />-->
? ? </root></configuration>
?