Java日志框架

目录

1、参考资料
2、发展
3、Log4j
4、SLF4J
5、Logback
6、Log4j2

1、参考资料

http://t.csdn.cn/pU3ti
http://t.csdn.cn/2spxn

2、发展

Java的日志发展有很多年历史,最早的时候,是使用System.outSystem.err,这是最早的日志记录方式,但是不灵活也不可配置,要么就是全部打印,要么就是全部不打印,没有一个统一的日志级别。

在1996年初,欧洲安全电子市场项目组决定编写自己的跟踪API,最后该API演变为Log4jLog4j日志软件包一经推出就备受欢迎,这里必须要提到一个人,就是Log4j的主要贡献者——Ceki Gülcü

后来Apache基金会说服Ceki Gülcü将log4f贡献到Apache并加入Apache参与维护,Log4j的火爆,让Log4j一度成为业内日志标杆。Apache基金会还曾经建议Sun引入Log4jjava的标准库中,但是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、在浏览器访问,控制台输出结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMSIqK3i-1655171893281)(docs/imgs/1655109152722.png)]

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>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8xIFjKQZ-1655171893282)(docs/imgs/1655110049201.png)]


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、结果

控制台

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h18o6imD-1655171893282)(docs/imgs/1655171206500.png)]

文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ns7rTqzw-1655171893283)(docs/imgs/1655171336618.png)]

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文件
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值