(一)Logback介绍及架构

一、什么是Logback?

Logback是Log4j项目的继承者,由Log4j创始人Ceki Gülcü基于过去十年企业级日志系统设计经验打造。Logback比目前所有已存的日志系统要快,它提供了其它日志系统缺失的独特和有用的特性。

二、Logback架构

Logback分为3个模块:logback-core、logback-classic和logback-access。core模块为其它两个模块奠定了基础,classic模块拓展了core模块,classic模块意义上来说相当于Log4j的进阶版本。Logback-classic模块实现了SLF4J API(simple logging facade for java,日志规范,logback为其中一种实现),因此能轻易在Logback和其它日志系统(如:log4j、java.util.logging)切换。

1、Logger(日志记录器)

Loggers命名为实体,他们的名字大小写敏感并且遵循层级命名规则(如果一个logger名字加点是另一个logger名字的前缀,则这个logger是另一个logger的祖先logger)。例如,名为"com.foo"的logger是名为"com.foo.Bar"的父logger。

Root logger在logger层级中处于最上级,可以通过名字进行检索。

Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

其它的日志记录器能通过LoggerFactory的静态方法getLogger检索,方法参数的名字为日志记录器的名字,下面是Logger接口的基本方法。

package org.slf4j; 
public interface Logger {

  // Printing methods: 
  public void trace(String message);
  public void debug(String message);
  public void info(String message); 
  public void warn(String message); 
  public void error(String message); 
}

2、Effective Level & Level Inheritence(有效等级和等级继承)

日志记录器可以指定级别,如:TRACE、DEBUG、INFO、WARN、ERROR。如果给定的日志记录器没有指定级别,那么它会继承最近祖先的级别,root日志记录器默认被分配的级别为DEBUG,下面是一些例子:

日志记录器名字分配的级别有效级别
ROOTDEBUGDEBUG
XNONEDEBUG
X.YNONEDEBUG
X.Y.ZNONEDEBUG
日志记录器名字分配的级别有效级别
ROOTEROOREROOR
XINFOINFO
X.YDEBUGDEBUG
X.Y.ZWARNWARN
日志记录器名字分配的级别有效级别
ROOTDEBUGDEBUG
XINFOINFO
X.YNONEINFO
X.Y.ZEROOREROOR
日志记录器名字分配的级别有效级别
ROOTDEBUGDEBUG
XINFOINFO
X.YNONEINFO
X.Y.ZNONEINFO

3、 打印方法基本选择规则

如果打印方法级别高于日志记录器的有效级别,那么日志请求是有效的,例如:日志请求的级别是p,日志记录器的有效级别为q,如果日志请求可用,则p>=q。级别排序:TRACE<=DEBUG<=INFO<=WARN<=ERROR<=OFF。

下面图表描述了选择规则如何运作。

日志请求日志记录器有效级别
TRACEDEBUGINFOWARNERROROFF
TRACEYESNONONONONO
DEBUGYESYESNONONONO
INFOYESYESYESNONONO
WARNYESYESYESYESNONO
ERRORYESYESYESYESYESNO

4、检索日志记录器

调用LoggerFactory.getLogger方法并指定相同的名字会返回相同的logger对象。例如x和y引用相同的logger对象:

Logger x = LoggerFactory.getLogger("wombat"); 
Logger y = LoggerFactory.getLogger("wombat");

5、Appenders & Layouts(输出源和布局)

日志输出的目的地叫做appender,目前存在的输出源有控制台、文件、远程套接字服务器、数据库和JMS等。

到指定日志记录器的日志请求会被转发到日志记录器的所有输出源以及高层级的输出源,什么叫高层级输出源,其实就是祖先日志记录器里配置的输出源。换句话说,输出源是叠加性地继承。下面图标清楚地展示了输出源的叠加性。

日志记录器名附加的输出源叠加性标识输出目的地备注
rootA1A1
xA-x1, A-x2trueA1, A-x1, A-x2
x.ynonetrueA1, A-x1, A-x2
x.y.zA-xyz1trueA1, A-x1, A-x2, A-xyz1
securityA-secfalseA-sec叠加性表示为false,无输出源聚集
security.accessnonetrueA-secsecurity叠加性标识为false,因此输出源只有security附加的输出源

6、参数化日志打印

logback-classic中的日志记录器实现了SLF4J中的Logger接口,里面的日志打印方法在最小化对代码可读性造成影响的同时主要用来改善性能。

logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));

上面这种日志打印方法会增加构造消息参数的性能,不管消息是否可以被打印,都会把整型变量i和entry[i]转换成字符串,然后再进行字符串拼接。

一种避免参数构造的可选方法为加上判断,如下:

if(logger.isDebugEnabled()) { 
  logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}

上面这种方式如果debugging不可用不会增加参数构造的性能,但如果debugging可用,那么会有两处地方会耗性能,一处在判断debug是否可用,一处在参数构造。

更好的方式:

Object entry = new SomeObject(); 
logger.debug("The entry is {}.", entry);

通过上面这种方式,只有确定打印日志时,日志记录器实现才会格式化消息并且替代占位符。换句话说,这种形式在日志打印不可用的时候不会造成参数构造时的性能消耗。

logger.debug("The new entry is "+entry+".");
logger.debug("The new entry is {}.", entry);

上面两条语句会产生相同的输出,但当日志打印不可用时,第二种方式会胜过第一种方式。

logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);

两个参数可以采用如上方式。

Object[] paramArray = {newVal, below, above};
logger.debug("Value {} was inserted between {} and {}.", paramArray);

三个或以上参数可以采用如上方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nick说说前后端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值