java日志框架系列(7):logback框架Layout详解

1.Layout

layout从字面意思来看就是排版、布局咯。

1.Layout简介

功能负责把事件转换成字符串。Layout接口的格式化方法doLayout()负责将代表任何类型的事件的转换成一个String对象并返回给调用者。

常用事件类型:ILoggingEvent。

Layout接口概要如下 :

public interface Layout<E> extends ContextAware, LifeCycle {
String doLayout(E event);
String getFileHeader();
String getPresentationHeader();
String getFileFooter();
String getPresentationFooter();
String getContentType();
}

接口很简单,却足够完成很多格式化需求。

2.Logback处理的事件类型种类

logback-classic模块中只会处理ch.qos.logback.classic.spi.ILoggingEvent类型的事件

3.自定义Layout

让我们实现一个简单却可工作的 layout,打印内容包括:自程序启动以来逝去的时间、记录事件的级别、包含在方括号里的调用者线程的名字、logger 名、连字符、事件消息和换行。
输出类似于:

 

 示例1:

想要自定义layout,可以通过继承LayoutBase类,并重写doLayout方法,代码如下:

package chapters.layouts;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.LayoutBase;
public class MySampleLayout extends LayoutBase<ILoggingEvent> {
  public String doLayout(ILoggingEvent event) {
    StringBuffer sbuf = new StringBuffer(128);
    sbuf.append(event.getTimeStamp()- event.getLoggerContextVO().getBirthTime());
    sbuf.append(" ");
    sbuf.append(event.getLevel());
    sbuf.append(" [");
    sbuf.append(event.getThreadName());
    sbuf.append("] ");
    sbuf.append(event.getLoggerName());
    sbuf.append(" - ");
    sbuf.append(event.getFormattedMessage());
    sbuf.append(CoreConstants.LINE_SEPARATOR);
    return sbuf.toString();
  } 
}

 编写完代码之后,需要在xml文件中配置自定义的layout,配置如下:

<configuration debug="true">
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
      <layout class="chapters.layouts.MySampleLayout" />     </encoder>   </appender>
  <root level="DEBUG">
    <appender-ref ref="STDOUT" />   </root> </configuration>

由于在自定义类MySampleLayout中已经实现了继承的doLayout()方法,因此,在<encoder>标签中通过子标签<layout>指定已经实现转换功能的类MySampleLayout,该类MySampleLayout负责将ILoggingEvent类型事件转换为String类型。

4.为自定义的Layout添加参数

如何为 layout 增加选项?为 layout 或任何 logback 的其他组件添加属性非常简单:声明一个属性及 setter 方法接即可。MySampleLayout2 类包含两个属性。第一个是为输出添加的前缀。第二个是用于选择是否显示记录请求的线程名。
示例1:
代码如下:
package chapters.layouts;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.LayoutBase;
public class MySampleLayout2 extends LayoutBase<ILoggingEvent> {   String prefix = null;   boolean printThreadName = true;   public void setPrefix(String prefix) {     this.prefix = prefix;   }   public void setPrintThreadName(boolean printThreadName) {     this.printThreadName = printThreadName;   }   public String doLayout(ILoggingEvent event) {     StringBuffer sbuf = new StringBuffer(128);     if (prefix != null) {       sbuf.append(prefix + ": ");     }     sbuf.append(event.getTimeStamp()- event.getLoggerContextVO().getBirthTime());     sbuf.append(" ");     sbuf.append(event.getLevel());     if (printThreadName) {       sbuf.append(" [");       sbuf.append(event.getThreadName());       sbuf.append("] ");     } else {       sbuf.append(" ");     }     sbuf.append(event.getLoggerName());     sbuf.append(" - ");     sbuf.append(event.getFormattedMessage());     sbuf.append(CoreConstants.LINE_SEPARATOR);     return sbuf.toString();   }
}
在配置里启用属性只需要有对应的 setter 方法即可。下面是 MySampleLayout2 所用的配置文件。
<configuration> 
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
      <layout class="chapters.layouts.MySampleLayout2">
        <prefix>MyPrefix</prefix>
        <printThreadName>false</printThreadName>       </layout>     </encoder>   </appender>
  <root level="debug">
    <appender-ref ref="STDOUT" />   </root> </configuration>

 

 

posted on 2019-10-17 10:21  _ZXP  阅读(2087)  评论(0编辑  收藏  举报

导航