在spring boot应用中启用log4j2
Spring boot的默认日志实现是使用的 Logback,默认日志级别是Info.
所以,最先一步就是排除掉spring boot带的日志实现.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
使用spring boot starter时,会自动引入spring-boot-starter-logging,其内容会包括:
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.13.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.30</version>
<scope>compile</scope>
</dependency>
</dependencies>
接着导入log4j 2的目标版本
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
日志配置
在classpath下配置一个名为log4j2.xml的配置文件,spring会检测到并导入.
也可以在application.yaml文件中指定:
logging:
config: classpath:log4j2.xml
我的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration monitorInterval="5">
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--变量配置-->
<Properties>
<!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %m:日志消息,%n是换行符-->
<!-- %c 输出类详情 %M 输出方法名 %pid 输出pid %line 日志在哪一行被打印 -->
<!-- %logger{80} 表示 Logger 名字最长80个字符 -->
<!-- value="${LOCAL_IP_HOSTNAME} %date [%p] %C [%thread] pid:%pid line:%line %throwable %c{10} %m%n"/>-->
<property name="LOG_PATTERN"
value="%highlight{%date [%-5p] [TD:%X{traceId}] %c{9.9./} %M [%thread] pid:%pid-%line %throwable %m %n}{FATAL=red, ERROR=red, WARN=yellow,TRACE=blue}"/>
<!-- 读取application.yaml文件中设置的日志路径 logging.file.path-->
<property name="FILE_PATH" value="${sys:LOG_PATH}"/>
<property name="FILE_STORE_MAX" value="10MB"/>
<property name="FILE_WRITE_INTERVAL" value="1"/>
<property name="LOG_MAX_HISTORY" value="60"/>
<!-- <property name="CONSOLE_LOG_PATTERN" value="%highlight{[%p] %-d{yyyy-MM-dd HH:mm:ss} –> %l%n[message] %msg%n}{FATAL=red, ERROR=red, WARN=yellow, INFO=cyan, DEBUG=cyan,TRACE=blue}"/>-->
<!-- value="%r [%t] %p %c %x - %m%n"/>–>-->
<property name="CONSOLE_LOG_PATTERN"
value="%highlight{%date [%-5p] [TD:%X{traceId}] %c{9.9./} %M [%thread] pid:%pid-%line %throwable %m %n}{FATAL=red, ERROR=red, WARN=yellow,TRACE=blue}"/>
</Properties>
<appenders>
<!-- <SMTP name="Mail" subject="Error Log" to="23333333@qq.com" from="666666@qq.com"-->
<!-- smtpHost="smtp.qq.com" smtpDebug="true" smtpProtocol="smtps" smtpUsername="666666@qq.com"-->
<!-- smtpPassword="giyzthpqvzbhbber" smtpPort="465" bufferSize="50" >-->
<!-- </SMTP>-->
<!-- 控制台输出 -->
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="${CONSOLE_LOG_PATTERN}"/>
<!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</console>
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingRandomAccessFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log"
filePattern="${FILE_PATH}/INFO-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
<TimeBasedTriggeringPolicy interval="${FILE_WRITE_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${FILE_STORE_MAX}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy max="${LOG_MAX_HISTORY}"/>
</RollingRandomAccessFile>
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingRandomAccessFile name="RollingFileDebug" fileName="${FILE_PATH}/debug.log"
filePattern="${FILE_PATH}/DEBUG-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
<TimeBasedTriggeringPolicy interval="${FILE_WRITE_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${FILE_STORE_MAX}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy max="${LOG_MAX_HISTORY}"/>
</RollingRandomAccessFile>
<!-- 这个会打印出所有的warn及以上级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingRandomAccessFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log"
filePattern="${FILE_PATH}/WARN-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
<TimeBasedTriggeringPolicy interval="${FILE_WRITE_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${FILE_STORE_MAX}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy max="${LOG_MAX_HISTORY}"/>
</RollingRandomAccessFile>
<!-- 这个会打印出所有的error及以上级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingRandomAccessFile name="RollingFileError" fileName="${FILE_PATH}/error.log"
filePattern="${FILE_PATH}/ERROR-%d{yyyy-MM-dd}_%i.log.gz">
<!--只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
<TimeBasedTriggeringPolicy interval="${FILE_WRITE_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${FILE_STORE_MAX}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy max="${LOG_MAX_HISTORY}"/>
</RollingRandomAccessFile>
</appenders>
<!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
<!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
<loggers>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<logger name="org.mybatis" level="info" additivity="false">
<AppenderRef ref="Console"/>
</logger>
<!--监控系统信息-->
<!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
<Logger name="org.springframework" level="info" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<!-- <Logger name="mail" level="error" additivity="false">-->
<!-- <AppenderRef ref="Mail"/>-->
<!-- </Logger>-->
<AsyncLogger name="AsyncLogger" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFileDebug"/>
<AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="RollingFileError"/>
</AsyncLogger>
<root level="trace">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileDebug"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
<!-- <appender-ref ref="Mail"/>-->
</root>
</loggers>
</configuration>
需要特别说明的一些点:
<property name="CONSOLE_LOG_PATTERN"
value="%highlight{%date [%-5p] [TD:%X{traceId}] %c{9.9./} %M [%thread] pid:%pid-%line %throwable %m %n}{FATAL=red, ERROR=red, WARN=yellow,TRACE=blue}"/>
</Properties>
`%highlight{输出的内容}{FATAL=red, ERROR=red, WARN=yellow,TRACE=blue}`高亮输出,第二个大括号中指定不同级别日志的颜色.
更多详细的设置可以参考官网.
ps:颜色设置在windows平台上无法正常使用的情况:
在启动时加入参数-Dlog4j.skipJansi=false
IDEA中如下设置:
java -jar命令使用时:
java -jar app.jar -Dlog4j.skipJansi=false
读取application.yml中的配置
<property name="FILE_PATH" value="${sys:LOG_PATH}"/>
application.yml文件内容
logging:
config: classpath:log4j2.xml
file:
path: ${LOG_HOME_PATH:/logs/java}/${spring.application.name}
sys:LOG_PATH 的值即为${LOG_HOME_PATH:/logs/java}/${spring.application.name};
这样就可以让不同项目的日志根据项目名将日志存放在不同的地方.
通过Java应用的system property来设置和读取值
`sys:var`取值的方式其实是取的jvm的property.可以在代码中使用`System.setProperty(key,val)`设置,然后在log4j2.xml中使用
`sys:key`获取值.