log4j2自动删除_登录样式:log4j 2,上下文,自动清除…全部不附带任何字符串!...

log4j2自动删除

日志记录-保持操作的时间跟踪-对于任何关键任务系统,无论大小,都至关重要。 我们的Project-X框架也是如此 ,这就是为什么我们希望从一开始就正确地做到这一点。

基于我们在传奇的UltraESB上的登录经验, 上下文日志记录(每条日志行自动记录其原始逻辑上下文(例如,它来自特定单元还是来自基础框架))一直是我们期待的事情 。

我们已经知道log4j2通过其CloseableThreadContext实现提供了上下文日志记录 ,几乎包含了我们所需要的一切。 但我们需要更多:

  1. 我们需要一个合适的日志代码管理机制,其中每个日志行包含一个唯一的日志代码,分别表示子系统,模块(包),甚至是特定的日志语句的准确“指标”,这样我们就不再需要grep通过整个代码库,以找出bugger的来源。
  2. 我们需要注入具有特定前缀的环境变量和系统属性,以将其自动注入到日志上下文中,以便特定的应用程序可以将其运行时参数注入日志(例如,对于我们的Integration Platform ,为集群ID )。

我们还需要与log4j2无关,因为我们应该保留与log4j2分离的自由,并在需要时利用其他日志记录框架(例如logback )。 尽管我们可以利用第三方包装器(例如SLF4J),但找不到适合所有需求的包装器。

因此,与以前的UltraESB一样,我们用x-logging封装了log4j2,这是我们自己的日志记录实现。 x-logging由一个API和一组到实际日志框架(例如log4j2和logback)的绑定组成,其中一个可以在服务器启动时使用Java宝贵的旧ServiceLoader机制动态地插入。 这可以帮助我们避免将log4j2特定内容泄漏到我们的实现中,因为可以将基于log4j2的实现(以及因此log4j2本身)从编译时依赖项集合中完全删除。

来自我们团队的Ruwan (也是Project-X的发起者)利用log4j2进行了一段时间的入侵,最后提出了一个很酷的设计,可以自动传播日志行的当前上下文,即它是否源自平台(系统(也称为引擎 )或已部署的项目 (如果是后者),则是该项目的其他元数据(例如版本)。 最酷的部分是,一旦执行离开特定上下文,该上下文将自动清理。

如果您熟悉CloseableThreadContext ,这听起来可能很简单。 对于其他人群,只需提及CloseableThreadContext便可以将键值对注入到日志记录上下文中就足够了,这样在关闭上下文时,仅清除在当前上下文中注入的那些值。 注入的值将自动提供给调用线程的日志记录上下文( ThreadContext ); 或者用英语,该线程打印的每条日志行都会在其线程上下文中看到该参数(或者用老式的行话中的MDC )。

好的,我承认以上内容可能有点难以理解。 也许一个示例代码片段可能会做得更好:

// assume we are walking in, with nothing useful inside the contexttry (CloseableThreadContext.Instance level1 = CloseableThreadContext.put("level", "1")) {// now the context has "1" as "level"logger.debug("Commencing operation"); // will see {level=1} as the context// let's also put in a "clearance" valuelevel1.put("clearance", "nypd");// now, any log lines would see {level=1,clearance=nypd}// let's go deepertry (CloseableThreadContext.Instance level2 = CloseableThreadContext.put("level", "2").put("clearance", "fbi")) {// now both of the above "level" and "clearance" values are "masked" by the new ones// and yes, you can chain together the context mutationslogger.debug("Commencing investigation"); // will see {level=2,clearance=fbi}// putting in some morelevel2.put("access", "privileged");// now context is {level=2,clearance=fbi,access=privileged}// still deeper...try (CloseableThreadContext.Instance level3 = CloseableThreadContext.put("level", "3").put("clearance", "cia")) {// "level" and "clearance" are overridden, but "access" remains unchangedlogger.debug("Commencing consipracy"); // {level=3,clearance=cia,access=privileged}}// cool thing is, once you're out of the level3 block, the context will be restored to that of level2 (thanks to the AutoCloseable nature of CloseableThreadContext.Instance)logger.debug("Back to investigation"); // {level=2,clearance=fbi,access=privileged}}// same for exiting level 2logger.debug("Back to operation"); // {level=1,clearance=nypd}; access is gone!}logger.debug("Back to square one"); // {}; oh no, all gone!

该机制非常适合我们使用,因为我们需要包括线程的当前执行上下文以及该线程生成的每个日志行:

  1. 在Project-X ( UltraESB-X的基础引擎)中,维护在基本框架级别的辅助 线程池负责代表属于特定项目的集成流处理入站消息。
  2. 仅在将消息注入到特定集成流的入口连接器之后,我们才认为该线程位于项目的上下文中。 在此之前,工作线程应该做很多工作,所有这些工作都被认为属于system上下文。
  3. 我们会在整个过程中生成日志,因此应自动为它们添加适当的上下文标记。
  4. 而且,由于每个日志行都有特定的错误代码,因此,每次实际输出日志行时,我们都需要打开一个新的上下文,该日志行除了包含其他上下文参数外,还包含所需的日志代码。

因此,池中线程的生命周期将是一个无休止的循环,例如:

// wake up from thread pool// do system level stuffloggerA.debug(143, "Now I'm doing this cool thing : {}", param);try (CloseableThreadContext.Instance projectCtx = CloseableThreadContext.put("project", project.getName()).put("version", project.getVersion())) {// do project level stuffloggerM.debug(78, "About to get busy : {}", param);// more stuff, tra la la la
}// back to system level, do still more stuff// jump back to thread pool and have some sleep

在内部, loggerAloggerM等将最终调用logImpl(code, message, params)方法:

// context already has system/project info,
// logger already has a pre-computed codePrefixtry (CloseableThreadContext.Instance logCtx = CloseableThreadContext.put("logcode", codePrefix + code)) {// publish the actual log line
}// only "logcode" cleared from the context, others remain intact

我们通过引入一个CloseableContext接口来模拟这种行为,而不绑定到log4j2,该接口的log4j2变体(显然是Log4j2CloseableContext )将以相同的方式操作CloseableThreadContext实例:

import java.io.Closeable;public interface CloseableContext extends Closeable {CloseableContext append(final String key, final String value);void close();
}

和:

import org.adroitlogic.x.logging.CloseableContext;
import org.apache.logging.log4j.CloseableThreadContext;public class Log4j2CloseableContext implements CloseableContext {private final CloseableThreadContext.Instance ctx;/* Creates an instance wrapping a new default MDC instance*/Log4j2CloseableContext() {this.ctx = CloseableThreadContext.put("impl", "project-x");}/* Adds the provided key-value pair to the currently active log4j logging (thread) context** @param key   the key to be inserted into the context* @param value the value to be inserted, corresponding to {@code key}* @return the current instance, wrapping the same logging context*/@Overridepublic CloseableContext append(String key, String value) {ctx.put(key, value);return this;}/* Closes the log4j logging context wrapped by the current instance*/@Overridepublic void close() {ctx.close();}
}

现在,我们要做的就是通过一个不错的管理界面LogContextProvider打开一个适当的上下文:

// system context is active by default...try (CloseableContext projectCtx = LogContextProvider.forProject(project.getName(), project.getVersion())) {// now in project context}// back to system context

logImpl

try (CloseableContext logCtx = LogContextProvider.overlayContext("logcode", codePrefix + code)) {// call the underlying logging framework
}

由于我们将CloseableContext实现与记录器绑定一起加载(通过ServiceLoader ),因此我们知道LogContextProvider最终将最终调用正确的实现。

这就是我们的x-logging框架中的上下文日志记录的故事。

也许我们将来也可以解释我们的日志代码治理方法; 在那之前,祝您伐木愉快!

翻译自: https://www.javacodegeeks.com/2017/09/logging-style-log4j-2-contextuality-auto-cleanup-no-strings-attached.html

log4j2自动删除

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

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

相关文章

Shell(bash) 介绍

文章目录Shell 介绍Shell 种类命令行环境终端模拟器命令行提示符进入和退出方法Shell 脚本第一个shell脚本BashBash如何解析命令Shell 和 Bash 的历史Shell 介绍 简单点理解,就是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。实际上&am…

mysql 5.7数据库密码_mysql5.7数据库忘记密码的解决方法

mysql5.7数据库忘记密码的解决方法发布时间:2020-09-08 11:56:53来源:亿速云阅读:60作者:小新这篇文章主要介绍了mysql5.7数据库忘记密码的解决方法,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完…

软件项目报价明细表_BIM必学软件之REVIT

BIM与Revit是什么关系呢?Revit在众多BIM软件中扮演什么角色,有什么意义?今天我们就来说说REVIT。BIM是建筑从项目立项、规划、概算、设计、预算、建造、结算、审计、物业等全生命周期中的智能动态控制系统,俗称建筑智能机器人系统。 BIM的关…

tdd java_适用于Idea的面向现代TDD的Java 8 JUnit测试模板(带有Mockito和AssertJ)

tdd java使用类似于BDD的语法,Java 8和Mockito-AssertJ二重奏为Idea调整JUnit测试类模板。 本文涵盖的主题似乎很简单。 但是,根据我的培训师经验,我知道(不幸的)这不是常见的做法。 因此,我决定写这篇简短…

Linux 进程状态介绍

文章目录进程状态说明进程状态图进程状态说明 进程主状态:D:不可中断的睡眠状态 uninterruptible sleeping(usually IO)R:正在运行,或在队列中的 running or runnable (on run queue)S:处于休眠状态 interruptible sle…

petalinux 配置_澧县高压管道工厂化配置专业销售

澧县高压管道工厂化配置专业销售 公司生产设备齐全,热处理工艺精湛,检测设备,年生产能力上万吨,具备化学分析、全相检验、物理实验、无损探伤等检测能力。能生产各种标准的不锈钢、合金钢、碳钢弯头、无缝弯管、无缝三通、高压异径…

php mysql刷新表格_php读入mysql数据并以表格形式显示(表单实现无刷新提交)

在网上参考了些例子,于是我这个sample实现了如标题上的功能。话不多说,上代码:lishi.html搜索form#form1 {height: 93%;}p {width: 99%;height: 84%;}iframe#id_iframe {width: 99%;height: 100%;border: 0 red solid;}input{display:block;}…

flowable背压 取消_使用Flowable.generate()生成可感知背压的流– RxJava常见问题解答...

flowable背压 取消RxJava缺少创建无限自然数流的工厂。 这样的流很有用&#xff0c;例如&#xff0c;当您想通过压缩两个事件的顺序来为可能的无限事件流分配唯一的序列号时&#xff1a; Flowable<Long> naturalNumbers //???Flowable<Event> someInfiniteEve…

abstract类_【Java】类的结构 - Nemo

类与对象类中主要包括五种结构&#xff0c;下面进行对这五种结构进行详细的介绍。1. 面向对象与面向过程面向过程&#xff1a;强调的是功能行为&#xff0c;以函数为最小单位&#xff0c;考虑怎么做。面向对象&#xff1a;强调具备了功能的对象&#xff0c;以类/对象为最小单位…

二元函数可微与可导的关系_多元函数中可微与可导的直观区别是什么?

在多元的情况下&#xff0c;可微可导的关系要比在一元情况下复杂&#xff0c;但是只是要复杂一些&#xff0c;如果我们从一元开始去理解&#xff0c;你会发现并不困难。这篇文章主要阐述以下三个概念&#xff1a;偏微分偏导数全微分全导数这里暂时不讲&#xff0c;看名字好像和…

java 错误输入异常_在Java中进行输入验证期间用错误通知替换异常

java 错误输入异常在我以前的文章中&#xff0c;我写了一篇关于输入验证设计的文章 &#xff0c;该设计取代了难以维护和测试的 if-else块。 但是&#xff0c;正如某些读者指出的那样&#xff0c;它有一个缺点–如果输入数据有多个验证错误&#xff0c;则用户将不得不多次提交请…

Linux 命令之 mkdir 命令-创建目录

文章目录介绍语法格式常用选项参考示例介绍 mkdir 命令是“make directories”的缩写&#xff0c;用来创建目录。如果在目录名的前面没有加任何路径名&#xff0c;则在当前目录下创建目录&#xff1b;如果给出了一个已经存在的路径&#xff0c;将会在该目录下创建一个指定的目…

uniapp app蓝牙打印_给编程器加装蓝牙串口模块,用手机APP操作打印信息进控制台...

公众号回复【编程器】可下载蓝牙串口APP专用蓝牙串口模块购买&#xff1a;https://item.taobao.com/item.htm?id619731291566编程器加装蓝牙模块后&#xff0c;可以方便的使用手机查看打印信息&#xff0c;进入控制台执行各种串口命令。本款蓝牙串口APP具有保存打印信息、分享…

Linux 命令之 rm -- 删除文件和目录

文章目录一、命令介绍二、语法格式三、参考选项四、参考示例&#xff08;一&#xff09;删除当前目录下有内容的子目录&#xff08;二&#xff09;删除当前目录下多个含有内容的子目录&#xff08;三&#xff09;删除当前目录下以特定关键字开头的文件&#xff08;四&#xff0…

mysql报表占容量_MariaDB(MySQL)修改表结构报表空间满

今天数据库表修改表结构&#xff0c;需要添加一列&#xff1a;ALTER TABLE xxxx_learn ADD COLUMN learn_stage_code VARCHAR(32) NULL DEFAULT 99 COMMENT 学段 AFTER qualified_rate;结果一直报错&#xff1a;ERROR 1114 (HY000) at line 303: The table xxxx_learn is full刚…

对话框 函数_通过函数式编程实现动态对话框处理程序

对话框 函数在我以前的文章中&#xff0c;我提到了一个常见的用例&#xff0c;当我们需要以编程方式检查当前事务是否脏了&#xff0c;并在做某件事之前通知用户有关该事务的信息。 就像“您尚未保存的更改将丢失&#xff0c;您要继续吗&#xff1f;”。 假设我们需要在应用程…

Linux 命令之 yum -- 基于 RPM 的软件包管理器

文章目录一、命令介绍二、选项参数选项参数三、配置文件四、参考示例&#xff08;一&#xff09;安装、升级和删除包安装指定的软件包强制重新安装本地安装指定软件包本地更新指定软件包安装 yum 服务器中的所有可安装的软件安装程序组&#xff08;软件组&#xff09;安装 yum …

adb 最大连接_手机触屏失效的抢救办法,以及如何利用adb实现PC与手机交互

手机进水或者摔坏屏幕导致触屏失效的时候&#xff0c;一般情况下&#xff0c;要么选择换屏&#xff0c;要么选择把手机扔掉。但其实如果有一根OTG线&#xff0c;手机中的资料还可以安全备份出来&#xff0c;或者还可以再利用起来&#xff0c;发挥一下余热做点别的事。像上图一样…

proxy跨域不生效_前端开发:深入使用proxy代理解决跨域问题

在前端领域里面&#xff0c;跨域指的是浏览器允许向服务器发送跨域请求&#xff0c;进而克服Ajax只能同源使用的局限性限制。同源策略是一种约定&#xff0c;而且是浏览器中最基本也是最核心的安全功能&#xff0c;若缺少了该策略&#xff0c;浏览器非常容易被***&#xff1b;同…

java 静态缓存示例_Java 9 JShell示例:集合静态工厂方法

java 静态缓存示例这篇文章继续从My My Java 9 Features博客文章中探索Java9功能。 在这里&#xff0c;我们在List&#xff0c;Set和Map接口中试验Java9 Collections静态工厂方法。 集合静态工厂方法 Java9使用其新的静态工厂方法使创建不可变列表变得更加容易 有12种Set.of和…