前沿
在JAVA的世界中,由于SLF4J的扩展性与良好的性能已经取代了大多数的日志框架,不论是Spring还是其他著名的框架都已经向SLF4J迁移了,SLF4J只是一个抽象的日志架构,具体的内容实现需要依赖于其他的日志框架,接下里就介绍下Logback。他是SLF4J的一个实现,由于本人对日志了解的比较薄弱,所以查阅了下LOGBACK的MANUAL手册,接下来就把英文版的翻译成中文版,帮助一些初学或是英语不好的同学。
LOGBACK试用手册
第一章介绍(直接忽略)
第二章架构
LOGBACK主要有三个模块:classic,core,access。classic模块实现SLF4J的接口,core实现了核心类,而access则提供了对于日志的多种访问访日比如http。
LOGBACK主要有三个类构成:Logger,Appendar,Layout。这三个类的组合可以根据消息类型以及等级帮助开发者在运行时控制对日志选择性的记录以及格式化。Logger类包含在classic模块中,Appener与Layout包含在core模块中。
Logger类的实例是以构造函数名字继承的,例如:com.foo.Bar--继承-->com.foo-->root。所有的logger都继承root。
Logger的level默认也是按照继承父类的level,当然也可以重载,有trace,debug,info,warn,error以及off。如果设置为off则子类无法重载负累的。
Example 1
Logger name | Assigned level | Effective level |
---|---|---|
root | DEBUG | DEBUG |
X | none | DEBUG |
X.Y | none | DEBUG |
X.Y.Z | none | DEBUG |
In example 1 above, only the root logger is assigned a level. This level value, DEBUG
, is inherited by the other loggers X
, X.Y
and X.Y.Z
Logger name | Assigned level | Effective level |
---|---|---|
root | ERROR | ERROR |
X | INFO | INFO |
X.Y | DEBUG | DEBUG |
X.Y.Z | WARN | WARN |
In example 2 above, all loggers have an assigned level value. Level inheritance does not come into play.
Example 3Logger name | Assigned level | Effective level |
---|---|---|
root | DEBUG | DEBUG |
X | INFO | INFO |
X.Y | none | INFO |
X.Y.Z | ERROR | ERROR |
In example 3 above, the loggers root
, X
and X.Y.Z
are assigned the levels DEBUG
, INFO
and ERROR
respectively. Logger X.Y
inherits its level value from its parent X
.
Logger name | Assigned level | Effective level |
---|---|---|
root | DEBUG | DEBUG |
X | INFO | INFO |
X.Y | none | INFO |
X.Y.Z | none | INFO |
代码中logger.trace的方法是否输出日志依赖于当前logger的level是否=>当前trace的方法。
level of request p | effective level q | |||||
TRACE | DEBUG | INFO | WARN | ERROR | OFF | |
---|---|---|---|---|---|---|
TRACE | YES | NO | NO | NO | NO | NO |
DEBUG | YES | YES | NO | NO | NO | NO |
INFO | YES | YES | YES | NO | NO | NO |
WARN | YES | YES | YES | YES | NO | NO |
ERROR | YES | YES | YES | YES | YES | NO |
import ch.qos.logback.classic.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
....
// get a logger instance named "com.foo". Let us further assume that the
// logger is of type ch.qos.logback.classic.Logger so that we can
// set its level
ch.qos.logback.classic.Logger logger =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.foo");
//set its Level to INFO. The setLevel() method requires a logback logger
logger.setLevel(Level. INFO);
Logger barlogger = LoggerFactory.getLogger("com.foo.Bar");
// This request is enabled, because WARN >= INFO
logger.warn("Low fuel level.");
// This request is disabled, because DEBUG < INFO.
logger.debug("Starting search for nearest gas station.");
// The logger instance barlogger, named "com.foo.Bar",
// will inherit its level from the logger named
// "com.foo" Thus, the following request is enabled
// because INFO >= INFO.
barlogger.info("Located nearest gas station.");
// This request is disabled, because DEBUG < INFO.
barlogger.debug("Exiting gas station search");
Logger x = LoggerFactory.getLogger("wombat"); Logger y = LoggerFactory.getLogger("wombat");当前x==y
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
当前这句日志编码方式效率低于以下,是由于logger.debug在判断当前是否需要输出才会去做字符串处理。
logger.debug("The entry is {}.", entry[i]);