Logback-日志文件按日期切分解决方案_logback日志切割-程序员宅基地

技术标签: java  logback  

Logback,是一个开源的日志组件,同样也是由log4j创始人设计。天然支持SLF4J(Simple Logging Facade For Java)。在Spring Boot中,使用Logback是最优的选择,可使用logback-spring.xml进行配置使用。

实际项目中经常需要通过日志文件来定位,不同于本地测试开发环境,线上的日志文件如果不做按日期切割整理就会比较乱,而且打开日志文件需要很久。

本文旨在提供多种实际可用的日志配置文件模板,便捷可用。

一、Logback使用

logback有5种级别,分别是TRACE < DEBUG < INFO < WARN < ERROR。

使用如下:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime;

public class MyLogback {
    

    private Logger logger = LoggerFactory.getLogger(MyLogback.class);
    
    void test(){
    
        String now = LocalDateTime.now().toString
        logger.trace("trace 测试日志打印->{}", now);
        logger.debug("debug 测试日志打印->{}", now);
        logger.info("info   测试日志打印->{}", now);
        logger.warn("warn   测试日志打印->{}", now);
        logger.error("error 测试日志打印->{}", now);
    }
}

如何自定义日志管理。在resource目录下新建一个logback-spring.xml文件。该xml文件主要分为以下几部分:

  1. 头部声明

    <?xml version="1.0" encoding="UTF-8"?>
    
  2. 主节点

    包含参数定义以及关键appender节点

    <configuration>
    	<!-- 项目名称 例:mylogback -->
        <property name="APP_NAME" value="mylogback" />
        <!-- 日志目录 例:/usr/local/mylogback/logs -->
        <property name="LOG_PATH" value="/usr/local/${APP_NAME}/logs" />
    </configuration>
    
  3. 关键子节点

    • appender:是一个接口,最重要的有两个Appender,分别为ConsoleAppender和RollingFileAppender。顾名思义,前者主要是控制台输出,对应的class值为:ch.qos.logback.core.ConsoleAppender;后者则是输出到文件中,对应的class值为ch.qos.logback.core.rolling.RollingFileAppender
    • file:主要针对RollingFileAppender输出文件命名规则
    • encoder:最主要的是pattern,定义日志格式
    • filter:日志过滤规则
    • rollingPolicy:主要针对文件日志输出,定义输出日志策略
    <appender name="myDebuglog" class="ch.qos.logback.core.ConsoleAppender">
        <file>
        	${LOG_PATH}/debug.log
        </file>
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <!-- 过滤策略 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 设置命中策略 debug、info、warn、error -->
            <level>debug</level>
            <!-- 命中设置的日志等级就记录 -->
            <onMatch>ACCEPT</onMatch>
            <!-- 未命中则拒绝该appender策略 -->
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 日志归档 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 每产生一个日志文件,该日志文件的保存期限为30天 -->
            <maxHistory>30</maxHistory>
            <!-- 单个文件达到最大10MB时开始切分 -->
            <maxFileSize>10MB</maxFileSize>
            <!-- 当日志容量超过20GB,即使没有到保存期限的30天也会开启日志清理 -->
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
    </appender>
    

二、默认实现

如果我们不写logback.xml配置文件,工程项目也会正常打印日志,因为springboot有默认的实现,即通过以下两个文件进行指定,以下是Spring Boot下的org/springframework/boot/logging/logback/base.xml、defaults.xml文件默认实现:

base.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!--
Base logback configuration provided for compatibility with Spring Boot 1.1
-->

<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>

defaults.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!--
Default logback configuration provided for import
-->

<included>
	<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{${LOG_DATEFORMAT_PATTERN:-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}}"/>
	<property name="CONSOLE_LOG_CHARSET" value="${CONSOLE_LOG_CHARSET:-${file.encoding:-UTF-8}}"/>
	<property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
	<property name="FILE_LOG_CHARSET" value="${FILE_LOG_CHARSET:-${file.encoding:-UTF-8}}"/>

	<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
	<logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
	<logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
	<logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/>
	<logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/>
	<logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/>
	<logger name="org.hibernate.validator.internal.util.Version" level="WARN"/>
	<logger name="org.springframework.boot.actuate.endpoint.jmx" level="WARN"/>
</included>

三、实用模板

经过上述分析,对logback配置文件有了大概的了解,接下来旨在提供标准可用的日志配置文件,并且由于trace级别的日志打印极少用到,我们在配置文件中暂不体现trace级别配置,若有需要请根据实际需求进行增减调整配置。

此处定义的日志目录会输出到C盘,若部署到线上需要做调整;日志最大保留天数均为30天,单个文件最大不超过100MB,且在同个level下总文件大小不超过20GB,否则即使没超过30天也会自动清理日志:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 引入默认实现 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <!-- 自定义项目名称 例:mylogback -->
    <property name="APP_NAME" value="mylogback" />
    <!-- 自定义日志目录 若线上部署环境需调整 如:/usr/local/${APP_NAME}/logs -->
    <property name="LOG_PATH" value="C:/${APP_NAME}/logs" />
    <!-- 引入日志等级参数,支持从配置文件读入 -->
    <springProperty scope="context" name="log.level" source="log.level"/>

    <!-- 时间滚动输出 level为 DEBUG 日志 -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/debug.log</file>
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <!-- 日志归档 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <maxFileSize>100MB</maxFileSize>
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <!-- 此日志文件只记录debug级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 INFO 日志 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/info.log</file>
        <encoder>
            <charset>UTF-8</charset>
            <!-- 引用默认的配置项 -->
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <!-- 日志归档 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <maxFileSize>100MB</maxFileSize>
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 WARN 日志 -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/warn.log</file>
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <!-- 日志归档 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <maxFileSize>100MB</maxFileSize>
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <!-- 此日志文件只记录warn级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 ERROR 日志 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/error.log</file>
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <!-- 日志归档 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <maxFileSize>100MB</maxFileSize>
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <!-- 此日志文件只记录error级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${log.level}</level>
        </filter>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <root level="${log.level}">
        <appender-ref ref="DEBUG_FILE" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="WARN_FILE" />
        <appender-ref ref="ERROR_FILE" />
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

使用前建议配置日志打印等级,表示只打印输出设置值及以上等级的日志:

logging:
  level:
    root: debug #debug info warn error

实际使用效果如下:

image-20211123135321043

image-20211123135359092

四、总结

项目中最细微的日志打印虽然平时感知不到,正所谓润物细无声,但是实际上好的日志打印能够帮助你更快定位项目的线上问题。

读者可以clone该项目体验日志文件输出,该项目会定时每隔5秒打印各个等级的日志:

https://gitee.com/dearvainycos/mylogback.git

参考资料:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/imVainiycos/article/details/121492830

智能推荐

promise解决重复调用同一接口(同步)_promise.all并行调同一个接口-程序员宅基地

文章浏览阅读4.7k次。前端实现多次调用同一个接口,所有数据均成功返回后,才可继续执行下面的代码封装请求数据方法getData(param) { return new Promise((resolve, reject) => { this.$axios .get(`/xx/xx/xxpath/${param}`) .then(res => { let content = res.data reso_promise.all并行调同一个接口

socket编程种名字与地址转换函数_getservbyname是可重入函数吗-程序员宅基地

文章浏览阅读274次。参考:《UNIX 网络编程 · 卷1 : 套接字联网API》之前都是使用数值地址来表示主机(比如:127.0.0.1),用数值端口号来标识服务器(比如:6379)。但是有时候最好使用名字而不是数值:名字比较容易记住,数值地址容易变动,而名字地址保持不变;随着 IPv6 上转移,数值地址变得很长,手工键入数值容易出错。之后将有一系列函数用于名字、数值、端口之间的转换。gethostbyname & gethostbyaddr 函数gethostbyname 函数查找主机名字最基本的函数时 g_getservbyname是可重入函数吗

第一章 Java概述_第 1章java me的概述-程序员宅基地

文章浏览阅读436次。JavaSE结构•Java概述•Java编程基础•面向对象编程•异常处理•API常用类•多线程•容器类•I/O•网络编程•注解1 Java概述结构•1.1 软件编程常识•1.2 Java语言概述•1.3 Java体系结构•1.4 Java语言的跨平台特性•1.5 搭建Java程序的开发环境•1.6 Java程序开发体验_第 1章java me的概述

CSS 选取第几个标签元素_css 第几个几个div-程序员宅基地

文章浏览阅读1w次,点赞6次,收藏11次。在前端开发中,我们可能会碰到这样的需求:想让列表中的第一个部分显示不同的样式 ,想让列表中的偶数部分显示不同的背景颜色,想让列表中的最后一部分样式不一样……这样的需求,我们怎样来实现?其实,如果前面文件是php开发的,可以通过php的循环语句+判断语句+css样式来实现。但是,如果是静态代码,php就无法用了。这时,我们还可以通过CSS来实现,CSS给我们提供了几个非常有用的样式参数:first-..._css 第几个几个div

固定资产管理系统的打造-程序员宅基地

文章浏览阅读106次。固定资产管理总体分为两个部分:固定资产管理财务帐部分,固定资产管理实物帐部分。前者偏重价值管理,后者偏重实物管理,前者一般由财务部门负责,后者一般由行政部门负责。两部分信息又是紧密衔接相辅相成的,通过信息系统的..._crv管理系统

SAP MM 物料主数据MRP2 视图Rounding Value字段-程序员宅基地

文章浏览阅读639次。SAP MM 物料主数据MRP2 视图Rounding Value字段如下物料号,MRP2视图中,维护了rounding value字段值为50。MRP type..._sap mpr2视图

随便推点

单片机入门资料,按键消抖方式,按键怎么消抖_单片机按键消抖-程序员宅基地

文章浏览阅读1.2w次,点赞19次,收藏108次。1.什么是按键消我们先来看一下按键按下去的波形图1.按键消抖原理我们可以看到当按键按下的那一时刻和松开的时候有类似于锯齿的形状那就是按键抖动,这个抖动不是我们人为能控制得了的,所以我们只能对进行硬件消抖或者进行软件消抖本期我们讲解软件消抖.**上图中我们可以看到理想波形和实际波形有很大的区别,区别在于实际波形在按键按下的那一刻前后有20毫秒的抖动,我们按键消抖的目的呢就是把抖动忽略掉只要中间的稳定闭合区域.**## 方法一延时消抖法可以用延时的方式跳过抖动的区域优缺点:优点._单片机按键消抖

Image2Lcd图片取模软件-程序员宅基地

文章浏览阅读3.7w次,点赞73次,收藏265次。image2lcd是一款非常简单使用的图片转换成LCD图像数据的图片转换软件。它能够将各种形式来源的图片转换成特定的数据格式以用来匹配单片机系统所需要的显示数据格式。在输入方面,它支持JPG、BMP、EMF、WBMP、GIF、ICO等多种格式图片的输入,输出的数据拥有二进制类型、WBMP格式、C语言数组类型和标准的BMP格式等多种类型。同时它还能将图象的数据扫描方式、亮度、对比度、灰度(颜色数)以及图像数据排列方式等等进行调节。image2lcd v3.2破解版image2lcd是一款非常简单使_image2lcd

IOS里的TaggedPointer[NSNumber篇]_nsnumber的tagged pointer-程序员宅基地

文章浏览阅读1.9k次。转自:http://www.infoq.com/cn/articles/deep-understanding-of-tagged-pointer/前言在2013年9月,苹果推出了iPhone5s,与此同时,iPhone5s配备了首个采用64位架构的A7双核处理器,为了节省内存和提高执行效率,苹果提出了Tagged Pointer的概念。对于64位程序,引入Tagged Po_nsnumber的tagged pointer

BUUCTF_2.RIP覆盖一下_buuctf rip-程序员宅基地

文章浏览阅读3.7k次。解题思路1. 查看文件信息,安全机制2. 代码审计3. 分析漏洞点4. 编写EXP1.基本信息$checksec ./文件名2.代码审计不管在简单题都一定要IDA查看一下伪代码(IDA做好是7.0以上的版本)首先查看敏感字符串(Ctrl+1)1.gets从标准输入设备读字符串函数,其可以无限读取,不会判断上限,以回车结束读取,所以应该确保buffer的空间足够大,以便在执..._buuctf rip

curl_init()和curl_multi_init()多线程的速度比较_curl_multi_init c++-程序员宅基地

文章浏览阅读7k次。php中curl_init()的作用很大,尤其是在抓取网页内容或文件信息的时候,例如之前文章curl获得header检测GZip压缩的源代码就介绍到curl_init()的强大。curl_init()处理事物是单线程模式,如果需要对事务处理走多线程模式,那么php里提供了一个函数curl_multi_init()给我们,这就是多线程模式处理事务的函数。curl_init()与cur_curl_multi_init c++

execve系统调用_execve系统调用寄存器参数-程序员宅基地

文章浏览阅读2.6k次。sys_execve()在真正的开始执行系统调用函数之前,系统调用服务程序已经将一些系统调用的函数的参数传递给了相应的寄存器,比如这里的ebx,ecx,edx都分别保存了系统调用的参数,ebx保存的是第一个参数,依次类推(当然最多传递的参数个数不能大于5个),首先这个函数通过ebx获取需要执行的文件的绝对路径,他通过这样一个函数实现获取到文件名之后他就会调用do_execve();_execve系统调用寄存器参数

推荐文章

热门文章

相关标签