springboot中logback配置conversionRule、ConsoleAppender

2023-11-04

1 概述

在Java生态中,日志框架有很多,常见的有:jul(JDK提供)、log4j、logback等,随着各种日志框架的出现,在实际项目中使用方式、暴露的日志api、依赖等问题都需要程序员考虑和选择。面对中场景SLF4J出现了即简单日志门面,自身不记录日志,只作为各个日志框架的门面存在。SLF4J常用的日志实现:log4j、logback,一般有slf4j+log4j(log4j2)、slf4j+logback两种日志组合。

在springboot中,默认使用logback作为日志实现,并对logback进行了默认的配置,我们在项目开发和系统运行中难免会遇到,对logback进行定制和高并发场景日志性能优化。本文主要在springboot环境下对logback的使用、配置、优化进行讲解。

1.1 logback介绍

logback 由log4j创始人Ceki Gülcü设计的,相比于其他日志框架,性能更好、占用空间更小。主要包含三个模块:

logback-core:logback的核心基础模块,为其他模块提供支撑

logback-classic:实现了slf4j API,看作log4j的增强,提供了常用的encoder、filter、pattern、AsyncAppender等

Logback-access:可以与 Servlet 容器(如 Jetty 或 Tomcat)集成,以提供丰富而强大的 HTTP 访问日志功能。

甩出官网:Documentation (qos.ch)

1.2 演示测试项目

springboot版本:

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7</version>

logback版本:1.2.11

jdk版本:17.0.2

2 抛砖引玉

开始之前先给出,个人开发项目过程中使用的配置方式和细节,暂时没做dev、test、pre、pro环境区分。

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--
 scan:         logback配置文件一旦发生变化,logback支持重新加载文件
 scanPeriod:   60s加载一次
 debug:        应用启动时在控制台上打印出 context上下文的加载情况
 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!-- spring上下文的属性配置 -->
    <springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
    <springProperty scope="context" name="APP_PORT" source="server.port"/>

    <!-- 彩色日志依赖的渲染类 -->
    <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"/>

    <!-- 彩色日志格式
        时间:            %d{yyyy-MM-dd HH:mm:ss.SSS}
        应用名称:         ${APP_NAME:-APP}
        日志级别:         %5p
        进程ID:          ${PID:- }
        线程名称:         %15.15t
        触发日志类方法:    %-40.40logger{39}
        代码行号:         %-4line
        日志内容:         %m
        换行符:           %n
        异常:            %wEx
    -->
    <property name="CONSOLE_LOG_PATTERN"
              value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} [${APP_NAME:-APP} %clr(${APP_PORT:-}){blue}] %clr(${PID:- }){magenta} %clr(%5p) %clr([%15.15t]){faint} %clr(%-40.40logger{39} %-4line){cyan} %clr(:){faint} %m%n%wEx"/>

    <!-- 文件日志格式 -->
    <property name="FILE_LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [${APP_NAME:-APP}] %5p ${PID:- } [%15.15t] %-40.40logger{39} %-4line : %m%n%wEx"/>


    <!-- 定义日志文件存储位置和文件名 -->
    <property name="LOG_FILE" value="logs/log"/>

    <!-- 定义日志文件归档格式:
         log.2023-06-07.0.gz
         log.2023-06-07.1.gz
         log.2023-06-07.2.gz
     -->
    <property name="ROLLINGPOLICY_FILE_NAME_PATTERN" value="${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz"/>

    <!-- 单个日志文件大小 -->
    <property name="ROLLINGPOLICY_MAX_FILE_SIZE" value="20MB"/>

    <!-- 归档文件占用磁盘总大小,超过后会根据cleanHistoryOnStart实行,决定是否删除 -->
    <property name="ROLLINGPOLICY_TOTAL_SIZE_CAP" value="1GB"/>

    <!-- 超过最大磁盘限制后是否删除归档文件 -->
    <property name="ROLLINGPOLICY_CLEAN_HISTORY_ON_START" value="true"/>

    <!-- 保留的历史归档日志文件个数 -->
    <property name="ROLLINGPOLICY_MAX_HISTORY" value="10"/>
    

    <!-- 控制台输出 -->
    <appender name="CONSOLE_OUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 文件输出: RollingFileAppender 滚动日志输出-->
    <appender name="FILE_OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <file>${LOG_FILE}</file>
        <!-- 滚动日志策略: SizeAndTimeBasedRollingPolicy 根据文件大小和时间进行分割归档-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${ROLLINGPOLICY_FILE_NAME_PATTERN}</fileNamePattern>
            <cleanHistoryOnStart>${ROLLINGPOLICY_CLEAN_HISTORY_ON_START}</cleanHistoryOnStart>
            <maxFileSize>${ROLLINGPOLICY_MAX_FILE_SIZE}</maxFileSize>
            <totalSizeCap>${ROLLINGPOLICY_TOTAL_SIZE_CAP}</totalSizeCap>
            <maxHistory>${ROLLINGPOLICY_MAX_HISTORY}</maxHistory>
        </rollingPolicy>
    </appender>


    <!-- AsyncAppender 在于高并发下,加如日志队列缓存,减少写磁盘日志的IO次数。可以根据实际情况决定是否使用 -->

    <appender name="ASYNC_CONSOLE_APPENDER" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 如果设置20,表示队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志,设置0则不会丢弃 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>1024</queueSize>
        <!-- 队列满了不阻塞调用者-->
        <neverBlock>false</neverBlock>
        <!-- 是否记录调用者额外的信息(比如记录后,可以打印行号)会造成性能损耗,默认false只记录线程名字和mdc信息 -->
        <includeCallerData>true</includeCallerData>
        <!-- 实际输出日志appender,最多只能添加一个 -->
        <appender-ref ref ="CONSOLE_OUT"/>
    </appender>

    <appender name="ASYNC_FILE_APPENDER" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 如果设置20,表示队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志,设置0则不会丢弃 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>1024</queueSize>
        <!-- 队列满了不阻塞调用者-->
        <neverBlock>false</neverBlock>
        <!-- 实际输出日志appender,最多只能添加一个 -->
        <appender-ref ref ="FILE_OUT"/>
    </appender>

    <!-- 默认的日志输出级别 -->
    <root level="INFO">
        <!--选择合适的日志记录器,可以是多个,会同时写入。一般是一个console,一个file,可以选择异步和同步-->
        <appender-ref ref="ASYNC_CONSOLE_APPENDER"/>
        <appender-ref ref="ASYNC_FILE_APPENDER"/>
    </root>
</configuration>

在这里插入图片描述

3 功能介绍

3.1 配置文件加载

springboot默认加载classpath下 logback-spring.xml,可以通过properties配置指定路径:

logging.config=classpath:log/logback-spring.xml

如果想区分环境可以通过不同的环境的application-xx.properties指定不同的日志文件路径。

3.2 logback配置

3.2.1 configuration

根节点:configuration,作为顶级标签, 可以用来配置一些lockback的全局属性,常见的属性如下:

  • scan=“true” :scan是否开启自动扫描,监控配置文件更新,生效。
  • scanPeriod=“60 seconds” :扫描的频率
  • debug=“false”:是否开启logback的debug模式,注意这里和日志的debug无关,开启后启动之前会打印一些logback自身的信息。

3.2.2 property

property 标签可以定义一些属性变量,供其他配置地方通过${xxx}使用。

springProperty 标签可以获取spring上下文里的属性。

3.2.3 conversionRule

定义转换器,可以用来对日志进行特殊的转换,比如,SpringBoot后启动项目控制台会带有彩色日志样式,是因为使用了org.springframework.boot.logging.logback.ColorConverter颜色转换器,会把日志用AnsiOutput进行输出。

3.2.4 appender

Appender是logback中的最核心组件之一,承担日志时间的写入任务,包括:控制台、日志文件、网络输出等。借用一张官方的继承体系图:

在这里插入图片描述

途中可以看出常用的appender有三个:

  • ConsoleAppender:日志写入到控制台,底层会调用jdk的 System.outSystem.err
<appender name="CONSOLE_OUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>
  • FileAppender:日志写入到指定文件,有几个常用属性。
    • file:指定写入的日志文件名,可以是相对或者绝对目录
    • append:追加模式默认开启,不会清空原文件
    • prudent:当设置为true,日志会被安全的写入文件,即使其他的FileAppender也在向此文件做写入操作,效率低,默认是 false。
    • immediateFlush:默认情况下true,每个日志事件都会立即刷新到文件输出流中。这种方法更安全,因为如果应用程序退出时没有正确关闭appender,则不会丢失日志记录事件。但是,想显著提高日志的吞吐量,可以将 limateFlush 属性设置为 false。
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>testFile.log</file>
    <append>true</append>
    <immediateFlush>true</immediateFlush>
    <encoder>
        <pattern>${FILE_LOG_PATTERN}</pattern>
    </encoder>
</appender>
  • RollingFileAppender:实际生产环境写文件日志的首选appender,可以实现滚动式写日志,在写日志的过程中如果符合某些条件策略时,会重新写入到新的文件,还可以将历史日志进行归档、定期删除等。解决了FileAppender方式会导致日志都在一个文件中,文件会越来越大,难以打开。常用属性配置:
    • file:文件存储位置
    • rollingPolicy:滚动策略配置
<appender name="FILE_OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${FILE_LOG_PATTERN}</pattern>
        <charset>UTF-8</charset>
    </encoder>
    <file>${LOG_FILE}</file>
    <!-- 滚动日志策略: SizeAndTimeBasedRollingPolicy 根据文件大小和时间进行分割归档-->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!-- 指定滚动文件名称的生成规则 -->
        <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
        <!-- 超过最大磁盘限制后是否删除归档文件 -->
        <cleanHistoryOnStart>true</cleanHistoryOnStart>
        <!-- 单个日志文件大小 -->
        <maxFileSize>20MB</maxFileSize>
        <!-- 归档文件占用磁盘总大小,超过后会根据cleanHistoryOnStart实行,决定是否删除 -->
        <totalSizeCap>1GB</totalSizeCap>
        <!-- 保留的历史归档日志文件个数 -->
        <maxHistory>10</maxHistory>
    </rollingPolicy>
</appender>
  • AsyncAppender:异步写日志,本身不做真是的日志写入,需要配置包裹其它appender,在于高并发下,加如日志队列缓存,减少写磁盘日志的IO次数。可以根据实际情况决定是否使用 。
<appender name="ASYNC_FILE_APPENDER" class="ch.qos.logback.classic.AsyncAppender">
    <!-- 如果设置20,表示队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志,设置0则不会丢弃 -->
    <discardingThreshold>0</discardingThreshold>
    <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
    <queueSize>1024</queueSize>
    <!-- 队列满了不阻塞调用者-->
    <neverBlock>false</neverBlock>
    <!-- 实际输出日志appender,最多只能添加一个 -->
    <appender-ref ref ="FILE_OUT"/>
</appender>
  • 不常用的appender:SocketAppender 写入socket、SMTPAppender 写入邮件、DBAppender 写入数据库

3.2.5 encoder

Encoder在0.9.19中引入,作用负责将日志事件转换为字节数组,并将字节数组输出到输出流中(具体的appender输出流)。在此之前的版本主要使用Layout,Layout只能将日志事件转换为String。Layout还无法控制何时写出日志,因此Layout无法对日志事件进行批量控制,相比之下,Encoder不仅可以完全控制写出的字节的格式,而且还可以控制何时(以及是否)写出这些字节内容。

  • PatternLayoutEncoder:最常用的编码器,通常指定:编码和日志打印规则

在这里插入图片描述

<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%15.15t] %-40.40logger{39} %-4line : %m%n%wEx</pattern>
    <charset>UTF-8</charset>
</encoder>

3.2.6 Layout

layout根据pattern规则,将日志事件转换为具体的日志字符串,我们配置的各种日志打印格式,都是由layout解析翻译成字符串。由于官方规则太多,我们以一个具体的例介绍一些常用的规则符号:

在这里插入图片描述

时间:            %d{yyyy-MM-dd HH:mm:ss.SSS}
应用名称:         ${APP_NAME:-APP}
日志级别:         %5p
进程ID:          ${PID:- }
线程名称:         %15.15t
触发日志类方法:    %-40.40logger{39}
代码行号:         %-4line
日志内容:         %m
换行符:           %n
异常:            %wEx

%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} [${APP_NAME:-APP} %clr(${APP_PORT:-}){blue}] %clr(${PID:- }){magenta} %clr(%5p) %clr([%15.15t]){faint} %clr(%-40.40logger{39} %-4line){cyan} %clr(:){faint} %m%n%wEx

详细规则:Chapter 6: Layouts (qos.ch)

3.2.7 Filters

filter 日志过滤器,本人实际用的不是太多,logback 的内置 filter 有一下几种:

  • 级别过滤器 ch.qos.logback.classic.filter.LevelFilter。对指定级别的日志进行具体的操作

  • 阀值过滤器 ch.qos.logback.classic.filter.ThresholdFilter。

  • 表达式过滤器 ch.qos.logback.core.filter.EvaluatorFilter。

    • Groovy的表达式 ch.qos.logback.classic.boolex.GEventEvaluator。

    • Java的表达式ch.qos.logback.classic.boolex.JaninoEventEvaluator。使用 Janino 解析java script。

  • 包含标记 ch.qos.logback.classic.boolex.OnMarkerEvaluator

<filter class="ch.qos.logback.classic.filter.LevelFilter">
    <!-- 过滤的级别 -->
    <level>INFO</level>
    <!-- 匹配时的操作:接收(记录) -->
    <onMatch>ACCEPT</onMatch>
    <!-- 不匹配时的操作:拒绝(不记录) -->
    <onMismatch>DENY</onMismatch>
</filter>

4 结束

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot中logback配置conversionRule、ConsoleAppender 的相关文章

随机推荐

  • Mysql用同一张表查询的结果删除此表的数据报错

    DELETE FROM study name WHERE name id IN SELECT name id FROM study name WHERE name id 20221209 执行会报错如下 DELETE 0 row s 0 0
  • LaTex学习笔记(三):矩阵的输入

    矩阵的输入类似于表格 在latex中输入矩阵有多种方式 1 left begin array clr 4343 434 235 45 3232 34 56 232 3467 end array right 2 begin bmatrix 不
  • Excel 两列数据中相同的数据进行同行显示

    一 要求 假设您有两个列 分别是A列和B列 需要在C列中找出A列对应的B列的值 二 方案 方法1 寻常思路 凸显重复项 对A列单独进行筛选 按颜色进行排序 然后升序 对B列重复上述操作即可 方法2 两个公式 VLOOKUP 纵向查找函数 语
  • HDFS操作

    1 使用oiv命令查看hadoop 的镜像文件 hadoop s201 hadoop dfs name current hdfs oiv Usage bin hdfs oiv OPTIONS i INPUTFILE o OUTPUTFILE
  • Python处理缺失数据

    目录 1 缺失原因 2 缺失类型 3 处理方法 3 1 删除 3 1 1 统计每列缺失值的个数 3 1 2 直接删除含有缺失值的行 3 1 3 直接删除含有缺失值的列 3 1 4 只删除全是缺失值的行 3 1 5 保留至少有4个非缺失值的行
  • 51单片机(STC)串口无阻塞发送函数

    目录 一 简介 1 1 开发环境 1 2 功能描述 二 串口程序 2 1 串口配置 2 2 变量定义 2 3 中断函数 2 4 发送函数 一 简介 1 1 开发环境 KeilC51 单片机型号STC15F2K60S2 1 2 功能描述 使用
  • Hutool导出Excel,导多个Sheet页

    重要方法 指定要写出的 Sheet 页 bigWriter setSheet sheet getSheetName 工具类 public class HuExcelUtils 导出多个 Sheet 页 param response para
  • 零售业未来如何破局?抓住数智化经营的两把利刃!

    导语 数字化转型浪潮席卷了千行百业 有人从中看出了汹涌的挑战 也有人从中嗅出了美妙的商机 对于零售企业而言 当前数智经营进入了哪个阶段 未来的破局之道又在何方 我们邀请到了广东省 CIO 协会消费品与零售行业分会会长 腾讯云 TVP 行业大
  • Unity3D

    Cheer Up 游戏说明 除了音效 游戏地图上的元素有 草丛 玩家可以躲进去 敌人攻击不到 河流 双方都过不去 但是子弹可以穿过 铁墙 坦克和子弹都过不去 砖墙 一发子弹摧毁后坦克可以过去 空气墙 围在地图周围 防止出界 敌方大坦克 打两
  • 介绍几款Python科学计算发行版

    目前比较流行的Python科学计算发行版 主要有这么几个 Python x y GUI基于PyQt 曾经是功能最全也是最强大的 而且是Windows系统中科学免费Python发行版的不二选择 不过今时已不同往昔 PythonXY里面的许多包
  • 在Excel中使用SQL

    说明 Excel中许多函数虽然能代替SQL的功能 但是比起SQL 还是有一些逊色 特意做了这个教程 主要有 分组统计 Excel中用数据透视表 SQL中用Group By 去重 Excel中可以用条件标识功能 开始 gt 条件标识 SQL中
  • 无闪视频风格切换新思路

    近段时间 视频风格切换应用的热度逐渐上升 包括已经成熟应用的gen 还有Ebsynth等 但是这些视频的切换都有一个通病就是视频会出现闪烁 导致最终的切换效果不佳 最近 有开源项目CoDeF提供了一种新的思路来解决这种闪烁的问题 从已经的公
  • ubuntu下使用Eclipse搭建Hadoop开发环境

    在ubuntu下使用Eclipse搭建Hadoop开发环境 一 安装准备 1 JDK版本 jdk1 7 0 jdk 7 linux i586 tar gz 2 hadoop版本 hadoop 1 1 1 hadoop 1 1 1 tar g
  • Milvus2.0

    一 介绍 项目官网 Milvus Open Source Vector Database built for scalable similarity searchhttps milvus io cn 项目文档 关于 Milvus Milvu
  • 页面禁止鼠标右键点击

    把这段代码放到head里就OK了
  • ChatGPT+Midjourney可量产“宫崎骏”,AI将会让多少设计师失业?

    最近 大家都被横空出世的ChatGPT惊艳到了 瞬间在全世界爆红的ChatGPT 除了陪聊 它还能写论文 写小说 写代码 编剧本 几乎无所不能 ChatGPT让科技巨头谷歌发出了红色警报 一夜之间全世界的打工人们也都慌了 我们的很多工作似乎
  • 带环单链表+带环单链表

    带环单链表 带环单链表 判断相交 若共用一个环则相交 若不共用则不相交 求解相交点 判断是否带环 定义快慢指针 快指针一次走两步 慢指针一次走一步 若快指针走完 慢指针走到一半 奇数为中间的节点 偶数为中间的两个中的后一个节点 则无环 若有
  • Windows下非常好用的包管理器scoop介绍

    以前我写过文章介绍过Windows下的包管理器Chocolatey 而Chocolatey并不是唯一的选择 还有一个很流行的选择就是scoop 原来我用Chocolatey比较多一点 但是后来因为我发现Chocolatey安装的JDK等软件
  • 700亿参数Llama 2训练加速195%!数据成为其提升效果的关键要素

    Llama 2是Meta AI正式发布的最新一代开源大模型 达到了2万亿的token 精调Chat模型是在100万人类标注数据上训练 Llama 2在包括推理 编码 精通性和知识测试等许多外部基准测试中都优于其他开源语言模型 Llama 2
  • springboot中logback配置conversionRule、ConsoleAppender

    1 概述 在Java生态中 日志框架有很多 常见的有 jul JDK提供 log4j logback等 随着各种日志框架的出现 在实际项目中使用方式 暴露的日志api 依赖等问题都需要程序员考虑和选择 面对中场景SLF4J出现了即简单日志门