logback官方文檔中文翻譯第十三章:從 log4j 遷移

第十三章:從 log4j 遷移

本章涉及到的內(nèi)容為將 log4j 的組件,例如 appender 或者 layout 遷移到 logback-classic。

僅僅調(diào)用 log4j 客戶端 API 的軟件,也就是 org.apache.log4j 包中 Logger 或者 Category 類,可以通過 SLF4J 遷移工具使用 SLF4J 來(lái)進(jìn)行自動(dòng)遷移。為了將 log4j.property 文件轉(zhuǎn)換為同等的 logback 配置,你可以使用 log4j.properties 轉(zhuǎn)換器。

在某種程度上來(lái)說,log4j 與 logback-classic 密切相關(guān)。核心組件,logger,appender 以及 layout 在兩個(gè)框架中都存在,并且目的一致。類似的,最重要的內(nèi)部數(shù)據(jù)結(jié)構(gòu),叫做 LoggingEvent,在兩個(gè)框架中非常相似,但是實(shí)現(xiàn)完全不同。最主要的是,在 logback-classic 中,LoggingEvent 實(shí)現(xiàn)了 ILoggingEvent 接口。遷移 log4j 組件到 logback-classic 最大的改變?cè)谟?LoggingEvent 類相關(guān)的實(shí)現(xiàn)不同。但是,請(qǐng)放心,這些變化是有限的。如果你盡了最大的努力仍然不能將 log4j 組件遷移到 logback-classic,你可以通過 logback 開發(fā)郵件列表來(lái)進(jìn)行提問。logback 的開發(fā)者應(yīng)該可以提供指導(dǎo)。

遷移 log4j 的 layout

假設(shè)我們現(xiàn)在要遷移一個(gè)簡(jiǎn)單的,名叫 TrivialLog4jLayout 的 log4j layout,它將日志事件中的消息作為格式化消息返回。代碼如下:

package chapters.migrationFromLog4j;

import org.apache.log4j.Layout;
import org.apache.log4j.spi.LoggingEvent;

public class TrivialLog4jLayout extends Layout {

  public void activateOptions() {
    
  }

  public String format(LoggingEvent loggingEvent) {
    return loggingEvent.getRenderedMessage();
  }

  public boolean ignoresThrowable() {
    return true;
  }
}

等價(jià)的 logback-classic TrivialLogbackLayout 如下:

package chapters.migrationFromLog4j;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.LayoutBase;

public class TrivialLogbackLayout extends LayoutBase<ILoggingEvent> {

  public String doLayout(ILoggingEvent loggingEvent) {
    return loggingEvent.getMessage();
  }
}

正如你所見,在 logback-classic layout 中,格式化的方法叫做 doLayout,而在 log4j 中叫 format()。因?yàn)樵?logback-classic 中沒有等價(jià)的方法,所以 ignoresThrowable() 方法則不需要。logback-classic layout 必須繼承 LayoutBase<ILoggingEvent> 類。

activateOptions() 方法的優(yōu)點(diǎn)值得進(jìn)一步討論。在 log4j 中,一個(gè) layout 有它自己的 activateOptions() 方法,通過 log4j 的配置程序,也就是 PropertyConfiguratorDOMConfigurator,會(huì)在 layout 所有的選項(xiàng)都設(shè)置完之后調(diào)用。因此,layout 有機(jī)會(huì)去檢查它的所有的選項(xiàng)是否一致,如果是,那么開始進(jìn)行初始化。

在 logback-classic 中,layout 必須實(shí)現(xiàn) LifeCycle 接口,該接口包含了一個(gè) start() 方法。這個(gè) start() 方法相當(dāng) log4j 中的 activateOptions() 方法。

遷移 log4j 的 appender

遷移 appender 與遷移 layout 相當(dāng)?shù)念愃?。下面是有一個(gè)名為 TrivialLog4jAppender 的簡(jiǎn)單 appender,它會(huì)在控制臺(tái)輸出由它的 layout 返回的字符串。

package chapters.migrationFromLog4j;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;


public class TrivialLog4jAppender extends AppenderSkeleton {

  protected void append(LoggingEvent loggingevent) {
    String s = this.layout.format(loggingevent);
    System.out.println(s);
  }

  public void close() {
    // nothing to do
  }

  public boolean requiresLayout() {
    return true;
  }
}

在 logback-classic 中等價(jià)的寫法為 TrivialLogbackAppender,如下:

package chapters.migrationFromLog4j;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;

public class TrivialLogbackAppender extends AppenderBase<ILoggingEvent> {

  @Override
  public void start() {
    if (this.layout == null) {
      addError("No layout set for the appender named [" + name + "].");
      return;
    }
    super.start();
  }

  @Override
  protected void append(ILoggingEvent loggingevent) {
    // AppenderBase.doAppend 只會(huì)在這個(gè) appender 成功啟動(dòng)之后調(diào)用這個(gè)方法
    String s = this.layout.doLayout(loggingevent);
    System.out.println(s);
  }
}

比較這兩個(gè)類,你會(huì)發(fā)現(xiàn) append() 方法的內(nèi)容沒有改變。requiresLayout 方法在 logback 中沒有用到,所以它可以被移除。在 logback 中,stop() 方法與 log4j 中的 close() 方法等價(jià)。然而,logback-classic 中的 AppenderBase 包含一個(gè)沒有實(shí)現(xiàn)的 stop 方法,但是在這個(gè)簡(jiǎn)單的 appender 已經(jīng)足夠了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容