再严重的Log4j2 漏洞也伤害不了Java  

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"12 月 10 日凌晨,Apache 开源项目 Log4j 的远程代码执行漏洞细节被公开,由于 Log4j 的广泛使用,该漏洞一旦被攻击者利用会造成严重危害。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Log4j 是一个被许多 Java 应用程序使用的库,它是迄今为止最普遍的 Java 库之一。Log4j安全问题围绕 Log4j 库中的一个错误展开,该错误可能允许攻击者在使用 Log4j 写出日志消息的系统上执行任意代码。这个安全漏洞影响广泛,该漏洞一旦被攻击者利用会造成严重危害。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"随着Log4j安全漏洞问题的持续发酵,一些天天唱衰Java的家伙,又开始借助这一漏洞问题将矛头指向Java。他们总爱发文发帖、强调这种已经拥有25年历史的顶级编程语言就快不行了。不过每次Java都能挺过来,继续为全球无数开发者服务。这里我先要承认,不少安全厂商针对log4j2漏洞利用原理发布的文章确实意义重大。这个安全问题确实值得大家保持关注,也推荐各位尽快根据建议审查自己的Java项目是否存在隐患。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"在本文中,我想着重聊聊Java生态系统,探讨日志记录框架是什么、为什么\/该怎么使用这些框架,以及开发团队要如何观察并控制自己JVM的活动模式。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Java开发者们的安全责任"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Java开发者们应该如何保证安全性?答案很简单——只要快速修复JDK和库,我们就能规避大多数潜在的普遍性违规问题。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"修复库(必选)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"一旦发现库内存在漏洞,最有效的方法当然是修复库以消除漏洞。若不及时修复,你的应用程序很可能被黑客入侵,攻击者将获得对目标系统及其数据的完全访问权限。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"而无论面对什么状况,修复都是最有效的应对手段。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"日志框架可以来自任何依赖项——既可以是传递依赖项(由其他库添加),也可以是直接依赖项(由你自己添加)。我们可以使用Contrast Community Edition等分析工具检查当前依赖项及其他自定义漏洞。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"此外,Maven dependency tree (dependency:tree) 与 "},{"type":"link","attrs":{"href":"https:\/\/docs.gradle.org\/current\/userguide\/viewing_debugging_dependencies.html","title":null,"type":null},"content":[{"type":"text","text":"Gradle dependency tree"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"也都是很好的开源依赖项分析工具。NetBeans等IDE则提供依赖项关系图可视化工具。只要升级至2.15.0或更高版本,log4j2漏洞就不会再骚扰各位。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"按照Java安全基准(推荐、定期)修复JRE"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"各个Java主版本都会维护一套持续性的安全基准。由于JDK每个季度都会通过新一轮安全改进实施修复,所以这套基准也在持续前进。换言之,任何低于当前安全基准的Java安装包都包含某些已知安全问题,应立即进行更新。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"当然,这只是标准的安全最佳实践,与log4j2库漏洞没有直接关系、也解决不了这个漏洞。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"但开发团队仍然应该使用Foojay Disco API自动监控安全基准并升级现有系统。开发人员可以将其与GitHub操作匹配起来,确保代码中的每个build都切实引入了最新安全更新。而一旦安全事件出现,升级JRE与代码的重构与重新部署也将同步进行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Java安全基准会在每年1月、4月、7月和10月最靠近17号的那个星期二迎来更新。详细信息请参考Oracle重要补丁更新计划,具体方式与OpenJDK漏洞组保持相同。当然,有时候即使没有大问题、官方也可能提供计划外的安全更新。Log4j2并不属于此类。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"下面我们以Java 11中的安全基准配置为例:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"jobs:\njava11:\nruns-on: ${{ matrix.os }}\nstrategy:\nmatrix:\nos: [ubuntu-latest, macos-latest, windows-latest]\nupdate: [x]\npackage: [jdk, jre]\nfail-fast: false\nmax-parallel: 4\nname: ${{ matrix.package }} 11.0.${{ matrix.update }}, ${{ matrix.os }}\nsteps:\n- uses: actions\/checkout@v1\n- name: Set up JDK 11 Zulu\nuses: foojayio\/setup-java@disco\nwith:\njava-package: ${{ matrix.package }}\njava-version: 11.0.${{ matrix.update }}\ndistro: zulu\n- name: java -version\nrun: java -version"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"定期检测自定义安全漏洞(测试中,推荐)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"自动化安全工具能帮助我们在缺乏相关知识时仍准确捕捉到安全漏洞。通过将集成代理添加至Java应用程序当中,大家即可对应用程序中记录的安全信息进行被动检测。与前文提到的分析依赖项编号以确定是否存在漏洞的工具不同,这些自动化安全工具虽然也会跟踪同样的依赖项信息,但会通过集成分析器告知各现有库间的组合效果、特别是配合使用是否安全。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"例如,集成分析器并不会简单查看是否存在log4j2漏洞及其版本,而是检测远程输入记录功能是否会被攻击者所控制。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"此外,Contrast Community Edition等免费分析工具也能捕捉log4j2零日漏洞及其他多种安全缺陷的行踪,例如:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"我的应用程序中是否包含SQL注入缺陷,例如在Hibernate、JBDC或者其他位置?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"远程攻击者能否控制发送至Runtime.exec的任何输入,进而导致命令注入漏洞?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"我的应用程序中使用到哪些加密算法,具体用在何处、是否符合适当的安全标准?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"我们是否正以某种非常规、有风险的方式组合不同库,例如OGNL输入解析?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"使用JDK Flight Recorder监控安全事件"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"JDK Flight Recorder是各类现代OpenJDK发行版中普遍提供的性能分析工具,能够以低资源成本提供安全信息。开发团队可以使用JDK Flight Recorder记录下诸多IO操作,例如JRE访问过哪些文件、或者哪些类与反序列化配对。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"通过使用JDK Flight Recorder监控Java应用程序事件,并将事件流传输至安全信息与事件管理(SIEM)系统当中,Java团队即可监控异常行为并\/或是将已知安全类同Java反序列化过滤器相配对,因此防止漏洞利用行为。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"哪些安全努力不值得尝试"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"以log4j2场景为例,Web应用程序防火墙(WAF)等类似的网络防御方案虽然在短期内会有一定效果,但整体表现不佳而且工作量极为巨大。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"网络防御成效捉急。大家可能都听过网上流传的段子,有人用Photoshop精心设计出一张看似正常、似藏玄机的车牌,识别系统一扫就会遭遇注射攻击。这办法绝了,因为开发者知道车牌识别系统会尝试解析和记录一切通过计算机视觉捕捉到的内容,而且这部分注入数据压根不用经过网络层。同样的,大多数应用程序也会有针对性地使用部分数据、解码数据并记录下各类细节。很明显,任何网络工具都没办法覆盖到如此广泛的攻击面。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"监控并跟踪攻击者,第一时间屏蔽其IP同样效果不佳。虽然有些组织会坚持维护一套潜在攻击者清单,但AWS IP之所以被命名为Elastic(弹性),正是因为它们会定期更改。即使拉黑一个,对方要么可以等自然解禁、要么就是换个IP继续攻击。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"系统属性与动态补丁:效果尚可"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"我们可以使用几个系统属性与补丁控制住log4j2的肆意活动。如果暂时无法更新库或者依赖项,那这些就是最合理的过渡性安全问题。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"两项Java系统属性:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Dcom.sun.jndi.rmiobject.trustURLCodebase=false"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Dcom.sun.jndi.cosnaming.object.trustURLCodebase=false"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"将它们设置为false即可阻止远程加载。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"另有一个动态补丁能够接入当前运行的JVM并执行修复。它的问题是,我们每次启动JVM都需要再次运行此补丁。在一部分用例中这样就够了,只是肯定不如直接更新库来得方便。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Java是如何处理日志记录的?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Java开发者通常会从多种日志记录系统和外观中做出选择。随着社区的多年发展、合并和交融,各类日志记录框架往往已经能够彼此协同运作:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/docs.oracle.com\/javase\/9\/docs\/api\/java\/lang\/System.html","title":null,"type":null},"content":[{"type":"text","text":"System Logger"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" (2017年,推荐)在JDK 9中被首次引入。它改进了JDK Logger的API,并提供类似于SLF4j的外观,能够将JDK日志重新定向至应用程序团队指定的记录器处。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"JDK Logger (2004年)于Java 1.4版本中被引入。它特别常见,只是API显得有点陈旧了。虽然也能用,但不像其他日志记录框架那么灵便。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/logging.apache.org\/log4j\/2.x\/","title":null,"type":null},"content":[{"type":"text","text":"Log4j与Log4j2"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 属于社区开发的记录器。它们改进了API,让团队能够轻松控制需要记录的内容、检索特定数据何时出现在哪些层级。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"http:\/\/logback.qos.ch\/","title":null,"type":null},"content":[{"type":"text","text":"Logback"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 与 "},{"type":"link","attrs":{"href":"http:\/\/www.slf4j.org\/","title":null,"type":null},"content":[{"type":"text","text":"SLF4j"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 也是两款颇具人气的记录器。SLF4J属于一套相对简单的日志记录外观,可帮助团队管理其他多种记录器——库维护人员将直接登录到SLF4J,之后再由应用程序开发人员具体配置要使用哪些底层记录器提供统一的输出结果。除了高质量AIP之外,二者还最大限度减少了我们需要面对的依赖项。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/docs.jboss.org\/process-guide\/en\/html\/logging.html","title":null,"type":null},"content":[{"type":"text","text":"JBoss Logger"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 是JBoss生态系统中的另一款流行记录器,运行状态稳定且速度很快。它现在已经能够支持Quarkus等多种其他日志记录框架。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Apache Commons-Logging(2002年)的历史比JDK Logger更长,也启发了后来诸多API。它的最后一个版本发布于2014年,之后随着从单一项目向跨项目API的用户趋势变化而没落。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2022年最推荐的Logger方案"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"对于依赖项较少、发布时间不长的新兴项目,这里建议大家优先考虑System Logger。对于包含大量依赖项的项目,我们则建议继续遵循大部分依赖项的对接的既有记录器、或者使用统一的日志记录外观(门面)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"如果你之前并没有使用任何记录器,则可以把System Logger当成是具有良好API的JDK Logger来使用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"参考链接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoworld.com\/article\/3644492\/how-to-detect-the-log4j-vulnerability-in-your-applications.html","title":null,"type":null},"content":[{"type":"text","text":"https:\/\/www.infoworld.com\/article\/3644492\/how-to-detect-the-log4j-vulnerability-in-your-applications.html"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/foojay.io\/today\/log4j-isnt-killing-java\/","title":null,"type":null},"content":[{"type":"text","text":"https:\/\/foojay.io\/today\/log4j-isnt-killing-java\/"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章