目录
1、参考资料
2、发展
3、Log4j
4、SLF4J
5、Logback
6、Log4j2
1、参考资料
http://t.csdn.cn/pU3ti
http://t.csdn.cn/2spxn
2、发展
Java的日志发展有很多年历史,最早的时候,是使用System.out
和System.err
,这是最早的日志记录方式,但是不灵活也不可配置,要么就是全部打印,要么就是全部不打印,没有一个统一的日志级别。
在1996年初,欧洲安全电子市场项目组决定编写自己的跟踪API
,最后该API
演变为Log4j
,Log4j
日志软件包一经推出就备受欢迎,这里必须要提到一个人,就是Log4j
的主要贡献者——Ceki Gülcü。
后来Apache基金会说服Ceki Gülcü将log4f贡献到Apache并加入Apache参与维护,Log4j的火爆,让Log4j一度成为业内日志标杆。Apache基金会还曾经建议Sun
引入Log4j
到java
的标准库中,但是sun
拒绝了。
sun有自己的小心思,2002年2月JDK1.4发布,Sun推出了自己的日志标准库JUL(Java Util Logging)
,其实是照着Log4j抄的,而且还没抄好,还是在JDK1.5以后性能和可用性才有所提升。由于Log4j比JUL好用,并且成熟,所以Log4j在选择上占据了一定的优势。
2002年8月Apache推出了JCL(Jakarta Commons Logging)
,也就是日志抽象层,支持运行时动态加载日志组件的实现,当然也提供一个默认实现Simple Log
(在 ClassLoader 中进行查找,如果能找到Log4j则默认使用log4j实现,如果没有则使用JUL实现,再没有则使用JCL内部提供的 Simple Log实现)。
2006年巨佬Ceki
因为一些原因离开了Apache组织,之后Ceki觉得JCL不好用,于是自己撸出一个新工程,也就是一套新日志接口(有得也叫日志门面):Slf4j(Simple Logging Facade for Java)
,很明显Slf4j是对标JCL,后面也证明了Slf4j比JCL更优秀。
巨佬Ceki提供了一系列的桥接包来帮助Slf4j接口与其他日志库建立关系,这种方式称桥接设计模式。代码使用Slf4j接口,就可以实现日志的统一标准化,后续如果想要更换日志实现,只需引入Slf4j与相关的桥接包,再引入具体的日志标准库即可。
由于使用Slf4j
,需要一次桥接包,也就是之前的日志产品都不是正统的Slf4j
的实现,因此,2006年,出自Ceki Gülcü之手的日志产品Logback
应运而生。
在2012年,Apache
直接推出新项目,不是Log4j1.x
升级,而是新项目Log4j2
,因为Log4j2
是完全不兼容Log4j1.x
的。
现如今Java日志被分为两大体系:Commons Logging和SLF4J。
3、Log4j
1、导入依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2、配置文件log4j.properties
# 控制台输出配置
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
# 文件输出配置
log4j.appender.A = org.apache.log4j.DailyRollingFileAppender
#指定日志的输出路径
log4j.appender.A.File = E:/log.txt
log4j.appender.A.Append = true
log4j.appender.A.Threshold = DEBUG
#使用自定义日志格式化器
log4j.appender.A.layout = org.apache.log4j.PatternLayout
#指定日志的输出格式
log4j.appender.A.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
#指定日志的文件编码
log4j.appender.A.encoding=UTF-8
#指定日志的输出级别与输出端
log4j.rootLogger=DEBUG,Console,A
3、测试
package com.log.controller;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class indexController {
private static Logger logger = Logger.getLogger(indexController.class);
@GetMapping("/")
public Object index() {
logger.info("访问了首页");
return "首页";
}
@GetMapping("/hello")
public Object hello() {
logger.info("访问了欢迎页");
return "欢迎";
}
}
4、在浏览器访问,控制台输出结果如下
5、log.txt文件内容如下
4、SLF4J
SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。
5、Logback
1、导入依赖
<!--实际上spring boot默认使用的就是SLF4J+Logback的组合,如果不需要更改其他的日志系统,则无需多余的配置。由于spring boot项目一会引用spring-boot-starter或者spring-boot-starter-web,而这两个依赖就包含了Logback,所以无需添加额外依赖。-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!--因为会使用到@SLF4j注解,所以需要导入Lombok的包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2、配置文件
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。-->
<!--debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<!--scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。-->
<configuration debug="false" scan="false">
<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue="springboot"/>
<property name="LOG_HOME" value="logs/${spring.application.name}"/>
<!-- 日志格式和颜色渲染 -->
<!-- 彩色日志依赖的渲染类 -->
<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>debug</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--把debug日志输出-->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/debug.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 记录错误日志到单独文件 error.log -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 记录错误日志到单独文件 info.log -->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/info.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 下面配置一些第三方包的日志过滤级别,用于避免刷屏 -->
<logger name="org.springframework.web" level="INFO"/>
<!-- Log日志级别从高到低排序
ERROR:用户程序报错,必须解决的时候使用此级别打印日志
WARN:警告,不会影响程序的运行,但是值得注意。
INFO:一般处理业务逻辑的时候使用,就跟 system.err打印一样
DEBUG:一般放于程序的某个关键点的地方,用于打印一个变量值或者一个方法返回的信息之类的信息
TRACE:一般不会使用,在日志里边也不会打印出来,好像是很低的一个日志级别。
-->
<!-- 定义本地环境日志级别 -->
<springProfile name="local">
<logger name="com.log" level="DEBUG"/><!-- 定义将com.log包下的最低级别日志信息 -->
<root level="INFO"><!-- 系统全局日志输出最低级别,但不包括com.log包 -->
<appender-ref ref="console"/>
</root>
</springProfile>
<!-- 定义测试环境日志级别 -->
<springProfile name="dev">
<logger name="com.log" level="DEBUG"/>
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
</root>
</springProfile>
<!-- 定义线上环境日志级别 -->
<springProfile name="online">
<root level="INFO">
<appender-ref ref="error"/>
</root>
</springProfile>
</configuration>
application-dev.yml
logging:
config: classpath:logback-spring.xml
application.yml
#这里使用开发环境,当然,也可以使用本地环境,但是本地环境不会把日志输出到文件中
spring:
profiles:
active: dev
3、测试
package com.log.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class LogbackController {
@GetMapping("/")
public Object index() {
log.debug("访问了首页");
return "首页";
}
@GetMapping("/hello")
public Object hello() {
log.info("访问了欢迎页");
return "欢迎";
}
}
4、结果
控制台
文件
5、常用配置
以下是网上常用的配置
配置一
<?xml version="1.0" encoding="UTF-8"?>
<!--scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。-->
<!--debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<!--scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 全局变量 -->
<!--日志文件保存路径-->
<springProperty scope="context" name="logPath" source="logging.file.path" defaultValue="logs"/>
<!--应用名称-->
<springProperty scope="context" name="appName" source="spring.application.name" defaultValue="springBoot"/>
<!-- 通用日志文件输出appender -->
<appender name="COMMON_FILE_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。
-->
<File>${logPath}/${appName}.log</File>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${logPath}/${appName}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--只保留最近30天的日志-->
<maxHistory>30</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<!--日志输出编码格式化-->
<encoder>
<charset>UTF-8</charset>
<!--<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>-->
<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
</encoder>
</appender>
<!-- 开发环境,多个使用逗号隔开,本地开发环境只输出控制台日志-->
<springProfile name="dev">
<!-- 本地开发控制栏彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<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}}"/>
<!-- Console 输出设置 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</layout>
</appender>
<!-- 控制台不打印tomcat启动过程中的JAR包扫描警告 -->
<logger name="o.a.tomcat.util.scan.StandardJarScanner" level="ERROR" additivity="false">
<appender-ref ref="CONSOLE"/>
</logger>
<!--指定最基础的日志输出级别-->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<!-- 测试环境,多个使用逗号隔开,测试环境输出INFO级别日志,只以文件形式输出-->
<springProfile name="test">
<logger name="com.xf" level="INFO" additivity="false">
<appender-ref ref="COMMON_FILE_LOG"/>
</logger>
<root level="INFO">
<appender-ref ref="COMMON_FILE_LOG"/>
</root>
</springProfile>
<!-- 生产环境,多个使用逗号隔开,生产环境输出ERROR级别日志,只以文件形式输出-->
<springProfile name="prod">
<root level="ERROR">
<appender-ref ref="COMMON_FILE_LOG"/>
</root>
</springProfile>
</configuration>
配置二
<?xml version="1.0" encoding="UTF-8"?>
<!--scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。-->
<!--debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<!--scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。-->
<configuration debug="false" scan="false">
<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue="springboot"/>
<property name="LOG_HOME" value="logs/${spring.application.name}"/>
<!-- 日志格式和颜色渲染 -->
<!-- 彩色日志依赖的渲染类 -->
<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>debug</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--把debug日志输出-->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/debug.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 记录错误日志到单独文件 error.log -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 记录错误日志到单独文件 info.log -->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/info.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 下面配置一些第三方包的日志过滤级别,用于避免刷屏 -->
<logger name="org.springframework.web" level="INFO"/>
<!-- Log日志级别从高到低排序
ERROR:用户程序报错,必须解决的时候使用此级别打印日志
WARN:警告,不会影响程序的运行,但是值得注意。
INFO:一般处理业务逻辑的时候使用,就跟 system.err打印一样
DEBUG:一般放于程序的某个关键点的地方,用于打印一个变量值或者一个方法返回的信息之类的信息
TRACE:一般不会使用,在日志里边也不会打印出来,好像是很低的一个日志级别。
-->
<!-- 定义本地环境日志级别 -->
<springProfile name="local">
<logger name="com.xf" level="DEBUG"/><!-- 定义将com.xf包下的最低级别日志信息 -->
<root level="INFO"><!-- 系统全局日志输出最低级别,但不包括com.xf包 -->
<appender-ref ref="console"/>
</root>
</springProfile>
<!-- 定义测试环境日志级别 -->
<springProfile name="dev">
<logger name="com.xf" level="DEBUG"/>
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
</root>
</springProfile>
<!-- 定义线上环境日志级别 -->
<springProfile name="online">
<root level="INFO">
<appender-ref ref="error"/>
</root>
</springProfile>
</configuration>
配置三
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<!--引用默认日志配置-->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!--使用默认的控制台日志输出实现-->
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="springBoot"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/>
<!--LogStash访问host-->
<springProperty name="LOG_STASH_HOST" scope="context" source="logstash.host" defaultValue="localhost"/>
<!--DEBUG日志输出到文件-->
<appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--输出DEBUG以上级别日志-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder>
<!--设置为默认的文件日志格式-->
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--设置文件命名格式-->
<fileNamePattern>${LOG_FILE_PATH}/debug/${APP_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!--设置日志文件大小,超过就重新生成文件,默认10M-->
<maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
<!--日志文件保留天数,默认30天-->
<maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
</rollingPolicy>
</appender>
<!--ERROR日志输出到文件-->
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--只输出ERROR级别的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<!--设置为默认的文件日志格式-->
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--设置文件命名格式-->
<fileNamePattern>${LOG_FILE_PATH}/error/${APP_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!--设置日志文件大小,超过就重新生成文件,默认10M-->
<maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
<!--日志文件保留天数,默认30天-->
<maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
</rollingPolicy>
</appender>
<!--DEBUG日志输出到LogStash-->
<appender name="LOG_STASH_DEBUG" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<destination>${LOG_STASH_HOST}:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>Asia/Shanghai</timeZone>
</timestamp>
<!--自定义日志输出格式-->
<pattern>
<pattern>
{
"project": "mall",
"level": "%level",
"service": "${APP_NAME:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger",
"message": "%message",
"stack_trace": "%exception{20}"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<!--ERROR日志输出到LogStash-->
<appender name="LOG_STASH_ERROR" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<destination>${LOG_STASH_HOST}:4561</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>Asia/Shanghai</timeZone>
</timestamp>
<!--自定义日志输出格式-->
<pattern>
<pattern>
{
"project": "mall",
"level": "%level",
"service": "${APP_NAME:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger",
"message": "%message",
"stack_trace": "%exception{20}"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<!--业务日志输出到LogStash-->
<appender name="LOG_STASH_BUSINESS" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${LOG_STASH_HOST}:4562</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>Asia/Shanghai</timeZone>
</timestamp>
<!--自定义日志输出格式-->
<pattern>
<pattern>
{
"project": "xxx",
"level": "%level",
"service": "${APP_NAME:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger",
"message": "%message",
"stack_trace": "%exception{20}"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<!--接口访问记录日志输出到LogStash-->
<appender name="LOG_STASH_RECORD" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${LOG_STASH_HOST}:4563</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>Asia/Shanghai</timeZone>
</timestamp>
<!--自定义日志输出格式-->
<pattern>
<pattern>
{
"project": "xxx",
"level": "%level",
"service": "${APP_NAME:-}",
"class": "%logger",
"message": "%message"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<!--控制框架输出日志-->
<logger name="org.slf4j" level="INFO"/>
<logger name="springfox" level="INFO"/>
<logger name="io.swagger" level="INFO"/>
<logger name="org.springframework" level="INFO"/>
<logger name="org.hibernate.validator" level="INFO"/>
<logger name="com.xf.common.log.WebLogAspect" level="DEBUG">
<appender-ref ref="LOG_STASH_RECORD"/>
</logger>
<logger name="com.xf" level="DEBUG">
<appender-ref ref="LOG_STASH_BUSINESS"/>
</logger>
<root>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE_DEBUG"/>
<appender-ref ref="FILE_ERROR"/>
<appender-ref ref="LOG_STASH_DEBUG"/>
<appender-ref ref="LOG_STASH_ERROR"/>
</root>
</configuration>
6、Log4j2
官网:https://logging.apache.org/log4j/2.x/
1、导入依赖
<!--在spring boot项目中,不导入web依赖几乎是不可能的,而web依赖包含了Logback,这会与我们的log4j2产生冲突所以我们需要排除掉它-->
<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>
<!--导入log4j2依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2、配置文件
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。-->
<!--debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<!--scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。-->
<configuration debug="false" scan="false">
<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue="springboot"/>
<property name="LOG_HOME" value="logs/${spring.application.name}"/>
<!-- 日志格式和颜色渲染 -->
<!-- 彩色日志依赖的渲染类 -->
<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>debug</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--把debug日志输出-->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/debug.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 记录错误日志到单独文件 error.log -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 记录错误日志到单独文件 info.log -->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/info.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<fileNamePattern>${LOG_HOME}/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志文件最大尺寸 -->
<maxFileSize>100MB</maxFileSize>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 下面配置一些第三方包的日志过滤级别,用于避免刷屏 -->
<logger name="org.springframework.web" level="INFO"/>
<!-- Log日志级别从高到低排序
ERROR:用户程序报错,必须解决的时候使用此级别打印日志
WARN:警告,不会影响程序的运行,但是值得注意。
INFO:一般处理业务逻辑的时候使用,就跟 system.err打印一样
DEBUG:一般放于程序的某个关键点的地方,用于打印一个变量值或者一个方法返回的信息之类的信息
TRACE:一般不会使用,在日志里边也不会打印出来,好像是很低的一个日志级别。
-->
<!-- 定义本地环境日志级别 -->
<springProfile name="local">
<logger name="com.log" level="DEBUG"/><!-- 定义将com.xf包下的最低级别日志信息 -->
<root level="INFO"><!-- 系统全局日志输出最低级别,但不包括com.xf包 -->
<appender-ref ref="console"/>
</root>
</springProfile>
<!-- 定义测试环境日志级别 -->
<springProfile name="dev">
<logger name="com.log" level="DEBUG"/>
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
</root>
</springProfile>
<!-- 定义线上环境日志级别 -->
<springProfile name="online">
<root level="INFO">
<appender-ref ref="error"/>
</root>
</springProfile>
</configuration>
application.yml
logging:
config: classpath:log4j2.xml
3、测试
package com.log.controller;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Log4j2
public class Log4j2Controller {
@GetMapping("/")
public Object index() {
log.error("error");
log.warn("warning");
log.info("info"); // 默认的日志级别信息
log.debug("debug");
log.trace("trace"); // 追踪信息
return "首页";
}
}
4、结果
控制台
D盘log文件