logback,log4j,log4j2,commons-logging和java.util。日志记录是Java系统的所有日志框架。不同的类库也可以选择使用不同的日志框架,从而导致统一的管理困难。
SLF4J只是一个日志标准,仍然需要实际的日志框架。日志框架本身并未实现SLF4J API,因此需要进行前转换。日志本身是根据SLF4J API标准实现的,因此无需绑定模块进行转换。
尽管Log4J桥可用于接收SLF4J,但也可以通过实现SLF4J来调整Log4J,并且也可以将其吸引到列,但不能同时使用它们,否则会发生死周期。JCL和JUL是一样的。
尽管该图中有4个灰色日志实施框架,但最多的业务开发是logback和log4j,由同一个人开发。logback可以将其视为改进的log4j版本,建议使用它,已经是社会主流。
Spring Boot的日志框架也是记录式的。
Spring-Boot-Starter模块依赖于Spring-Boot-Starter-Logging模块,而Spring-Boot-Starter-Logging自动引入了logback-classic(包括SLF4J和LogBack Log Frame)和SLF4J。
如何避免将记录作为系统性能瓶颈?这与磁盘(例如机械磁盘)IO的性能差和大量日志有关,并且日志非常大,如何记录日志。
定义以下日志配置。有两个appender:
控制台是一个consoleappender,用于记录带有时间标签的日志
将大量日志输出到文件中,日志文件将非常大。如果性能测试结果也混合在其中,则很难找到日志。因此,评估仪Filter用于根据标记过滤日志,并将过滤后的日志分别输出到控制台。输出测试结果的日志。
通过使用标记和评估仪,可以通过标签过滤日志。
测试代码:实现指定数量的记录的大日志,每个日志包含1MB字节的仿真数据,最后记录了标记的方法中的时间 - 耗尽的日志:时间为标记的方法:
执行该程序后,发现记录1,000 log和10,000 logs的呼叫时间为5.1和39s
对于记录文件日志的代码来说,这次太长了。
从outputStreamAppender继承
添加日志时,它直接写在outputStream中,这是同步记录日志
因此,大量日志可以耐用。我们可以意识到,当编写大量日志时,它不会影响业务逻辑和影响吞吐量的时间?
使用LogBack的ASYNCAPPENDER实现异步日志记录。
Asyncappender类似于装饰模式,在不更改类的原始基本功能的情况下添加新功能。此功能可以将异步范围连接到其他Appender并将其异步。
定义异步的appender异步。
记录1,000个日志和10,000个日志时间,为537ms和1019ms
异步日志是否如此高性能?不,因为它没有记录所有日志。
模拟缓慢的日志记录方案:首先,自定义从consoleappender继承的myslowappender,作为记录到控制台的输出记录器,并在编写日志时睡1s。
在配置文件中使用Asyncappender将MySlowAppender打包为异步日志记录
测试代码
默认队列的大小为256,在80%之后开始丢弃<=INFO级日志后,即可理解日志中为什么只有两百多条INFO日志了。
可能导致OOM
默认值256就已经算很小了,且discardingThreshold设置为大于0(或为默认值),队列剩余容量少于discardingThreshold的配置就会丢弃<=INFO日志。这里的坑点有两个:
queueSize、discardingThreshold和neverBlock三参密不可分,务必按业务需求设置:
以上日志配置最常见两个误区
再看日志记录本身的误区。
使用{}占位符,就不用判断log level了吗?
据不知名网友说道:SLF4J的{}占位符语法,到真正记录日志时才会获取实际参数,因此解决了日志数据获取的性能问题。 是真的吗?
验证代码:返回结果耗时1s
若记录DEBUG日志,并设置只记录>= info -level日志,该程序是否需要1 s?三种方法测试:
第一种方法称为“慢速”,因此需要1。而第二种方法是使用该地点占据记录的斜线。尽管此方法允许对象传递对象,但它没有明确缝合字符串,但它只是延迟(如果日志未记录,消除了)log参数对象.tostring()和字符串缝合时间花费时间。
在这种情况下,除非提前判断日志级别,否则必须应用缓慢的速度。因此,无法通过延迟参数值来求解日志数据采集的性能。
除了提前判断日志级别外,您还可以获取lambda参数的内容。但是,SLF4J API不支持lambda。因此,您需要使用log4j2 log api将lombok的@slf4j注释替换为@log4j2注释来提供lambda表达参数:
致电调试,签名供应商>当真正需要记录日志时,这些参数将被延迟:
因此,debug4不调用缓慢的方法
仅由Log4J2 API替换,实际日志记录仍然是logBack,这是SLF4J改编的好处。