当前位置: 首页 > 科技观察

到这里,你想要的高性能日志记录工具Log4j2

时间:2023-03-13 22:36:37 科技观察

Log4j已经介绍完毕,SLF4J已经介绍完毕,Logback也已经介绍完毕。你认为这是日志系列的结尾吗?不不不,我告诉你,还有一个Log4j2,顾名思义,就是Log4j的升级版,就像手机里的Pro版一样。作为一个写文章的工具人,或者叫打工仔,怎么可能写不完这最后一篇。Log4j、SLF4J、Logback之父——CekiGulcu,但Log4j2是个例外,它是Apache基金会的产物。SLF4J和Logback作为Log4j的替代品,在很多方面都做了必要的改进,那么为什么还需要Log4j2呢?只能说Apache基金会的开发者很闲,不,很勤奋,要不是他们精益求精的精神,这个编程世界该有多无聊,毕竟能轮到的轮子少了很多被使用“只是使用它”。上一篇文章提到,老板命令我把日志系统切换到Logback。我顺利交接了工作。老板很高兴,夸我这个工人很敬业。为了表达对老板的这份感谢,我决定偷偷试用一下Log4j2,虽然还不是成品,但可能会给项目带来一些隐患。可谁让我们成为了敬岗爱业的劳动者呢。01.Log4j2的强项是什么1)在多线程场景下,Log4j2的吞吐量比Logback高10倍,延迟降低几个数量级。这听起来像是吹牛,但这是官方的Log4j2吹牛。Log4j2的异步Logger使用无锁数据结构,而Logback和Log4j的异步Logger使用ArrayBlockingQueue。对于阻塞队列,多线程应用程序在尝试对日志事件进行排队时经常会遇到锁争用。下图说明了无锁数据结构在多线程场景下对吞吐量的影响。Log4j2可以随着线程数更好地扩展:具有更多线程的应用程序可以记录更多。其他日志记录库的总吞吐量保持不变或减少,因为由于锁争用而记录了更多线程。这意味着使用其他日志记录库,每个单独的线程将能够记录更少的日志。性能是Log4j2最大的亮点,至于其他方面的一些优势,比如下面这些,可以忽略不计。文本有多短意味着它有多不重要。2)Log4j2可以减轻垃圾收集器的压力。3)支持Lambda表达式。4)支持自动重载配置。02.Log4j2使用实例废话不多说,直接上手。理论知识有用,但不如动手实践。这也是我多年来养成的一个“不太好”的编程习惯:发现问题,解决问题,在实际操作中寻找理论基础。第一步是在pom.xml文件中添加Log4j2的依赖:org.apache.logging.log4jlog4j-api2.5org.apache.logging.log4jlog4j-core2.5(这个artifactId是还是log4j,2没有体现,但是体现在版本上,有点误认为是log4j)第二步是最简单的测试用例:importorg.apache.logging.log4j.LogManager;importorg.apache.logging.log4j.Logger;publicclassDemo{privatestaticfinalLoggerlogger=LogManager.getLogger(Demo.class);publicstaticvoidmain(String[]args){logger.debug("log4j2");}}运行Demo类,可以看到控制台上的以下信息:ERRORStatusLoggerNolog4j2configurationfilefound.Usingdefaultconfiguration:loggingonlyerrorstotheconsole.Log4j2甚至没有将“log4j2”打印到控制台并抱怨我们没有为其指定配置文件。在这一点上,我觉得还不如Logback,毕竟人是会输出的。这对于新手来说是非常不友好的,因为新手遇到这种情况往往会手足无措。虽然在日志中反映了ERROR,但是代码并没有编译或者运行错误。为什么不输出呢?作为一个编程老手,我不得不告诉你,这个时候最好探究一下why。怎么做?我们可以复制日志信息中的关键字,例如:“找不到log4j2配置文件”,然后在IntellijIDEA中搜索。如果你下载了源代码和文档,不出意外的话,你会在ConfigurationFactory类中找到这段话。可以在方法中设置断点,然后调试,就会看到下图的内容。从源码可以看出,Log4j2会寻找4种配置文件,后缀分别是properties、yaml、json和xml。前缀是log4j2-test或者log4j2。得到这个提示后,就可以进行第三步了。第三步,在资源目录下添加log4j2-test.xml文件(与Logback对比),内容如下:1)配置appender,即配置输出目的地的日志。有Console,你已经看到了上面典型的console配置信息。简单解释一下里面pattern的格式:%d{HH:mm:ss.SSS}表示输出时间以毫秒为单位%t输出当前线程名%-5level输出日志级别,-5表示左对齐,固定输出5个字符,不够就在右边补空格%logger输出记录器名称,最多36个字符%msg日志文本%n换行顺便加上其他常用的占位符:%F输出类文件名,比如Demo.java%L输出行号%M输出方法名%l语句输出行号,包括类名、方法名、文件名、行号%p输出日志级别%c输出包名,如果后面有{length.}参数,比如%c{1.},会输出注册的第一个字符,比如com.itwanger实际注册只会输出c.i再次运行Demo类,可以看到打印的log信息在控制台:10:14:04.657[main]DEBUGcom.itwanger.Demo-log4j22)配置Loggers,指定Root的日志级别,一个d指定要启用的Appender。3)自动重新加载配置。Logback支持自动reload配置,Log4j2也支持。启用此功能非常简单,只需在Configuration元素中添加monitorInterval属性即可。...请注意,该值应设置为非零,这在上面的示例中表示至少30秒后检查配置文件中的更改。最小间隔为5秒。03.Async示例除了Console,还有Async,可以异步写成文件的形式。典型的配置信息如下:%d%p%c[%t]%m%n相对于Logback的配置文件,Log4j2确实复杂。不太好用,就这么直白的说吧!但是我约好了,我必须含着泪去完成它。将此异步添加到Appenders:%d%p%c[%t]%m%n>再次运行Demo类,可以在项目根路径下看到一个debug.log文件,内容如下:2020-10-3009:35:49,705DEBUGcom.itwanger.Demo[main]log4j204、RollingFile示例当然Log4j和Logback我们都配置了RollingFile,Log4j2也是少不了的。RollingFile会根据Triggering(触发)策略和Rollover(过渡)策略来滚动日志文件。如果没有配置Rollover,则使用DefaultRolloverStrategy作为RollingFile的默认配置。触发策略包括基于cron表达式的CronTriggeringPolicy(来自希腊语,意为时间,用于配置周期性执行任务的时间格式);基于文件大小的SizeBasedTriggeringPolicy;基于时间的TimeBasedTriggeringPolicy。过渡策略包括默认过渡策略DefaultRolloverStrategy和直接写DirectWriteRolloverStrategy。总的来说,默认的transitionstrategy就够用了,功能也够强大。我们来看第一个基于SizeBasedTriggeringPolicy和TimeBasedTriggeringPolicy策略的配置示例,以及默认的DefaultRolloverStrategy策略:-MM-dd}-%i.log">%d%p%c{1.}[%t]%m%n<策略>为了验证文件Strategy的滚动,我们调整Demo类让它打印更多的日志:for(inti=1;i<20;i++){logger.debug("微信搜索"{}",回复关键字"{}",有惊喜哦","沉默王二","java");}再次运行Demo类,可以看到根目录下多了3个日志文件:结合日志文件名,和再看RollingFile的配置,就很好理解了。1)fileName用于指定文件名。2)filePattern用于指定文件名的模式,依赖于转换策略。由于配置文件中没有明确指定翻转策略,因此RollingFile启用默认的DefaultRolloverStrategy。先看DefaultRolloverStrategy的属性:再看filePatternrolling-%d{yyyy-MM-dd}-%i.log的值,其中%d{yyyy-MM-dd}很好理解,就是年、月、日;其中%i是什么意思?第一个日志文件名是rolling.log(最近的日志放这里面),第二个文件名是rolling-1.log除去日期,第二个文件名是rolling-1.log除去日期-2.log,根据这些信息,你能猜出规则吗?其实和DefaultRolloverStrategy中的max属性有关。目前使用的默认值为7。当要生成rolling-8.log时,删除rolling-1.log。您可以在Demo中调整日志输出量进行验证。3)SizeBasedTriggeringPolicy,基于日志文件大小的时间策略,大小以字节为单位,后缀可以是KB、MB或GB,例如20MB。再来看一个日志文件压缩的??例子,我们看一下配置:%d%p%c{1.}[%t]%m%nfileName的属性值中包含一个目录gz,表示所有的日志文件都会放在这个目录下。在filePattern的属性值上加一个gz的后缀,表示日志文件是要压缩的,也可以是zip格式。运行Demo后,在gz目录下可以看到如下文件:至此,Log4j2的基本使用示例已经完成。测试环境搞定了,我再问问老大要不要在生产环境使用Log4j2。04,日志手册到此结束,日志系统的全家桶,Log4j,SLF4J,Logback,Log4j2,都由我来搞定。也就是说,一个近两万字的PDF就诞生了!MD,我要成为肝帝!有了这个PDF,硬着头皮告诉领导或者老板,再也不用担心代码里乱打印log了。虽不扶墙,亦受制。贴个地址:链接:https://pan.baidu.com/s/1dPwsQhT5OMVapE7hGi7vww密码:fxxy偷偷告诉你,嫖的感觉舒服,快去下载吧!本文转载自微信公众号“沉默的王二”,可通过以下二维码关注。转载本文请联系沉默王二公众号。