logback-spring.xml详解

本文来写说下logback-spring.xml相关的知识与概念

文章目录

  • 概述
  • configuration元素
  • 定义上下文名称
  • 定义变量
  • appender组件
  • RollingFileAppender配置
  • logger配置
  • root配置
  • ELK的配置
  • 输出logback状态数据
  • 异步输出日志
  • 代码中的日志格式
  • 本文小结


概述

对于xml日志文件的配置,大多数人第一次接触时有一种望而生畏的感觉,其实如果仔细分析,会发现核心的部分只有三个元素:appender、logger、root

在这里插入图片描述
通过上图我们可以清晰的了解整个xml文件的元素及功能。

其中configuration是根元素,必须的;logger和root可视为同一类,都是日志组件;logger定义日志从哪里(包)获取以及级别;appender配置日志格式、如何过滤、文件处理等。property和contextName元素,分别用来定义变量和应用上下文名称,非必须。

先通过一个简单的日志模板,从视觉上感受一下:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %
      logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  <logger name="chapters.configuration" level="INFO"/>
  <root level="DEBUG">          
    <appender-ref ref="STDOUT" />
  </root>  
</configuration>

上述实例定义了控制台输出debug级别日志的配置。下面对相关的元素进行逐一讲解。


configuration元素

logback.xml配置文件的基本结构可以描述为configuration元素,包含零个或多个appender元素,后跟零个或多个logger元素,后跟最多一个root元素(也可以没有)。

根元素configuration有三个属性:

  • debug:默认为false,若设置为true,则打印出logback内部日志信息。
  • scan:默认值为true,若设置为true,配置文件如果发生改变,将会被重新加载。
  • scanPeriod:与scan配合使用,当scan为true时,此属性生效,默认的时间间隔为1分钟,设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。如可以设置为scanPeriod="30 seconds"每30秒检测一次。

定义上下文名称

contextName元素,每一个日志组件(logger)都会关联到日志上下文,默认上下文名称是’default’,用于标识应用,如果多个应用输出到同一个地方,就有必要使用%contextName来区别。

上线文的配置直接在configuration元素下:

<configuration>
    <contextName>HelloWorld-log</contextName>
</configuration>

经过定义之后,在其他property属性或appender中便可通过“%contextName”来获取和使用该上下文名称了。


定义变量

通过property元素可定义变量。它有name和value两个属性。变量可以使“${name}”来使用变量。作用类似于代码中的常量字符串,定义之后公共地方便可以统一使用。如日志文件名称前缀、日志路径、日志输出格式等。

<configuration>
    <property name="log.path" value="./log" />
</configuration>

上面便是定义了日志的根路径的变量。

如果是在Spring或SpringBoot项目当中,想让value值是通过配置文件获取,可使用springProperty来定义。

<springProperty scope="context" name="log.path" 
source="catalina.base"/>

其中source指定的catalina.base便是在application.properties当中配置变量。此配置还是比较常用的,可以做到灵活区分环境。


appender组件

appender组件用来定义日志输出格式,日志如何过滤以及日志文件的处理。appender的结构如下:

在这里插入图片描述
appender的属性有name和class。name指定appender名称,后面使用该appender是也是通过名称来指定。

class属性指定要实例化的appender类的完全限定名称。appender类默认有以下几种:

  • ConsoleAppender:日志输出到控制台,类名ch.qos.logback.core.ConsoleAppender。
  • FileAppender:日志输入到文件,类名ch.qos.logback.core.FileAppender。
  • RollingFileAppender:滚动记录文件,FileAppender的子类,当符合条件(大小、时间),日志进行切分处理。类名:ch.qos.logback.core.rolling.RollingFileAppender。

appender元素可以包含零个或一个layout元素,零个或多个encoder元素以及零个或多个filter元素。

实战中ConsoleAppender及RollingFileAppender使用较多,若需要自定义如把日志输出到消息队列,可以自定义实现AppenderBase接口。

ConsoleAppender上面已经有示例,主要作用就是将日志输出到控制台,并通过pattern元素指定了输出的格式。下面重点看一下RollingFileAppender的配置。


RollingFileAppender配置

RollingFileAppender是FileAppender的子类,扩展了FileAppender,具有翻转日志文件的功能。

例如,RollingFileAppender可以记录到名为log.txt文件的文件,并且一旦满足某个条件,就将其日志记录目标更改为另一个文件。

RollingFileAppender通常包括File、filter,rollingPolicy,encoder和layout元素。

encoder用来指定日志的输出格式及编码等:

<!-- 文件输出日志格式 -->
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} 
%contextName [%thread] %-5level %logger{36} - %msg%n" />
<appender>
    <!--日志文件输出格式-->
    <encoder>
        <pattern>${FILE_LOG_PATTERN}</pattern>
        <charset class="java.nio.charset.Charset">UTF-8</charset>
    </encoder>
</appender>

file元素用来配置日志的路径和名称,一般把路径和文件名前缀定义到变量(property中)。

<encoder>
    <!-- 正在记录的日志文件的路径及文件名 -->
    <file>${log.path}/log_error.log</file>
</appender>

${log.path}获取的便是前面属性中定义的变量。

appender中可以有多个filter元素,比如用ThresholdFilter来过滤低于指定临界值的日志;用LevelFilter来过滤日志级别。以LevelFilter为例:

<!-- 过滤器,只记录debug级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>DEBUG</level>
    <OnMismatch>DENY</OnMismatch>
    <OnMatch>ACCEPT</OnMatch>
</filter>

其中level指定日志级别,onMath指定符合过滤条件的操作接收(ACCEPT),onMismatch指定不符合条件的拒绝(DENY)。

如果需要将不同级别的日志输出到不同的日志文件,那么就需要配置多个filter,每个filter像上面一样指定level级别:DEBUG,INFO,WARN和ERROR。

通常情况下,日志输出会配置三个,一个控制台输出用于开发阶段;一个INFO及以上级别的日志输出,可追踪相应的生产日志;一个单独ERROR级别的日志输出,方便快速检查出异常日志。

rollingPolicy用于配置滚动策略,支持TimeBasedRollingPolicy、SizeAndTimeBasedRollingPolicy、FixedWindowRollingPolicy、SizeBasedTriggeringPolicy。

分别是基于时间滚动、基于大小和时间滚动、固定窗口滚动和大小触发。其中FixedWindowRollingPolicy一般和SizeBasedTriggeringPolicy同时使用。下面以TimeBasedRollingPolicy为例,以天为单位输出日志,每天一个日志。

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!-- 日志输出格式 -->
    <fileNamePattern>${log.path}/debug.%d{yyyy-MM-dd}.log</fileNamePattern>
    <!-- 日志保留天数 -->
    <maxHistory>30</maxHistory>
</rollingPolicy>

fileNamePattern指定日志的路径及名称,此处是按日期输出,即%d{yyyy-MM-dd}格式。maxHistory表示日志最多保留天数,存活超过30天的日志会被删除。


logger配置

logger用来设置某一个类或者某个包的日志输出级别、以及关联的appender。

logger包含三个属性:

  • name:要输出日志的包名或者类名,比如com.secbro2。必选项。
  • level:设置日志级别,允许一个不区分大小写的字符串值TRACE,DEBUG,INFO,WARN,ERROR,ALL或OFF。如果未设置,则logger会向上继承最近一个非空级别。可选项。
  • additivity:是否将日志向上级传递,默认为 true。可选项。

logger通过1个或多个子节点appender-ref来控制日志的输出。

<logger name="org.springframework" level="WARN"/>
<logger name="com" level="debug" />

上面示例表示org.springframework包下的日志以warn级别输出,com包下的日志以debug级别输出。

<logger name="com.secbro2" level="info" additivity="true">
    <appender-ref ref="CONSOLE" />
</logger>

上面的示例对指定包指定appender进行日志控制,由于设置了info级别,additivity为true,而且关联CONSOLE的appender,因此info以上级别的日志会输出到控制台。

同时会把日志上传到父级,即root。若root也有配置CONSOLE的输出的话,会在控制台输出两次。additivity为false,则不会。


root配置

root元素配置根记录器。它是一个特殊的logger,是所有logger的根节点,只有一个属性level,默认为DEBUG 。

<root level="info">
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="LOGSTASH" />
    <appender-ref ref="INFO_FILE" />
    <appender-ref ref="ERROR_FILE" />
</root>

level属性的值可以是不区分大小写的字符串TRACE,DEBUG,INFO,WARN,ERROR,ALL或OFF之一。root元素可以包含零个或多个appender-ref元素;被引用的每个appender都被添加到根记录器中。

如果是基于SpringBoot项目,针对不同环境(profile)有不同的日志输出,比如开发(dev)环境只输出CONSOLE的,生产环境(prod)只输入info和error,那则可用到Spring支持的profile机制。对应的元素为springProfile。

profile的值与springboot中配置文件的spring.profiles.active值进行对照。

<!-- 开发环境 -->
<springProfile name="dev">
    <logger name="com" level="debug" />
    <root level="info">
        <appender-ref ref="CONSOLE" />
    </root>
</springProfile>
<!-- 测试环境+生产环境 -->
<springProfile name="test,prod">
    <logger name="com" level="info" />
    <root level="info">
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>
</springProfile>

当引入了springProfile,我们可以看到root元素可以出现多次了,但还是保证了一个环境只有一个root元素的要求。springProfile的name对应spring.profiles.active的值,多个值用逗号分隔。


ELK的配置

如果项目中的日志采用的是基于ELK(Elasticsearch,Logstash,Kibana三个开源软件的缩写)来进行日志管理。则可以在pom文件中引入logstash-logback-encoder依赖。

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>5.1</version>
</dependency>

然后在logback-spring.xml中配置对应的appender:

<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>debug</level>
    </filter>
    <destination>192.168.0.11:5061</destination>
    <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
        <customFields>{"project": "springboot-logback-elk"}</customFields>
    </encoder>
</appender>

该appender的使用与其他appender的使用无异。主要使用了LogstashTcpSocketAppender类来完成与Logstash的通信。其中destination为Logstash提供的服务地址。customFields为自定义的参数,便于Logstash识别日志是从哪个业务系统传输过来的。


输出logback状态数据

某些时候为了了解logback配置文件加载情况,配置中对应的appender、logger的装载情况等,我们需要启用logback状态数据的输出。这也是logback官网强烈推荐的,可以帮助我们排除诊断一些问题。

启用状态数据输出有两种方式:

  • 在根元素(configuration) 中设置属性debug=“true”。
  • 添加元素(statusListener),class使用OnConsoleStatusListener。如下:
<!-- 输出logback的本身状态数据 -->
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />

两种方式选其一即可。第一种方式的debug与配置文件中的日志级别没有关系,只用于表示输出状态数据。


异步输出日志

前面讲到的appender,日志输出到文件是同步输出的,即每次输出都会直接写IO到磁盘文件。对于高并发的应用,会产生一定的阻塞,造成不必要的性能损耗。

logback提供了日志异步输出的AsyncAppender。处理方式也很简单,添加一个基于异步写日志的appender,并指向原配置的appender即可:

<!-- 异步输出 -->
<appender name="ASYNCDEBUG" class="ch.qos.logback.classic.AsyncAppender">
    <!-- 默认如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志,若要保留全部日志,设置为0 -->
    <discardingThreshold>0</discardingThreshold>
    <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
    <queueSize>1024</queueSize>
    <!-- 添加附加的appender,最多只能添加一个 -->
    <appender-ref ref="DEBUGFILE"/>
    <includeCallerData>true</includeCallerData>
</appender>

<!-- 异步输出关联到root -->
<root level="DEBUG">
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="ASYNCDEBUG" />
    //...
</root>

AsyncAppender的实现原理是通过阻塞队列(BlockingQueue)来避免日志直接输出到文件,先把日志事件输出到BlockingQueue中,然后启动一个新的worker线程,主线程不阻塞,worker线程则从队列中获取需要写的日志,异步输出到对应的位置。


代码中的日志格式

在日常使用日志时,可以通过最开始的示例定义Logger对象,然后调用其对应级别的日志输出。当然,如果采用Lombok的情况下,可直接类上使用@Slf4j注解来自动注入log属性,不用再声明:

private static final Logger log = LoggerFactory.getLogger(LogbackController.class);

替换为:

@Slf4j
@RestController
public class LogbackController {

}

其他内容不变。

而在日志输出格式也有多种,其中最不可取的形式是如下模式的日志输出:

Object entry = new SomeObject(); 
logger.debug("The entry is " + entry);

这种模式会导致即使采用info基本输出,debug中的对象toString和字符串拼装依旧会处理。建议采用如下模式输出:

Object entry = new SomeObject(); 
logger.debug("The entry is {}.", entry);

此时,如果日志输出级别为info,则不会处理对象的toString和字符串的拼接。

logback作者进行测试得出:第一种和第二种写法输出结果相同。但在禁用日志记录语句的情况下,第二种将比第一种写法优于至少30倍。


本文小结

到此,关于logback日志框架的讲解告一段落,如果你还想了解更多底层原理和一些表达式,建议看一下官方的手册,虽然是英文的,但还是比较全面的。

本文用巨大篇幅,描述了logback日志常见的使用场景,想必读到此处时,原来在那复杂的日志配置文件已经变得十分简单吧。赶快尝试一下吧。用了两天写完这篇文章,多多支持,你懂得该怎么做的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

语义分割大模型RSPrompter论文阅读

论文链接 RSPrompter: Learning to Prompt for Remote Sensing Instance Segmentation based on Visual Foundation Model 开源代码链接 RSPrompter 论文阅读 摘要 Abstract—Leveraging vast training data (SA-1B), the foundation Segment Anything Model (SAM) propo…

遗传算法(GA)优化后RBF神经网络优化分析(Matlab代码实现)

目录 1 遗传算法 2 RBF神经网络 3 Matlab代码实现 4 结果 1 遗传算法 遗传算法是一种模拟自然界进化过程的优化算法。它通过模拟生物进化的遗传、交叉和变异等过程&#xff0c;来搜索最优解或近似最优解。 遗传算法的基本步骤如下&#xff1a; 初始化种群&#xff1a;随机生成…

SPSS读取纯文本文件

纯文本文件是通用的一种格式文件&#xff0c;根据纯文本文件中数据的排序方式&#xff0c;可以将其分为自由格式和固定格式。自由格式文本文件的数据项之间必须有分隔符&#xff0c;固定格式数据项之间不需要分隔符。 1.以自由格式读取数据 &#xff08;1&#xff09;选择“文…

自然语言处理从入门到应用——预训练模型总览:预训练模型的拓展

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 相关文章&#xff1a; 预训练模型总览&#xff1a;从宏观视角了解预训练模型 预训练模型总览&#xff1a;词嵌入的两大范式 预训练模型总览&#xff1a;两大任务类型 预训练模型总览&#xff1a;预训练模型的拓展 …

data和filter协议文件包含

实验目的 通过本实验&#xff0c;了解php封装伪协议&#xff0c;掌握filter协议和data协议的用法 实验环境 操作机&#xff1a;kali 靶机&#xff1a;Windows Server 2003 实验地址&#xff1a;http://靶机ip/exp/include2/filter/ http://靶机ip/exp/include/include3.php…

软件测试常用设计模式

设计模式的重要原则就是&#xff1a;高内聚、低耦合&#xff1b;通常程序结构中各模块的内聚程度越高&#xff0c;模块间的耦合程度就越低。 数据驱动测试&#xff1a;Data Driven Testing&#xff0c;简称DDT&#xff1b; 数据驱动指的是从数据文件&#xff08;如数据库、Ex…

ElasticSearch学习02——Kibana安装

ElasticSearch学习02——Windows下Kibana安装 Kibana是界面化的查询数据的工具&#xff0c;下载时尽量下载与ElasicSearch一致的版本。 1、下载对应版本的Kibana ​ 有了ElasticSearch安装的经验&#xff0c;我们发现了ES和JDK有着版本对应的关系&#xff0c;Kibana和ES共同为…

一文了解PoseiSwap的质押系统

PoseiSwap 正在向订单簿 DEX 领域深度的布局&#xff0c;并有望成为订单簿 DEX 领域的早期开创者。PoseiSwap 是行业内首个模块化 Layer3 架构链 Nautilus Chain 上的首个 DEX &#xff0c;Nautilus Chain 具备行业内最快的 EVM&#xff0c;支持以模块化的形式构建定制化开发&a…

【macOS 系列】如何调整启动台图标大小和行数

1、使用指令&#xff0c;这是隐藏的技巧&#xff0c;在控制台输入如下指令 defaults write com.apple.dock springboard-rows -int 6 defaults write com.apple.dock springboard-columns -int 8 defaults write com.apple.dock ResetLaunchPad -bool TRUE killall Dock以上表…

初始Liunx线程

文章目录 前言1.初始Liunx下线程2.关于虚拟地址的补充知识3.线程的相关特点1.线程的优点2.线程的缺点3.线程异常4.线程和进程的比较 4.线程相关操作接口线程控制相关接口 5.关于线程id的理解 前言 本文主要是对Liunx之下线程的前置知识铺垫&#xff0c;同时也是对之前进程的相…

EasyCVR如何实现国标级联无人机推送的RTMP推流通道?

EasyCVR视频融合平台基于云边端一体化架构&#xff0c;可支持多协议、多类型设备接入&#xff0c;包括&#xff1a;NVR、IPC、视频编码器、无人机、车载设备、智能手持终端、移动执法仪等。平台具有强大的数据接入、处理及分发能力&#xff0c;可在复杂的网络环境中&#xff0c…

ZYNQ——脉宽调制之呼吸灯实现

文章目录 原理简介实验代码软件仿真板上验证 原理简介 呼吸灯的实现过程就是把不同占空比的脉冲输出后加在LED上&#xff0c;LED灯就会显示不同的亮度&#xff0c;通过不断地调节方波的占空比&#xff0c;LED灯的亮度也会跟着变化&#xff0c;看起来就像是“呼吸”一样。 要得…

爬虫小白入门在服务器上-部署爬虫或者开服务接口并供给他人访问

目录 一、准备工作-服务器1、先准备一个服务器&#xff08;以阿里云为例子&#xff09;2、开通服务端口号访问权限 二、准备工作-Xshell登录服务器1、xshell基本登录操作2、xftp基本操作 三、部署代码到服务器上1、部署一个python爬虫脚本在服务器上定时运行等2、部署一个pytho…

【面试常见】JS继承与原型、原型链

前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 在 JavaScript 中&#xff0c;继承是实现代码复用和构建对象关系的重要概念。本文将讨论原型链继承、构造函数继承以及…

SONY索尼MP4视频变RSV文件修复方法

索尼MP4变RSV的原因分析 索尼新型号相机或者摄像机&#xff0c;如SONY A7S3&#xff0c;A7M4&#xff0c;FX3, FX6, FX9等&#xff0c;如果录像过程中有发生如下异常情况&#xff0c;如断电&#xff0c;死机&#xff0c;电量不足&#xff0c;机器摔倒&#xff0c;非常规操作&a…

【接口测试】Postman —— 接口测试知识准备

1.0 前言 ​应用程序编程接口&#xff08;Application Programming Interface, API&#xff09;是这些年来最流行的技术之一&#xff0c;强大的Web应用程序和领先的移动应用程序都离不开后端强大的API。API技术的应用给系统开发带来了便利&#xff0c;但也对测试人员提出了更高…

CentOS7下载并安装mysql-8.0.33

CentOS7下载并安装mysql-8.0.33 一、官网下载mysql-8.0.33 MySQL下载路径 MySQL :: Download MySQL Community Server 自己百度mysql官网下载的话直接按照完整路径指示下载即可&#xff0c;如果点击上面的连接下载mysql的话&#xff0c;直接按照4、5、6步骤选择适合自己linu…

旅游卡景区购票小程序开发定制

旅游业的蓬勃发展&#xff0c;越来越多的景区开始推出自己的旅游卡&#xff0c;以吸引更多的游客前来观光。同时&#xff0c;为了更加便捷地服务游客&#xff0c;许多景区也开始启用小程序来进行门票售卖和游客管理。针对这种情况&#xff0c;专业的小程序开发公司推出了定制旅…

自定义注解,基于redis实现分布式锁

一、如何实现自定义注解 1.1、注解的基础知识 实现自定义注解其实很简单&#xff0c;格式基本都差不多。也就参数可能变一变。 Retention&#xff1a;取值决定了注解在什么时候生效&#xff0c;一般都是取运行时&#xff0c;也就是RetentionPolicy.RUNTIME。 Target&#xff…

初识Go语言25-数据结构与算法【堆、Trie树、用go中的list与map实现LRU算法、用go语言中的map和堆实现超时缓存】

文章目录 堆Trie树练习-用go中的list与map实现LRU算法练习-用go语言中的map和堆实现超时缓存 堆 堆是一棵二叉树。大根堆即任意节点的值都大于等于其子节点。反之为小根堆。   用数组来表示堆&#xff0c;下标为 i 的结点的父结点下标为(i-1)/2&#xff0c;其左右子结点分别为…