当前位置: 首页 > 后端技术 > Java

log4j的替代者

时间:2023-04-01 15:02:11 Java

去年12月,由于log4j暴露出高危漏洞,对于Java开发者来说并不是什么好消息,尤其是Ops。前者必须用固定的Log4J版本重新打包他们的应用程序,而后者则必须重新部署。但是对于程序日志来说,就不仅仅是这样了。今天我们就来看看java系统自带的日志机制。简而言之,System.Logger是日志引擎的API。与其使用SFL4J的API并想实现它,不如使用System.Logger。Java9从Java9开始就开启了System.Logger,不过最近才知道,很遗憾。System.LoggerAPI此API与其他日志记录API略有不同:它避免了不同的日志记录方法,例如debug(),而是支持传递日志记录参数info()的单一方法。log()``级别System.Logger如果您没有在类路径上提供任何相应的实现,则默认为JUL。publicclassLoggerExample{privatestaticfinalSystem.LoggerLOGGER=System.getLogger("c.f.b.DefaultLogger");//1publicstaticvoidmain(String[]args){LOGGER.log(DEBUG,"Adebugmessage");记录器.log(INFO,"Helloworld!");}}获取记录器。运行上面的代码片段输出以下内容:2021年12月24日上午10:38:15c.f.b.DefaultLoggermainINFO:世界您好!与其他日志系统的广泛兼容性目前大多数应用程序使用Log4J2或SLF4J。两者都提供兼容的System.Logger实现。对于Log4J,我们需要添加两个依赖:org.apache.logging.log4jlog4j-core2.17.0org.apache.logging.log4jlog4j-jpl<版本>2.17.0Log4J实现了System.LoggerSystem.Logger对Log4J的支持。与上面相同的日志记录片段现在输出以下内容:11:00:07.373[main]INFOc.f.b.DefaultLogger-Helloworld!要改为使用SLF4J,需要添加以下依赖项:org.slf4jslf4j-simple2.0.0-alpha5org.slf4jslf4j-jdk-platform-logging2.0.0-alpha5基本的SLF4J实现。任何其他实现都可以,例如Logback。来自SLF4J的System.Logger支持。[main]INFOc.f.b.DefaultLogger-世界,您好!您自己的System.Logger实现System.Logger依赖于Java的ServiceLoader机制。log4j-jpl都包含slf4j-jdk-platform-logging一个META-INF/services/java.lang.System$LoggerFinder指向LoggerFinder实现文件。我们可以根据System.out目的创建自己的日志系统。\第一步是实现日志本身。publicclassConsoleLoggerimplementsSystem.Logger{privatefinalStringname;publicConsoleLogger(Stringname){this.name=name;}@OverridepublicStringgetName(){返回名称;}@OverridepublicbooleanisLoggable(Levellevel){returnlevel.getSeverity()>=Level.INFO.getSeverity();}@Overridepublicvoidlog(Levellevel,ResourceBundlebundle,Stringmsg,Throwablethrown){if(isLoggable(level)){System.out.println(msg);thrown.printStackTrace();}}@Overridepublicvoidlog(Levellevel,ResourceBundlebundle,Stringformat,Object...params){if(isLoggable(level)){System.out.println(MessageFormat.format(format,params));}}}然后,我们需要编写代码System.LoggerFinder:publicclassConsoleLoggerFinderextendsSystem.LoggerFinder{privatestaticfinalMapLOGGERS=newHashMap<>();//1@OverridepublicSystem.LoggergetLogger(Stringname,Modulemodule){returnLOGGERS.computeIfAbsent(name,ConsoleLogger::new);//2}}Pathtopreserveallexistinglogs:if如果不存在,创建一个记录器并存储它最后,我们创建一个服务文件:ch.frankel.blog.ConsoleLoggerFinder现在,运行相同的代码片段输出:Hello世界!结论虽然API比其他日志系统更成熟API更受限制,但System.Logger是一个不错的选择。它提供了属于JDK一部分的API。因此,它避免了SLF4J到Log4J2等其他第三方API的漏洞风险。为此,后期可以基于System.Logger实现系统日志功能。