SpringBoot 使用Logback日志框架

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: SpringBoot 使用Logback日志框架

1. 前言


项目中日志系统是必不可少的,目前比较流行的日志框架有log4j、logback等,可能大家还不知道,这两个框架的作者是同一个人,Logback旨在作为流行的log4j项目的后续版本,从而恢复log4j离开的位置。另外 slf4j(Simple Logging Facade for Java) 则是一个日志门面框架,提供了日志系统中常用的接口,logback 和 log4j 则对slf4j 进行了实现。我们本文将讲述如何在spring boot 中应用 logback+slf4j实现日志的记录。


2. 为什么使用logback


Logback 是log4j 框架的作者开发的新一代日志框架,它效率更高、能够适应诸多的运行环境,同时天然支持SLF4J


Logback的定制性更加灵活,同时也是spring boot的内置日志框架


3. logback构成部分


logback-core:核心代码模块


logback-classic:log4j的一个改良版本,同时实现了slf4j的接口,这样如果之后要切换其他日志组件也是一件很容易的事


logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能


4. 开始使用


spring-boot-starter中包含了logback的依赖,如果使用springboot工程,则不需要在进行额外的引入。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.7.2</version>
</dependency>


logback详细配置信息,可根据实际需要进行一定的删减处理

# 默认名称不用指定配置,修改文件名后需在配置中指定文件
#logging:
#  config: classpath:logback-spring.xml


logback-spring.xml,放在resources下

<?xml version="1.0" encoding="UTF-8"?>
<!--
scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。
默认值为false。
-->
<!--
Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用logback-spring.xml,而不是logback.xml),
命名为logback-spring.xml的日志配置文件,spring boot可以为它添加一些spring boot特有的配置项。
上面是默认的命名规则,并且放在src/main/resources下面即可
如果你即想完全掌控日志配置,但又不想用logback.xml作为Logback配置的名字,可以通过logging.config属性指定自定义的名字
logging.config=classpath:logging-config.xml
虽然一般并不需要改变配置文件的名字,但是如果你想针对不同运行时Profile使用不同的日志配置,这个功能会很有用。
一般不需要这个属性,而是直接在logback-spring.xml中使用springProfile配置,不需要logging.config指定不同环境使用不同配置文件
-->
<configuration scan="true" scanPeriod="60 seconds" debug="true">
    <!--
    此base.xml 在springboot中,包含了default。
    Spring Boot的日志系统预先定义了一些系统变量:
    base.xml内容如下:
        <included>
            <include resource="org/springframework/boot/logging/logback/defaults.xml" />
            <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
            <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
            <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
            <root level="INFO">
                <appender-ref ref="CONSOLE" />
                <appender-ref ref="FILE" />
            </root>
        </included>
        ${PID},当前进程ID
        ${LOG_FILE},Spring Boot配置文件中logging.file的值
        ${LOG_PATH}, Spring Boot配置文件中logging.path的值
        同时默认情况下包含另个appender——一个是控制台,一个是文件,
        分别定义在console-appender.xml和file-appender.xml中。
        同时对于应用的日志级别也可以通过application.properties进行定义
        logging.level.org.springframework.web=DEBUG
        logging.level.org.hibernate=ERROR
    -->
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <!--
        设置变量: <property> 用来定义变量值的标签,<property> 有两个属性name和value;
        name: 变量的名称
        value: 的值时变量定义的值。
        通过<property>定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
    -->
    <!-- 最大保存时间 15天-->
    <property name="maxHistory" value="15"/>
    <property name="maxFileSize" value="50MB"/>
    <property name="totalSizeCap" value="500MB"/>
    <property name="APP_NAME" value="log-kernel"/>
    <property name="log.path" value="./logs"/>
    <!--
        <timestamp>
        两个属性:
        key: 标识此<timestamp> 的名字;
        datePattern: 设置将当前时间(解析配置文件的时间)转换为字符串的模式,遵循java.txt.SimpleDateFormat的格式。
    -->
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
    <!--
        每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用设置成其他名字,
        用于区分不同应用程序的记录。一旦设置,不能修改,可以通过%contextName来打印日志上下文名称。
    -->
    <contextName>${APP_NAME}</contextName>
    <!--
        appender用来格式化日志输出节点,有俩个属性name和class,class用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略。
        Logback使用appender来定义日志输出,在开发过程中最常用的是将日志输出到控制台
    -->
    <!--输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息
            ThresholdFilter为系统定义的拦截器,例如我们用ThresholdFilter来过滤掉ERROR级别以下的日志不输出到文件中。
            如果不用记得注释掉,不然你控制台会发现没日志~
        -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>info</level>
        </filter>
        <!--
            encoder>表示对日志进行编码:
            %d{HH:mm:ss.SSS}——日志输出时间
            %thread——输出日志的进程名字,这在Web应用以及异步任务处理中很有用
            %-5level——日志级别,并且使用5个字符靠左对齐
            %logger{36}——日志输出者的名字
            %msg——日志消息
            %n——平台的换行符
        -->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId},%X{spanId}] %logger{50} - %msg%n
            </pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--输出到文件
        另一种常见的日志输出到文件,随着应用的运行时间越来越长,日志也会增长的越来越多,将他们输出到同一个文件并非一个好办法。
        RollingFileAppender用于切分文件日志.其中重要的是rollingPolicy的定义
    -->
    <!-- DEBUG 日志 -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/log_debug.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志归档 定义了日志的切分方式——把每一天的日志归档到一个文件中 -->
            <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${maxFileSize}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数 表示只保留最近15天的日志,以防止日志填满整个磁盘空间-->
            <maxHistory>${maxHistory}</maxHistory>
            <!--<totalSizeCap>1GB</totalSizeCap>用来指定日志文件的上限大小,例如设置为1GB的话,那么到了这个值,就会删除旧的日志-->
            <totalSizeCap>${totalSizeCap}</totalSizeCap>
        </rollingPolicy>
        <!-- 此日志文件只记录debug级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--INFO 日志 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/log_info.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId},%X{spanId}] %logger{50} - %msg%n
            </pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${maxFileSize}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>${maxHistory}</maxHistory>
            <totalSizeCap>${totalSizeCap}</totalSizeCap>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- WARN 日志 -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/log_warn.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId},%X{spanId}] %logger{50} - %msg%n
            </pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${maxFileSize}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>${maxHistory}</maxHistory>
            <totalSizeCap>${totalSizeCap}</totalSizeCap>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- ERROR 日志 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/log_error.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId},%X{spanId}] %logger{50} - %msg%n
            </pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${maxFileSize}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>${maxHistory}</maxHistory>
            <totalSizeCap>${totalSizeCap}</totalSizeCap>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--
        据不同环境(prod:生产环境,test:测试环境,dev:开发环境)来定义不同的日志输出,
        在 logback-spring.xml中使用 springProfile 节点来定义.
        application.properties增加环境选择的配置active: dev
        # 选择加载不同环境的配置文件 dev pre prod
        spring.profiles.active=dev
    -->
    <!--开发环境:打印控制台-->
    <springProfile name="dev">
        <root level="info">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>
    <!--生产环境:输出到文件-->
    <springProfile name="prod,test">
        <root level="info">
            <appender-ref ref="DEBUG_FILE"/>
            <appender-ref ref="INFO_FILE"/>
            <appender-ref ref="ERROR_FILE"/>
            <appender-ref ref="WARN_FILE"/>
        </root>
    </springProfile>
    <!--
        <logger>
            用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。<loger>仅有一个name属性,一个可选的level和一个可选的addtivity属性。
            name: 用来指定受此loger约束的某一个包或者具体的某一个类。
            level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,还有一个特俗值INHERITED或者同义词NULL`,代表强制执行上级的级别。 如果未设置此属性,那么当前loger将会继承上级的级别。
            addtivity: 是否向上级loger传递打印信息。默认是true。
    -->
    <!--
    <root>也是<loger>元素,但是它是根loger。只有一个level属性,应为已经被命名为"root".
    level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
           不能设置为INHERITED或者同义词NULL。 默认是DEBUG。
    <loger>和<root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger。
    -->
    <root level="info">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="DEBUG_FILE"/>
        <appender-ref ref="INFO_FILE"/>
        <appender-ref ref="ERROR_FILE"/>
        <appender-ref ref="WARN_FILE"/>
    </root>
    <!--
    带有loger的配置,不指定级别,不指定appender,<logger name="logback" />将控制logback包下的所有类的日志的打印,
    但是并没用设置打印级别,所以继承他的上级<root>的日志级别.没有设置addtivity,默认为true,
    将此loger的打印信息向上级传递; 没有设置appender,此loger本身不打印任何信息。
    当执行logback.LogbackDemo类的main方法时,因为LogbackDemo 在包logback中,所以首先执行<logger name="logback" />,将级别为“DEBUG”及大于“DEBUG”的日志信息传递给root,本身并不打印;
     root接到下级传递的信息,交给已经配置好的名为“STDOUT”的appender处理,“STDOUT”appender将信息打印到控制台;
    -->
    <!-- logback为java中的包 -->
    <logger name="logback"/>
    <!--
        <logger name="logback.LogbackDemo" level="INFO" additivity="false">控制logback.LogbackDemo类的日志打印,打印级别为“INFO”;
        additivity属性为false,表示此loger的打印信息不再向上级传递, 指定了名字为“STDOUT”的appender。
        当然如果你把additivity="false"改成additivity="true"的话,
        就会打印两次,因为打印信息向上级传递,logger本身打印一次,root接到后又打印一次。
    -->
    <!--logback.LogbackDemo:类的全路径 -->
    <logger name="logback.LogbackDemo" level="INFO" additivity="false">
        <appender-ref ref="CONSOLE"/>
    </logger>
</configuration>
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
1月前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
279 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
1月前
|
Java 中间件
SpringBoot入门(6)- 添加Logback日志
SpringBoot入门(6)- 添加Logback日志
76 5
|
29天前
|
Java 中间件
SpringBoot入门(6)- 添加Logback日志
SpringBoot入门(6)- 添加Logback日志
35 1
|
1月前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
47 1
|
2月前
|
Java 程序员 API
Android|集成 slf4j + logback 作为日志框架
做个简单改造,统一 Android APP 和 Java 后端项目打印日志的体验。
127 1
|
8天前
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
|
2月前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
313 3
|
18天前
|
存储 监控 安全
什么是事件日志管理系统?事件日志管理系统有哪些用处?
事件日志管理系统是IT安全的重要工具,用于集中收集、分析和解释来自组织IT基础设施各组件的事件日志,如防火墙、路由器、交换机等,帮助提升网络安全、实现主动威胁检测和促进合规性。系统支持多种日志类型,包括Windows事件日志、Syslog日志和应用程序日志,通过实时监测、告警及可视化分析,为企业提供强大的安全保障。然而,实施过程中也面临数据量大、日志管理和分析复杂等挑战。EventLog Analyzer作为一款高效工具,不仅提供实时监测与告警、可视化分析和报告功能,还支持多种合规性报告,帮助企业克服挑战,提升网络安全水平。
|
2月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1695 14
|
1月前
|
存储 监控 安全
什么是日志管理,如何进行日志管理?
日志管理是对IT系统生成的日志数据进行收集、存储、分析和处理的实践,对维护系统健康、确保安全及获取运营智能至关重要。本文介绍了日志管理的基本概念、常见挑战、工具的主要功能及选择解决方案的方法,强调了定义管理目标、日志收集与分析、警报和报告、持续改进等关键步骤,以及如何应对数据量大、安全问题、警报疲劳等挑战,最终实现日志数据的有效管理和利用。