log4j系列一:log4j简介以及Loggers
2016-05-19 19:40
369 查看
简介
经验表明,在项目中使用日志是有很多益处的。譬如查看bug、查看应用执行的记录等。但是他也是有缺点的,典型的就是拖慢了应用系统响应的时间。在平时开发中,任何一个中小型的项目可能都会采用自己的日志记录方式,最著名的就是
System.out.println这种类似的。但是在大型的商务系统中,采用
System.out.println很明显不能满足系统的需求。log4j就是在这样的情形下诞生的。
log4j是一个成熟的日志系统。经历过了1.x时代,目前我们主要使用的都是2.x,1.x至2015年8月5日起不在维护。到目前为止,log4j已被引用到
C、C++、C#、Perl、Python等语言中。在此我们主要介绍Java系的。
log4j中最主要的几个概念分别是Loggers(记录器)、Appenders(输出源)和Layouts(布局器)。可分别理解为日志类别,日志要输出的地方和日志以何种形式输出。综合使用这三个组件可以轻松地记录信息的类型和级别,并可以在运行时控制日志输出的样式和位置。
首先我们来介绍Loggers。
Loggers
Logger结构
Loggers其实就是一些命名的实体。在log4j中,创建的方式为:public class App { private static final Logger log = LoggerFactory.getLogger(App.class); }
之后,log4j会将创建的Logger实例保存在一个
ConcurrentMap中。以上面的代码为例,key则为
App.class.getName(),value则为
log实例。从这里可以看出,Logger的名字是大小写敏感的,如果key不同,则之后获取到的Logger实例则不同。Logger的名字一般为类的全限定名,当然你也可以自己指定,因为它的构造函数中可以用
String来指定,但是务必要清晰明了。
log4j定义了一套结构,即一个logger A的名字为另一个logger B的名字+“.”构成的话,则B是A的祖先。如果B和A之间没有其他的logger的话,则B是A的父亲。但是,不管如何,任何一个logger都有一个共同的祖先叫root,且root是原始祖先,你不能根据名称来获取root Logger,但是你可以采用
Logger.getRootLogger()来获得它。
例如,
indi.latch是
indi.latch.training的祖先,明确的说是它的父亲。再比如说,
java是
java.util的父亲,是
java.util.Vector的祖先。
Logger优先级
为了能更好的控制日志输出,log4j还提供了Logger的优先级。常见的级别有DEBUG、INFO、WARN、ERROR和FATAL(你也可以定义自己的级别)。其级别关系为DEBUG < INFO < WARN < ERROR < FATAL。Logger的优先级是可以传递的。如果指定的一个Logger没有赋值优先级,则会从其最近的具有优先级的祖先中获取优先级,直至到root。
以下展示了四种赋值不同优先级及获取优先级的情况:
表1:只有root具有优先级,那么其子Logger都会继承root的优先级。
Logger名称 | 赋值优先级 | 继承优先级 |
---|---|---|
root | Proot | Proot |
indi | none | Proot |
indi.latch | none | Proot |
indi.latch.training | none | Proot |
Logger名称 | 赋值优先级 | 继承优先级 |
---|---|---|
root | Proot | Proot |
indi | P1 | P1 |
indi.latch | P2 | P2 |
indi.latch.training | P3 | P3 |
Logger名称 | 赋值优先级 | 继承优先级 |
---|---|---|
root | Proot | Proot |
indi | P1 | P1 |
indi.latch | none | P1 |
indi.latch.training | P3 | P3 |
Logger名称 | 赋值优先级 | 继承优先级 |
---|---|---|
root | Proot | Proot |
indi | P1 | P1 |
indi.latch | none | P1 |
indi.latch.training | none | P1 |
package org.apache.log4j; public class Logger { // Creation & retrieval methods: public static Logger getRootLogger(); public static Logger getLogger(String name); // printing methods: public void trace(Object message); public void debug(Object message); public void info(Object message); public void warn(Object message); public void error(Object message); public void fatal(Object message); // generic printing method: public void log(Level l, Object message); }
debug即表示采用DEBUG级别输出日志;
info表示采用INFO级别输出,其他依次类推。
最后我们给出一个设置优先级和采用优先级输出的小例子:
public class App { // 获取一个命名为indi.latch的Logger private static final Logger logger = Logger.getLogger("indi.latch"); // 获取一个命名为indi.latch.training的Logger private static final Logger trainLogger = Logger.getLogger("indi.latch.training"); public static void main( String[] args ) { //加载基本的配置(后面会讲解) BasicConfigurator.configure(); //设置indi.latch Logger的优先级为INFO logger.setLevel(Level.INFO); // 这次日志会输出,因为WARN>INFO logger.warn("Low fuel level."); //这次日志不会输出,因为DEBUG<INFO logger.debug("Starting search for nearest gas station."); //这次日志会输出。因为trainLogger会获取logger的优先级,即INFO trainLogger.info("Located nearest gas station."); //这次日志不会输出。因为trainLogger会获取logger的优先级,即INFO,但是DEBUG<INFO trainLogger.debug("Exiting gas station search"); } }
相关文章推荐
- cas4.2.1 帐号密码
- POJ_2104_Kth_(主席树)
- UI进阶 即时通讯之XMPP环境搭建
- Jenkins学习总结(3)——Jenkins+Maven+Git搭建持续集成和自动化部署的
- Jenkins学习总结(3)——Jenkins+Maven+Git搭建持续集成和自动化部署的
- Python和shell中Base64编码使用那些事
- 网络信息安全攻防实验室 第四关
- yii
- 《学习笔记》之JAVA设计模式--抽象工厂模式
- 解决虚拟机上的tomcat无法被主机访问的问题
- Android探索之AIDL实现进程间通信
- 实验室实验备忘
- 解决OSX上面PHP curl SSLRead() error
- 详解Android首选项框架的使用
- Java面试题及答案(二)
- DP入门---Robberies
- 抽象工厂 C++实现
- COALESCE函数
- 网络信息安全攻防实验室 第三关
- 函数变量作用域