log4j2自动删除_登录样式:log4j 2,上下文,自动清除…全部不附带任何字符串!...
log4j2自動刪除
日志記錄-保持操作的時間跟蹤-對于任何關鍵任務系統,無論大小,都至關重要。 我們的Project-X框架也是如此 ,這就是為什么我們希望從一開始就正確地做到這一點。
基于我們在傳奇的UltraESB上的登錄經驗, 上下文日志記錄(每條日志行自動記錄其原始邏輯上下文(例如,它來自特定單元還是來自基礎框架))一直是我們期待的事情 。
我們已經知道log4j2通過其CloseableThreadContext實現提供了上下文日志記錄 ,幾乎包含了我們所需要的一切。 但我們需要更多:
我們還需要與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!該機制非常適合我們使用,因為我們需要包括線程的當前執行上下文以及該線程生成的每個日志行:
因此,池中線程的生命周期將是一個無休止的循環,例如:
// 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在內部, loggerA , loggerM等將最終調用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自動刪除
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的log4j2自动删除_登录样式:log4j 2,上下文,自动清除…全部不附带任何字符串!...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: apache.camel_在即将发布的C
- 下一篇: 对话框 函数_通过函数式编程实现动态对话