前言 Java髮展至今已經形成了一套完整的日誌體繫,分爲日誌門麵和日誌具體實現。日誌門麵相當於一個接口,日誌各種實現其實就是日誌門麵的不同實現。
Java的日誌加載依賴於SPI ,不同於API, SPI模式下接口處於調用者一側,開髮者一側隻擁有具體的實現。而API模式下接口和具體實現都處於開髮者一側,調用者無需關心具體實現,隻管調用開髮者提供的接口即可。
SPI機製給予了程序動態加載的能力,程序運行的過程中根據接口去動態掃描對應的接口實現類並加載。
舉個例子,Java的日誌門麵Slf4j對應的具體實現有Spring Boot自帶的也是默認的logback,還有log4j,log4j2等,在使用時會動態加載classpath中存在的slf4j對應的實現類並把它加載使用,這就是SPI機製。
Logback logback是Spring Boot默認使用的日誌實現,即使不配置也可以直接使用。
1 2 3 4 5 6 7 8 9 10 @SpringBootApplication public class RedisUsageApplication { public static void main (String[] args) { SpringApplication.run(RedisUsageApplication.class, args); Logger log = LoggerFactory.getLogger("RedisUsageApplication.class" ); log.warn("Easy bro, this is a fake warn lol." ); log.error("Easy bro, this is a fake error lol." ); } }
也可以使用Lombok提供的注解@Slf4j來輸出log,這樣簡潔一些。
1 2 3 4 5 6 7 8 9 10 @SpringBootApplication @Slf4j public class RedisUsageApplication { public static void main (String[] args) { SpringApplication.run(RedisUsageApplication.class, args); log.warn("Easy bro, this is a fake warn lol." ); log.error("Easy bro, this is a fake error lol." ); } }
但是默認的配置還是不能夠更加精準的滿足各種需求,需要進行自定義設置。
在classpath下創建logback.xml或者logback-spring.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 <configuration > <include resource ="org/springframework/boot/logging/logback/defaults.xml" /> <property name ="APP_NAME" value ="log-files" /> <property name ="LOG_PATH" value ="${user.home}/${APP_NAME}" /> <property name ="LOG_FILE" value ="${LOG_PATH}/redis-usage.log" /> <appender name ="APPLICATION" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > ${LOG_FILE}</file > <rollingPolicy class ="ch.qos.logback.core.rolling.TimeBasedRollingPolicy" > <fileNamePattern > ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern > <maxHistory > 7</maxHistory > <timeBasedFileNamingAndTriggeringPolicy class ="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP" > <maxFileSize > 50MB</maxFileSize > </timeBasedFileNamingAndTriggeringPolicy > </rollingPolicy > <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 > <appender name ="CONSOLE" class ="ch.qos.logback.core.ConsoleAppender" > <layout class ="ch.qos.logback.classic.PatternLayout" > <pattern > %green(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%magenta(%thread)] %highlight(%-5level) %yellow(%logger{36}): %msg%n</pattern > </layout > </appender > <root level ="info" > <appender-ref ref ="CONSOLE" /> <appender-ref ref ="APPLICATION" /> </root > </configuration >
log的配置中有這麼幾個標籤
property: 可以自定義變量名和變量值,方便拼接路徑等。
appender: 每一個appender對應一個日誌的輸出地點
layout: 日誌的輸出格式
rollingPolicy: 日誌的滾動策略
通過這些標籤可以實現日誌的完全自定義。
使用logback時可以在application.yml或者application.properties中加入logback的配置,但也可以不配置,因爲Spring Boot的默認行爲是掃描classpath下是否有logback.xml或者logback-spring.xml。
1 2 logging: config: classpath:logback-spring.xml
同時日誌文件也可以在對應的目錄下找到
Log4j2 log4j2和logback都是slf4j的具體實現,但在實際應用中二者不能同時存在,否則會報錯,導緻無法正常加載日誌的實現類。
所以在使用log4j2時需要在pom中顯示的剔除logback依賴,同時加入log4j2的依賴。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > <exclusions > <exclusion > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-logging</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-log4j2</artifactId > </dependency >
在classpath下創建log4j2.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 <?xml version="1.0" encoding="UTF-8" ?> <Configuration > <properties > <property name ="LOG_HOME" > ./service-logs</property > </properties > <Appenders > <Console name ="consoleAppender" target ="SYSTEM_OUT" > <PatternLayout pattern ="%style{%d{ISO8601}}{bright,green} %highlight{%-5level} [%style{%t}{bright,blue}] %style{%C{}}{bright,yellow}: %msg%n%style{%throwable}{red}" disableAnsi ="false" noConsoleNoAnsi ="false" /> </Console > <RollingFile name ="allFileAppender" fileName ="${LOG_HOME}/all.log" filePattern ="${LOG_HOME}/$${date:yyyy-MM}/all-%d{yyyy-MM-dd}-%i.log.gz" > <PatternLayout > <pattern > %d %p %C{} [%t] %m%n</pattern > </PatternLayout > <Policies > <SizeBasedTriggeringPolicy size ="100 MB" /> <TimeBasedTriggeringPolicy /> </Policies > <DefaultRolloverStrategy max ="100" /> </RollingFile > <RollingFile name ="debugFileAppender" fileName ="${LOG_HOME}/debug.log" filePattern ="${LOG_HOME}/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log.gz" > <Filters > <ThresholdFilter level ="info" onMatch ="DENY" onMismatch ="NEUTRAL" /> </Filters > <PatternLayout > <pattern > %d %p %C{} [%t] %m%n</pattern > </PatternLayout > <Policies > <SizeBasedTriggeringPolicy size ="100 MB" /> <TimeBasedTriggeringPolicy /> </Policies > <DefaultRolloverStrategy max ="100" /> </RollingFile > <RollingFile name ="infoFileAppender" fileName ="${LOG_HOME}/info.log" filePattern ="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz" > <Filters > <ThresholdFilter level ="warn" onMatch ="DENY" onMismatch ="NEUTRAL" /> </Filters > <PatternLayout > <pattern > %d %p %C{} [%t] %m%n</pattern > </PatternLayout > <Policies > <SizeBasedTriggeringPolicy size ="100 MB" /> <TimeBasedTriggeringPolicy interval ="1" modulate ="true" /> </Policies > </RollingFile > <RollingFile name ="warnFileAppender" fileName ="${LOG_HOME}/warn.log" filePattern ="${LOG_HOME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz" > <Filters > <ThresholdFilter level ="error" onMatch ="DENY" onMismatch ="NEUTRAL" /> </Filters > <PatternLayout > <pattern > %d %p %C{} [%t] %m%n</pattern > </PatternLayout > <Policies > <SizeBasedTriggeringPolicy size ="100 MB" /> <TimeBasedTriggeringPolicy /> </Policies > <DefaultRolloverStrategy max ="100" /> </RollingFile > <RollingFile name ="errorFileAppender" fileName ="${LOG_HOME}/error.log" filePattern ="${LOG_HOME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz" > <PatternLayout > <pattern > %d %p %C{} [%t] %m%n</pattern > </PatternLayout > <Policies > <SizeBasedTriggeringPolicy size ="100 MB" /> <TimeBasedTriggeringPolicy /> </Policies > <DefaultRolloverStrategy max ="100" /> </RollingFile > <RollingFile name ="errorJsonAppender" fileName ="${LOG_HOME}/error-json.log" filePattern ="${LOG_HOME}/error-json-%d{yyyy-MM-dd}-%i.log.gz" > <JSONLayout compact ="true" eventEol ="true" locationInfo ="true" /> <Policies > <SizeBasedTriggeringPolicy size ="100 MB" /> <TimeBasedTriggeringPolicy interval ="1" modulate ="true" /> </Policies > </RollingFile > </Appenders > <Loggers > <Root level ="debug" > <AppenderRef ref ="allFileAppender" level ="all" /> <AppenderRef ref ="consoleAppender" level ="debug" /> <AppenderRef ref ="debugFileAppender" level ="debug" /> <AppenderRef ref ="infoFileAppender" level ="info" /> <AppenderRef ref ="warnFileAppender" level ="warn" /> <AppenderRef ref ="errorFileAppender" level ="error" /> <AppenderRef ref ="errorJsonAppender" level ="error" /> </Root > <Logger name ="org.springframework" level ="info" /> <Logger name ="druid.sql.Statement" level ="warn" /> <Logger name ="com.mybatis" level ="warn" /> </Loggers > </Configuration >
同樣也可以通過appender和patternLayout等標籤來設置日誌的輸出。
然後在application.properties中加上log4j2的配置
1 logging.config =classpath:log4j2.xml
測試一下,可以通過Lombok的@Log4j2注釋使用日誌
1 2 3 4 5 6 7 8 9 @SpringBootApplication @Log4j2 public class Log4j2UsageApplication { public static void main (String[] args) { SpringApplication.run(Log4j2UsageApplication.class, args); log.warn("this is form log4j2." ); } }
同時按照log4j2.xml的配置對應的目錄下可以找到按照日誌級別分類的記錄