logback最全日志输出,你需要的这里都有,全是干货

有工作经历的都知道,日志打印非常重要,往往是定位生产问题的唯一方式。

如果不了解日志的配置,先查看我另一篇文章基于springboot的logback日志管理,文章里面日志输出,分级、分文件目录,还有各种配置以及说明都写的很详细。

进入正题

场景:针对(微)多服务,并发的情况。当有多机部署或者高并发情况下,多个日志同时写入同一个日志文件如info.log时,会出现日志打印非常杂乱,出现问题的话,不能确定日志是哪一个请求打印出来的。

解决办法:在日志打印添加一个ID,方便追踪同一个请求打印的ID

本文章参考于Logback 日志添加请求唯一追踪 ID

操作:
添加过滤器拦截

import org.slf4j.MDC;import javax.servlet.*;
import java.io.IOException;
import java.util.UUID;/*** @Description* @Author Bernie* @Date 2024/3/7 11:04**/
public class LogMDCFilter implements Filter {private static final String UNIQUE_ID_NAME = "traceId";@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException {MDC.put(UNIQUE_ID_NAME, UUID.randomUUID().toString().replace("-", ""));// UUID太长,可自定义配置短的,短时间内不重复就行try {filterChain.doFilter(servletRequest, servletResponse);} finally {MDC.remove(UNIQUE_ID_NAME);}}
}

注册拦截器

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @Description* @Author Bernie* @Date 2024/3/7 11:07**/
@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<LogMDCFilter> logFilterRegistration() {FilterRegistrationBean<LogMDCFilter> registration = new FilterRegistrationBean<>();// 注入过滤器registration.setFilter(new LogMDCFilter());// 拦截规则registration.addUrlPatterns("/*");// 过滤器名称registration.setName("logMDCFilter");// 过滤器顺序registration.setOrder(0);return registration;}}

在 logback.xml 日志配置文件中,使用%X{traceId}来引用程序中设置的日志唯一追踪 ID 的值
我这里是配置很全的。

<?xml version="1.0" encoding="UTF-8"?>
<!--
scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<configuration scan="false" scanPeriod="60 seconds" debug="false"><!-- 定义日志的根目录 --><property name="LOG_HOME" value="./logs" /><!-- 定义日志文件名称 --><property name="debug" value="manager-codekiller-debug"></property><property name="info" value="manager-codekiller-info"></property><property name="error" value="manager-codekiller-error"></property><property name="warn" value="manager-codekiller-warn"></property><property name="job" value="manager-codekiller-job"></property><property name="fileName" value="logback"></property><!-- ch.qos.logback.core.ConsoleAppender 表示控制台输出 --><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><!--日志输出格式:%d表示日期时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度%logger{50} 表示logger名字最长50个字符,否则按照句点分割。%msg:日志消息,%n是换行符%-15.15():如果记录的线程字符长度小于15(第一个)则用空格在右侧补齐,如果字符长度大于15(第二个),则从开头开始截断多余的字符%-50.50():如果记录的logger字符长度小于50(第一个)则用空格在右侧补齐,如果字符长度大于50(第二个),则从开头开始截断多余的字符%highlight():颜色,info为蓝色,warn为浅红,error为加粗红,debug为黑色%boldMagenta:粗红%magenta:洋红$cyan:青色%white:白色--><layout class="ch.qos.logback.classic.PatternLayout"><springProfile name="dev"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}  %highlight(%-5level) %magenta([%-15.15(%thread)]) [%X{traceId}] %cyan( %-50.50(%logger{50} )) : %msg%n</pattern></springProfile><springProfile name="!dev"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}  %highlight(%-5level) %magenta([%-15.15(%thread)]) [%X{traceId}] %cyan( %-50.50(%logger{50} )) : %msg%n</pattern></springProfile></layout></appender><!--控制台打印警告信息的单独处理--><appender name="consoleWarn" class="ch.qos.logback.core.ConsoleAppender"><layout class="ch.qos.logback.classic.PatternLayout"><springProfile name="dev"><pattern>%magenta(%d{yyyy-MM-dd HH:mm:ss.SSS}  %highlight(%-5level) %magenta([%-15.15(%thread)]) [%X{traceId}] %cyan( %-50.50(%logger{50} )) : %msg%n)</pattern></springProfile><springProfile name="!dev"><pattern>%magenta(%d{yyyy-MM-dd HH:mm:ss.SSS}  %highlight(%-5level) %magenta([%-15.15(%thread)]) [%X{traceId}] %cyan( %-50.50(%logger{50} )) : %msg%n)</pattern></springProfile></layout></appender><!--控制台打印错误信息的单独处理--><appender name="consoleError" class="ch.qos.logback.core.ConsoleAppender"><layout class="ch.qos.logback.classic.PatternLayout"><springProfile name="dev"><pattern>%boldMagenta(%d{yyyy-MM-dd HH:mm:ss.SSS}  %highlight(%-5level) %magenta([%-15.15(%thread)]) [%X{traceId}] %cyan( %-50.50(%logger{50} )) : %msg%n)</pattern></springProfile><springProfile name="!dev"><pattern>%boldMagenta(%d{yyyy-MM-dd HH:mm:ss.SSS}  %highlight(%-5level) %magenta([%-15.15(%thread)]) [%X{traceId}] %cyan( %-50.50(%logger{50} )) : %msg%n)</pattern></springProfile></layout></appender><!--debug日志存储--><appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 指定日志文件的名称 --><file>${LOG_HOME}/${debug}/${fileName}.log</file><!--过滤,只存储DEBUG级别的日志--><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>DEBUG</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><!--当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。--><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动%i:当文件大小超过maxFileSize时,按照i进行文件滚动--><fileNamePattern>${LOG_HOME}/${debug}/${fileName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern><!--可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除。--><MaxHistory>365</MaxHistory><!--当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy--><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><!-- 日志输出格式: --><layout class="ch.qos.logback.classic.PatternLayout"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}  %-5level  [%-15.15(%thread)] [%X{traceId}] [%X{traceId}] %-50.50(%logger{50}) :  %msg%n</pattern></layout></appender><!--info日志存储--><appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_HOME}/${info}/${fileName}.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_HOME}/${info}/${fileName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern><MaxHistory>365</MaxHistory><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><!-- 日志输出格式: --><layout class="ch.qos.logback.classic.PatternLayout"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}  %-5level  [%-15.15(%thread)] [%X{traceId}] %-50.50(%logger{50}) :  %msg%n</pattern></layout></appender><!--warn日志存储--><appender name="warn" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_HOME}/${warn}/${fileName}.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARN</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_HOME}/${warn}/${fileName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern><MaxHistory>365</MaxHistory><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><!-- 日志输出格式: --><layout class="ch.qos.logback.classic.PatternLayout"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}  %-5level  [%-15.15(%thread)] [%X{traceId}] %-50.50(%logger{50}) :  %msg%n</pattern></layout></appender><!--error日志存储--><appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_HOME}/${error}/${fileName}.log</file><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_HOME}/${error}/${fileName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern><MaxHistory>365</MaxHistory><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><!-- 日志输出格式: --><layout class="ch.qos.logback.classic.PatternLayout"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}  %-5level  [%-15.15(%thread)] [%X{traceId}] %-50.50(%logger{50}) :  %msg%n</pattern></layout></appender><!--    &lt;!&ndash;job日志存储&ndash;&gt;--><!--    <appender name="job" class="ch.qos.logback.core.rolling.RollingFileAppender">--><!--        &lt;!&ndash; 指定日志文件的名称 &ndash;&gt;--><!--        <file>${LOG_HOME}/${job}/${fileName}.log</file>--><!--        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">--><!--            <fileNamePattern>${LOG_HOME}/${job}/${fileName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>--><!--            <MaxHistory>365</MaxHistory>--><!--            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">--><!--                <maxFileSize>100MB</maxFileSize>--><!--            </timeBasedFileNamingAndTriggeringPolicy>--><!--        </rollingPolicy>--><!--        &lt;!&ndash; 日志输出格式: &ndash;&gt;--><!--        <layout class="ch.qos.logback.classic.PatternLayout">--><!--            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}  %-5level  [%-15.15(%thread)]  %-50.50(%logger{50}) :  %msg%n</pattern>--><!--        </layout>--><!--    </appender>--><!--job包的单独输出--><!--    <logger name="top.codekiller.manager.examination.job"  level="debug"   additivity="false">--><!--        <appender-ref ref="job"></appender-ref>--><!--        <appender-ref ref="console"></appender-ref>--><!--    </logger>--><!--logger主要用于存放日志对象,也可以定义日志类型、级别,并且会先执行。name:表示匹配的logger类型前缀,也就是包的前半部分level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERRORadditivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出,即是否将信息提交给rootfalse:表示只用当前logger的appender-ref,true:表示当前logger的appender-ref和rootLogger的appender-ref都有效--><!--mapper包的单独输出(输出sql信息,至关重要)--><logger name="mapper"  level="debug"   additivity="false"><appender-ref ref="console"></appender-ref></logger><!--debug的单独输出--><logger name="log-debug"  level="debug"   additivity="false"><appender-ref ref="console"/><appender-ref ref="debug" /></logger><!--warn的单独输出--><logger name="log-warn"  level="warn"   additivity="false"><appender-ref ref="consoleWarn"/><appender-ref ref="warn" /></logger><!--error的单独输出--><logger name="log-error"  level="error"   additivity="false"><appender-ref ref="consoleError"/><appender-ref ref="error"/></logger><!--root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。--><root level="info"><appender-ref ref="console"/><appender-ref ref="debug" /><appender-ref ref="info" /><appender-ref ref="warn" /><appender-ref ref="error" /></root></configuration>

效果如下:
控制台:
在这里插入图片描述
info.log
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/726894.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

四面体单元悬臂梁的Matlab有限元编程 | 实体单元 | Matlab源码 | 理论文本

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

全面剖析一下ThreadLocal

什么是ThreadLocal&#xff1f; ThreadLocal英文翻译过来就是&#xff1a;线程本地量&#xff0c;它其实是一种线程的隔离机制&#xff0c;保障了多线程环境下对于共享变量访问的安全性。 看到上面的定义之后&#xff0c;那么问题就来了&#xff0c;ThreadLocal是如何解决共享…

Java 中创建线程多种方式介绍

在 Java 中&#xff0c;创建线程有多种方式&#xff0c;以下是最常见的四种&#xff1a; 1. **通过继承 Thread 类** 2. **通过实现 Runnable 接口** 3. **通过实现 Callable 接口** 4. **通过使用 Executor 框架** 每种方式都有其特点和适用场…

Go编译报错 link: running gcc failed: exit status 1(已解决)

背景 在对一个开源的Go程序二次开发 重新编译时 &#xff0c; 报错截图如下 报错文字如下&#xff1a;关键信息 link: running gcc failed: exit status 1 $ go build -o orchestrator-didi -i go/cmd/orchestrator/main.go go build: -i flag is deprecated # command-li…

客服提效工具:一键回复,效率翻倍

在快节奏的工作环境中&#xff0c;每一秒都是宝贵的。对于客服人员来说&#xff0c;每天面对的是海量的咨询和回复&#xff0c;如何在保证服务质量的同时&#xff0c;提高工作效率&#xff1f;最近&#xff0c;我被同事安利了一个神奇的工具——客服宝聊天助手。这是一款专为客…

基于单片机的天然气泄漏报警系统设计论文

目 录 摘 要 I Abstract II 1 引 言 1 2天然气泄露检测报警系统的方案设计 4 2.1 方案选择 4 2.2 天然气泄露报警系统的整体设计方案 5 2.2.1天然气泄漏报警器工作原理 5 2.2.2天然气泄漏报警器的结构 5 3天然气泄露报警的硬件部分设计 7 3.1 STC89C52单片机 7 3.2 传感器的选…

IJCAI23 - Continual Learning Tutorial

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 本篇 Tutorial 主要介绍了 CL 中的一些基本概念以及一些过往的方法。 Problem Definition Continual Learning 和 Increm…

【MOMO_Tips】批量将word转换为PDF格式

批量将word转换为PDF格式 1.打开文件–>选项–>自定义功能区–>开发工具–>确定 2.点开开发工具&#xff0c;选择第一个visual basic 3.进入页面后找到插入–>模块&#xff0c;就可以看到这样的画面之后将下列vba代码复制粘贴到模块中 Sub ConvertWordsToPd…

进程的内存布局与进程的虚拟地址空间

进程的内存布局 历史沿袭至今&#xff0c;C 语言程序一直都是由以下几部分组成的&#xff1a; ⚫ 正文段。也可称为代码段&#xff0c;这是 CPU 执行的机器语言指令部分&#xff0c;文本段具有只读属性&#xff0c;以防止程序由于意外而修改其指令&#xff1b;正文段是可以共…

精读《React Conf 2019 - Day1》

1 引言 React Conf 2019 在今年 10 月份举办&#xff0c;内容质量还是一如既往的高&#xff0c;如果想进一步学习前端或者 React&#xff0c;这个大会一定不能错过。 希望前端精读成为你学习成长路上的布道者&#xff0c;所以本期精读就介绍 React Conf 2019 - Day1 的相关内…

2024主流测试工具测评,总有一款适合你!

大家好&#xff01;我是测试元宝~ 在软件开发周期中&#xff0c;测试是确保产品质量的关键环节。随着企业对于软件质量的要求日益提升&#xff0c;测试人员面临着前所未有的挑战&#xff0c;“工欲善其事必先利其器”&#xff0c;选择一款高效、实用的软件测试工具&#xff0c…

LeetCode # 547. 省份数量

547. 省份数量 题目 有 n 个城市&#xff0c;其中一些彼此相连&#xff0c;另一些没有相连。如果城市 a 与城市 b 直接相连&#xff0c;且城市 b 与城市 c 直接相连&#xff0c;那么城市 a 与城市 c 间接相连。 省份 是一组直接或间接相连的城市&#xff0c;组内不含其他没有…

Git 基于ED25519、RSA算法生成 SSH 密钥

Git 基于ED25519、RSA算法生成 SSH 密钥 基于ED25519算法&#xff0c;生成密钥对命令如下&#xff1a; ssh-keygen -t ed25519 -C "邮箱地址"基于RSA算法&#xff0c;生成密钥对命令如下&#xff1a; ssh-keygen -t rsa -C "<注释内容>"基于ED255…

若依集成MybatisPlus步骤

目录 一、新建业务模块二、集成MybatisPlus三、测试 一、新建业务模块 新建Maven模块&#xff0c;并建立如下目录 新模块的pom.xml添加如下内容 <description>业务模块</description><dependencies><!-- Mysql驱动包 --><dependency><groupI…

Locust中wait_time中匿名函数使用方法浅析

前言 翻出之前做个压测项&#xff0c;看到locust中对等待时间的实现方式感到好奇&#xff0c;于是总结下来。 源代码实现 def between(min_wait, max_wait):"""Returns a function that will return a random number between min_wait and max_wait.Example:…

thinkphp学习12-数据库的时间查询

传统方式 可以使用>、<、>、<来筛选匹配时间的数据&#xff1b; public function index() {$res Db::name(user)->where(create_time, >, 2018-1-1)->select();dump($res); }可以使用 between 关键字来设置时间的区间&#xff1b; public function in…

如何在Linux系统部署MeterSphere服务并配置固定公网访问地址

文章目录 推荐 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#…

影响APP广告变现收益的4个关键因素

APP的广告收入&#xff08;IAA&#xff09;展示 * eCPM/1000 IAA收入其实是由广告总展示量和每次展示的平均收入共同决定的。所以&#xff0c;提高IAA收入&#xff0c;我们需要双管齐下&#xff1a;同时提高广告总展示量和平均每次展示的收入。 app广告变现对接点击⬇️链接&…

单机版openstack安装

说明&#xff1a; 本文环境&#xff1a;CentOS 7 x64位 1.创建虚拟机 2.在虚拟机中安装 centos 7&#xff08;最小安装&#xff09;&#xff0c;修改主机名&#xff1a;openstack&#xff0c;设置 root 密码&#xff1a;12345678 3. 网卡设置&#xff0c;重启网络服务&#…

20240306-1-大数据的几个面试题目

面试题目 1. 相同URL 题目: 给定a、b两个文件&#xff0c;各存放50亿个url&#xff0c;每个url各占64字节&#xff0c;内存限制是4G&#xff0c;让你找出a、b文件共同的url&#xff1f; 方案1&#xff1a;估计每个文件的大小为50G64320G&#xff0c;远远大于内存限制的4G。所以…