logback之pattern详解以及源码分析

目录

(一)pattern关键字介绍

(二)源码分析


(一)pattern关键字介绍

%d或%date:表示日期,可配置格式化%d{yyyy-MM-dd HH:mm:ss}

%r或%relative:也是日期,不过显示的是相对时间,是相对于日志框架加载开始的时间,单位是ms。

%level或%le或%p:表示日志级别

%t或%thread:表示线程名

%lo或%logger或%c(小写c):表示logger的名称,即 LoggerFactory.getLogger传入的名称,如果传入的是class则为类全限定名。

%m或%msg或%message:表示日志消息

%C(大写C)或%class:日志写入调用所在类名

%M或%method:日志写入调用所在的方法

 %L或者%line:日志写入调用所在的行数

%F或者%file:日志写入调用所在的文件

%X或%mdc:mdc写入的信息,记得mdc设置后,需要在finally中删除,避免内存泄漏。

%ex或%exception或%throwable:异常信息

%rEx或%rootException:带根因的异常信息

%xEx或%xException或%xThrowable:显示继承的异常信息

显示的异常信息量:%rootException > %xException > %exception;如果pattern中没有指定异常显示,那么默认会在末尾添加异常显示,根据上下文中的packagingDataEnabled设置,如果为true,加的是%xException,false为%exception(默认为false); %nopex或%nopexception:表示不打印异常信息。%ex在有异常的情况下回自动添加,而如果配置了这个那么就不会输出异常,所以和%ex是互斥的

%cn或%contextName:日志上下文的名称

%caller:表示日志详细的调用链

%maker:显示日志的标记,marker主要用于日志的分类和过滤。打印日志时可以调带Marker参数的方法,实现Marker的传递。

%property: 显示配置,会先查日志上下文的配置,如果没有从系统配置中获取,如:%property{java.version}就是打印java版本

%n: 表示换行

以下面格式的pattern,我们打印一个带异常的日志,看看效果,也好对应:

%d{yyyy-MM-dd HH:mm:ss} -%r [%thread] %-5level %logger{50} %class.%method-%line %F [%X{logTrackId}][%cn] [%caller] [%marker] %property{java.version} - %msg%n

使用下面代码进行比较全的日志打印,这样和日志对照起来,对关键字就有了更具体的理解:

public void doNothing() {String logTrackId = UUID.randomUUID().toString();MDC.put("logTrackId", logTrackId);try {RuntimeException causeException = new RuntimeException("this is a cause exception");Marker marker = MarkerFactory.getMarker("basicMarker");ImpossibleLogger.warn(marker, "some exception happen:", new RuntimeException("this is encosing exception", causeException));} finally {MDC.remove("logTrackId");}
}

(二)源码分析

日志是如何根据pattern进行转化的呢?

下面我们看一下源码:

首先是<pattern>标签对应的PatternLayout类:这里定义了很多默认的转换器类:

可以看到关键字d和date都匹配的DateConverter。所以我们在pattern中定义的每个关键字都会有一个对应的转换器,既然是转换器那么一定会有转换的方法:convert,可以看一下DateConverter的convert方法,看一下它是如何转换的:

很简单只是把ILoggingEvent中获取时间戳,然后使用cachingDateFormatter进行转换,cachingDateFormatter实际上只是包装了一个SimpleDateFormat对象,因为其是线程不安全的,所以使用cachingDateFormatter将其包了一层,调用format时使用synchronized进行同步保证线程安全。

对于一个日志的格式化转换就是循环调用每个转换器然后将转换的信息添加到字符串中

那么转换器又是怎么加载到PatternLayout中的呢?可以看PatternLayoutBase.start方法,这个方法在Context初始化创建Pattern后会被调用。

核心的步骤有3个:

(1)创建一个解析器Parser,然后调用parse对pattern字符串进行解析,解析出的结果是一个Node层级对象,里面包含了%d、%thread等都被解析成对应的Node

(2)getEffectiveConverterMap获取有效的Converter集合,它主要把默认的转换器和以及context中PATTERN_RULE_REGISTRY存储自定义的转换器获取过来。

所以我们实际上可以通过往context中的PATTERN_RULE_REGISTRY这个key对应的map中写入自己的转换器类实现。key是关键字,值是自定义的转换器类名,而实现方式实际上是在配置文件中configuration节点下定义conversionRule标签,这个标签会被解析成converter,可参见ConversionRuleAction这个类

但要注意的是,xml的解析是有顺序的,所以conversionRule自定义的转换器需要在使用此转换器对应关键字的pattern之前,否则pattern解析时从PATTERN_RULE_REGISTRY获取不到对应的转换器。

(3)调用p.compile:这里就是转换器实际实例化创建的地方

第一步解析的Node有3中类型,分别是Node.LITERAL(字面量)、Node.COMPOSITE_KEYWORD(组合关键字)、Node.SIMPLE_KEYWORD(简单关键字)。字面量就是对应我们的pattern中的一些常量,如空格、-等会直接输出到日志中,不做转换。而组合转换器是比较复杂的转换器,会有子转换器的嵌套。我们常用的大部分都是SIMPLE_KEYWORD。

主要到DynamicConverter都会调用setFormattingInfo以及setOptionList,这些两个可能会被转换器用到。

如我们经常在%d后会加日期格式化yyyy-MM-dd HH:mm:ss,这个就会放到OptionList中,通过,分隔,如日期还可以设置时区%d{yyyy-MM-dd HH:mm:ss,GMT-8:00},这是OptionList中就有两个值

而%-5level中的-5则会设置到FormattingInfo,FormattingInfo主要设置关键字转换的字符串的最小长度和最大长度,用.分隔,如:%-5,7level,这里5就是最小值,7是最大值,表示日志级别最小显示长度为5,最大长度为7。最小值和最大值都可以带符号,最小值的正负号表示字符串长度不够时补齐的方向,-号是右边补齐,所以level如果是warn,那么不够5个字符串,那么右边会补一个空格。而最大值正负号则字符串超出,需要截取掉超出最大值的字符串,表示截取的方向,-号是截取左边的。

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

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

相关文章

【专题】2024年出口跨境电商促销趋势白皮书报告汇总PDF洞察(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p38722 在当今全球化加速演进、数字经济蓬勃发展的大背景下&#xff0c;跨境电商行业正以前所未有的态势重塑国际贸易格局&#xff0c;成为各方瞩目的焦点领域。 根据亚马逊发布的《2024年出口跨境电商促销趋势白皮书》&#xff0c;…

primevue的<Menu>组件

1.使用场景 2.代码 1.给你的menu组件起个引用名 2.<Menu>组件需要一个MenuItem[] 3.你要知道MenuItem[ ]的特殊的数据格式&#xff0c;就像TreeNode[ ]一样&#xff0c;数据格式不对是不渲染的。。。。 常用的属性就这几种&#xff0c;js语言和java不一样&#xff0c;J…

NVR小程序接入平台EasyNVR使用FFmpeg取流时提示错误是什么原因呢?

在视频监控系统中&#xff0c;FFmpeg常用于从各种源&#xff08;如摄像头、文件、网络流等&#xff09;获取流媒体数据&#xff0c;这个过程通常称为“取流”。 在EasyNVR平台中&#xff0c;使用FFmpeg取流是一种常见的操作。FFmpeg作为一款强大的开源多媒体处理工具&#xff…

Springboot 升级带来的Swagger异常

当升级到Springboot 2.6.0 以上的版本后&#xff0c;Swagger 就不能正常工作了, 启动时报如下错误。当然如果你再使用sping boot Actuator 和 Springfox, 也会引起相关的NPE error. (github issue: https://github.com/springfox/springfox/issues/3462) NFO | jvm 1 | 2022/04…

编译原理期末复习-3小时速通

教材使用&#xff1a; 第二章 形式语言理论 基本概念 句子&#xff1a;只包含终结符。&#xff08;基本上就是全部由小写字母组成&#xff09;句型&#xff1a;推导过程中出现的所有符号串都叫做句型。只包含终结符的句型叫做句子。子树&#xff1a;语法树的某个节点连同他向…

关于 覆铜与导线之间间距较小需要增加间距 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144776995 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

Spring Certified Professional 2024 (2V0-72.22)

关于认证 Spring Certified Professional (2V0-72.22) 认证可证明您在 Spring Framework 方面的专业知识&#xff0c;Spring Framework 是构建企业级 Java 应用程序的领先平台。此认证在全球范围内得到认可&#xff0c;并证明您在 Spring 的各个方面都具有熟练程度&#xff0c;…

Spring Bean 无法被扫描到的问题

问题复现 ● 使用如下包结构&#xff1a; ● 我们发现 HelloWorldController 失效了&#xff0c;无法找到 HelloWorldController 这个 Bean 了。这是为何&#xff1f; 案例分析 ● 对于 Spring Boot 而言&#xff0c;关键点在于 Application.java 中使用了 SpringBootAppli…

Linux umami网站统计工具自定义API开发

Linux umami网站统计工具自定义API开发 一、src/queries/analytics/下添加调用sql查询文件&#xff1a;二、src/queries/index.js文件中增加导出模块内容&#xff1a;三、src/pages/api/下根据目录添加接口方法文件&#xff1a;四、构建项目&#xff0c;启动。1、到umami目录&a…

libvirt学习

文章目录 libvirt 简介节点、Hypervisor和域libvirt 安装和配置libvirt的XML配置文件libvirt APIMain libvirt APIsError handlingSpecial specific APIs 建立到Hypervisor的连接libvirt API使用编译libvirt工具virshvirt-clonevirt-dfvirt-imagevirt-installvirt-topvirt-what…

自动化测试工具Ranorex Studio(七十八)-故障排除

故障排除 如果你有连接问题&#xff0c;请考虑以下潜在的问题来源&#xff1a; • 请确保被测系统&#xff08;移动设备&#xff09;和运行测试的机器&#xff08;安装Ranorex的&#xff09;是在同一网络中的。 设备上的Wi-Fi设置更改后&#xff0c;请务必重新启动设备。 •…

常用的linux命令介绍

Linux是一个强大的操作系统&#xff0c;它提供了许多命令行工具来帮助用户管理文件和目录、监控系统性能、以及执行各种系统管理任务。下面是一些常用的Linux命令&#xff0c;我会用简单的语言来解释它们的作用&#xff1a; 1. ls • 作用&#xff1a;列出目录内容。 • 比喻&a…

万里数据库GreatSQL监控解析

GreatSQL是MySQL的一个分支&#xff0c;专注于提升MGR&#xff08;MySQL Group Replication&#xff09;的可靠性及性能。乐维监控平台可以有效地监控GreatSQL&#xff0c;帮助用户及时发现并解决潜在的性能问题。 通过在GreatSQL服务器上安装监控代理&#xff0c;收集数据库性…

缓存管理自动化:JuiceFS 企业版 Cache Group Operator 新特性发布

近期&#xff0c;JuiceFS 企业版推出了 Cache Group Operator&#xff0c;用于自动化创建和管理缓存组集群。Operator 是一种简化 Kubernetes 应用管理的工具&#xff0c;它能够自动化应用程序的生命周期管理任务&#xff0c;使部署、扩展和运维更加高效。 在推出 Operator 之前…

Wireshark和科来网络分析系统

Wireshark 是一款功能强大的网络协议分析工具&#xff0c;主要用于捕获和分析网络流量&#xff0c;帮助用户排查网络问题、进行安全分析和学习网络协议。以下是 Wireshark 的基础使用指南&#xff1a; 1. 安装 Wireshark 访问 Wireshark 官网 下载并安装适合你操作系统的版本…

无穿戴动作捕捉系统技术解密及多元化运用

在当今科技飞速发展的时代&#xff0c;动作捕捉技术不断革新&#xff0c;无穿戴动作捕捉系统崭露头角。与传统粘贴标记点的动作捕捉技术相比&#xff0c;无标记点动作捕捉技术具有显著优势。它能够在确保高精度捕捉的前提下&#xff0c;以非接触的方式极大地提升被捕捉对象的表…

GPT分区 使用parted标准分区划分,以及相邻分区扩容

parted 是一个功能强大的命令行工具&#xff0c;用于创建和管理磁盘分区表和分区。它支持多种分区表类型&#xff0c;如 MBR&#xff08;msdos&#xff09;、GPT&#xff08;GUID Partition Table&#xff09;等&#xff0c;并且可以处理大容量磁盘。parted 提供了一个交互式界…

DevOps工程技术价值流:Ansible自动化与Semaphore集成

在DevOps的浪潮中&#xff0c;自动化运维工具扮演着举足轻重的角色。Ansible&#xff0c;作为一款新兴的自动化运维工具&#xff0c;凭借其强大的功能和灵活性&#xff0c;在运维领域迅速崭露头角。本文将深入探讨Ansible的特点、架构、工作原理&#xff0c;以及其应用场景&…

2025元旦源码免费送

我们常常在当下感到时间慢&#xff0c;觉得未来遥远&#xff0c;但一旦回头看&#xff0c;时间已经悄然流逝。对于未来&#xff0c;尽管如此&#xff0c;也应该保持一种从容的态度&#xff0c;相信未来仍有许多可能性等待着我们。 免费获取源码。 更多内容敬请期待。如有需要可…

嵌入式开发中的机器人表情绘制

机器人的表情有两种&#xff0c;一种是贴图&#xff0c;一钟是调用图形API自绘。 贴图效果相对比较好&#xff0c;在存储空间大的情况下是可以采用的。 自绘比较麻烦&#xff0c;但在资源和空缺少的情况下&#xff0c;也是很有用的。而且自绘很容易通过调整参数加入随机效果&…