1.Layout

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

1.Layout简介

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

常用事件类型:ILoggingEvent。

Layout接口概要如下 :

  1. public interface Layout<E> extends ContextAware, LifeCycle {
  2. String doLayout(E event);
  3. String getFileHeader();
  4. String getPresentationHeader();
  5. String getFileFooter();
  6. String getPresentationFooter();
  7. String getContentType();
  8. }

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

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

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

3.自定义Layout

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

示例1:

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

  1. package chapters.layouts;
  2. import ch.qos.logback.classic.spi.ILoggingEvent;
  3. import ch.qos.logback.core.CoreConstants;
  4. import ch.qos.logback.core.LayoutBase;
  5. public class MySampleLayout extends LayoutBase<ILoggingEvent> {
  6.   public String doLayout(ILoggingEvent event) {
  7.     StringBuffer sbuf = new StringBuffer(128);
  8.     sbuf.append(event.getTimeStamp()- event.getLoggerContextVO().getBirthTime());
  9.     sbuf.append(" ");
  10.     sbuf.append(event.getLevel());
  11.     sbuf.append(" [");
  12.     sbuf.append(event.getThreadName());
  13.     sbuf.append("] ");
  14.     sbuf.append(event.getLoggerName());
  15.     sbuf.append(" - ");
  16.     sbuf.append(event.getFormattedMessage());
  17.     sbuf.append(CoreConstants.LINE_SEPARATOR);
  18.     return sbuf.toString();
  19.   }
    }

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

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

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

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

如何为 layout 增加选项?为 layout 或任何 logback 的其他组件添加属性非常简单:声明一个属性及 setter 方法接即可。MySampleLayout2 类包含两个属性。第一个是为输出添加的前缀。第二个是用于选择是否显示记录请求的线程名。
示例1:
代码如下:
  1. package chapters.layouts;
  2. import ch.qos.logback.classic.spi.ILoggingEvent;
  3. import ch.qos.logback.core.CoreConstants;
  4. import ch.qos.logback.core.LayoutBase;
  5. public class MySampleLayout2 extends LayoutBase<ILoggingEvent> {
  6.   String prefix = null;
  7.   boolean printThreadName = true;
  8.   public void setPrefix(String prefix) {
  9.     this.prefix = prefix;
  10.   }
  11.   public void setPrintThreadName(boolean printThreadName) {
  12.     this.printThreadName = printThreadName;
  13.   }
  14.   public String doLayout(ILoggingEvent event) {
  15.     StringBuffer sbuf = new StringBuffer(128);
  16.     if (prefix != null) {
  17.       sbuf.append(prefix + ": ");
  18.     }
  19.     sbuf.append(event.getTimeStamp()- event.getLoggerContextVO().getBirthTime());
  20.     sbuf.append(" ");
  21.     sbuf.append(event.getLevel());
  22.     if (printThreadName) {
  23.       sbuf.append(" [");
  24.       sbuf.append(event.getThreadName());
  25.       sbuf.append("] ");
  26.     } else {
  27.       sbuf.append(" ");
  28.     }
  29.     sbuf.append(event.getLoggerName());
  30.     sbuf.append(" - ");
  31.     sbuf.append(event.getFormattedMessage());
  32.     sbuf.append(CoreConstants.LINE_SEPARATOR);
  33.     return sbuf.toString();
  34.   }
    }
在配置里启用属性只需要有对应的 setter 方法即可。下面是 MySampleLayout2 所用的配置文件。
  1. <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>
  2.       </layout>
  3.     </encoder>
  4.   </appender>
      <root level="debug">
        <appender-ref ref="STDOUT" />
  5.   </root>
  6. </configuration>

java日志框架系列(7):logback框架Layout详解的更多相关文章

  1. Java容器解析系列(6) Queue Deque AbstractQueue 详解

    首先我们来看一下Queue接口: /** * @since 1.5 */ public interface Queue<E> extends Collection<E> { / ...

  2. Java容器解析系列(4) ArrayList Vector Stack 详解

    ArrayList 这里关于ArrayList本来都读了一遍源码,并且写了一些了,突然在原来的笔记里面发现了收藏的有相关博客,大致看了一下,这些就是我要写的(╹▽╹),而且估计我还写不到博主的水平,这 ...

  3. 深入理解JAVA I/O系列三:字符流详解

    字符流为何存在 既然字节流提供了能够处理任何类型的输入/输出操作的功能,那为什么还要存在字符流呢?容我慢慢道来,字节流不能直接操作Unicode字符,因为一个字符有两个字节,字节流一次只能操作一个字节 ...

  4. 《手把手教你》系列基础篇(八十三)-java+ selenium自动化测试-框架设计基础-TestNG测试报告-下篇(详解教程)

    1.简介 其实前边好像简单的提到过测试报告,宏哥觉得这部分比较重要,就着重讲解和介绍一下.报告是任何测试执行中最重要的部分,因为它可以帮助用户了解测试执行的结果.失败点和失败原因.另一方面,日志记录对 ...

  5. 【山外笔记-工具框架】iperf3网络性能测试工具详解教程

    [山外笔记-工具框架]iperf3网络性能测试工具详解教程   本文下载链接 [学习笔记]iperf3网络性能测试工具.pdf 网络性能评估主要是监测网络带宽的使用率,将网络带宽利用最大化是保证网络性 ...

  6. Farseer.net轻量级开源框架 入门篇:添加数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 分类逻辑层 下一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 ...

  7. Farseer.net轻量级开源框架 入门篇:修改数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 添加数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 ...

  8. Farseer.net轻量级开源框架 入门篇:删除数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 查询数据详解 ...

  9. Farseer.net轻量级开源框架 入门篇:查询数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 下一篇:Farseer.net轻量级开源框架 中级篇: Where条 ...

  10. 《手把手教你》系列技巧篇(二十八)-java+ selenium自动化测试-处理模态对话框弹窗(详解教程)

    1.简介 在前边的文章中窗口句柄切换宏哥介绍了switchTo方法,这篇继续介绍switchTo中关于处理alert弹窗的问题.很多时候,我们进入一个网站,就会弹窗一个alert框,有些我们直接关闭, ...

随机推荐

  1. 关于解决ruby源码安装 gem install报错问题

    因做redis集群需要安装ruby,源码安装过后gem install redis安装redis接口报错 解决方案: 确保主机安装zlib,没有安装执行 yum -y install zlib zli ...

  2. MySql通过Data恢复数据库数据

    公司的服务器开不了机,把硬盘装在其他机器上面,文件是没有丢失,可是数据库开不了了.上网查了下,用DATA恢复了数据. 1.先通过MYSQL目录下的my.ini配置文件找到 datadir的文件夹地址. ...

  3. [APIO2017]商旅——分数优化+floyd+SPFA判负环+二分答案

    题目链接: [APIO2017]商旅 枚举任意两个点$(s,t)$,求出在$s$买入一个物品并在$t$卖出的最大收益. 新建一条从$s$到$t$的边,边权为最大收益,长度为原图从$s$到$t$的最短路 ...

  4. can't read property 'push' of undefined

    在某些情况下是因为没有初始化,所以初始化一下就好了

  5. vue中class用法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. redis5种数据结构讲解及使用场景

    string  list  hash set zset  探究 Redis 4 的 stream 类型 redis提供了5中数据结构,理解每种数据结构的特点对于redis开发运维非常重要.  一.字符 ...

  7. redis之为什么redis是单线程?

    官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽.既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的 ...

  8. TynSerial图片序列(还原)

    TynSerial图片序列(还原) 笔者以生成图形验证码为例. function TForm1.VerifyCode(image: TImage): string; // 生成验证码和图像 var u ...

  9. 咏南中间件新增MORMOT插件功能

    咏南中间件新增MORMOT插件功能 咏南中间件支持DATASNAP和MORMOT两种通讯框架. 原来已经支持DATASNAP插件,现在又增加了MORMOT插件,已经支持DATASNAP和MORMOT两 ...

  10. 如何十倍提高你的webpack构建效率

    前言 http://jafeney.com/2016/07/10/2016-07-10-webpack/     webpack 是个好东西,和 NPM 搭配起来使用管理模块实在非常方便.而 Babe ...