log4j框架logger的继承关系以及使用场景
log4j框架logger的继承关系以及使用场景
log4j日志框架logger是存在继承关系的,我们一般都会在log4j.properties文件中定义log4j.rootLogger。其他所有logger都继承自这个rootLooger。考虑下面这种场景:假如我们有2个类HelloLog4j和A。
- package aty.log;
- import org.apache.log4j.Logger;
- import aty.log.service.A;
- public class HelloLog4j {
- private static Logger logger = Logger.getLogger(HelloLog4j.class);
- public static void main(String[] args) {
- logger.debug("log in main.");
- new A().run();
- }
- }
- package aty.log.service;
- import org.apache.log4j.Logger;
- public class A {
- private static Logger logger = Logger.getLogger(A.class);
- public void run() {
- logger.error("log in A.java");
- }
- }
log4j.properties文件配置如下:
- #rootLogger can print DEBUG to console
- log4j.rootLogger=debug, console
- log4j.appender.console=org.apache.log4j.ConsoleAppender
- log4j.appender.console.Threshold=debug
- log4j.appender.console.ImmediateFlush=true
- log4j.appender.console.Target=System.err
- log4j.appender.console.layout=org.apache.log4j.PatternLayout
运行HelloLog4j.java控制台日志如下:可以看到这2个类使用的logger都是rootLogger。
现在我们有这个需求:让A.java中日志的打印到单独的a.log日志文件中,而HelloLog4j中的日志还是打印到控制台。也就是说:我们想让A和HelloLog4j这2个类使用不同的logger。java代码不用修改,我们将log4j.properties修改如下:
- #rootLogger can print DEBUG to console
- log4j.rootLogger=debug, console
- log4j.appender.console=org.apache.log4j.ConsoleAppender
- log4j.appender.console.Threshold=debug
- log4j.appender.console.ImmediateFlush=true
- log4j.appender.console.Target=System.err
- log4j.appender.console.layout=org.apache.log4j.PatternLayout
- log4j.appender.console.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}]-[%t]-[%X{ip}]-[%l]-[%p] %m%n
- #A.java is special.we use a individual appender for it.
- #A class's full qulified qualified name is logger's name.
- log4j.logger.aty.log.service.A=DEBUG, testA
- log4j.appender.testA=org.apache.log4j.FileAppender
- log4j.appender.testA.Threshold=warn
- log4j.appender.testA.ImmediateFlush=true
- log4j.appender.testA.Append=true
- log4j.appender.testA.File=c:/a.log
- log4j.appender.testA.layout=org.apache.log4j.PatternLayout
- log4j.appender.testA.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}]-[%t]-[%X{ip}]-[%l]-[%p] %m%n
- #avoid print to parent logger.
- log4j.additivity.aty.log.service.A= false
再次运行HelloLog4j可以看到:A.java中的日志并没有打印到控制台上,而是打印到了a.log文件中。
我们来解释下上面的配置:
log4j.logger.aty.log.service.A=DEBUG, testA 我们用A的全类名定义了一个logger。
log4j.additivity.aty.log.service.A= false 避免日志打印到rootLogger中。如果这里设置成true,那么A.java中的日志既会打印到控制台上,也会打印到a.log文件中。
现在我们可以介绍下logger的继承关系了,比如我们上面的类aty.log.service.A中使用了logger来写日志。那么log4j会先查找名称是"aty.log.service.A"的logger,如果没有找到,向上查找名称是"aty.log.service"的logger,如果还没有找到那么继续向上查找,查找的最顶层就是rootLogger。这就是log4j中logger的继承关系。rootLogger一定要在配置,其他特定类或者特定包的logger可以不用配置。知道了这个继承特性之后,如果我们要aty.log.dao包下所有的类都打印到同一个日志文件,那么可以进行如下配置。
- # a package appender
- log4j.logger.aty.log.dao=DEBUG, daoAppender
- log4j.appender.daoAppender=org.apache.log4j.FileAppender
- log4j.appender.daoAppender.Threshold=warn
- log4j.appender.daoAppender.ImmediateFlush=true
- log4j.appender.daoAppender.Append=true
- log4j.appender.daoAppender.File=c:/dao.log
- log4j.appender.daoAppender.layout=org.apache.log4j.PatternLayout
- log4j.appender.daoAppender.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}]-[%t]-[%X{ip}]-[%l]-[%p] %m%n
- log4j.additivity.aty.log.dao= false
可以看到:利用logger的继承特性,我们可以很容易将不同的日志打印到不同的文件中,这样可以避免各种日志混杂在一起。如果我们想将A.java中有的日志打印到a.log中,有的日志打印到控制台上也是可以的。
- package aty.log.service;
- import org.apache.log4j.Logger;
- public class A {
- private static Logger logger = Logger.getLogger(A.class);
- private static Logger rootLogger = Logger.getRootLogger();
- public void run() {
- logger.error("log in A.java");
- rootLogger.error("a to console.");
- }
- }
最后提一下:log4j默认是使用类名或者包名来查找logger的。log4j允许我们自己定义logger的名称。
- package aty.log.service;
- import org.apache.log4j.Logger;
- public class A {
- private static Logger logger = Logger.getLogger("atyAlogger");
- public void run() {
- logger.error("log in A.java");
- }
- }
- #use atyAlogger as appender name.
- log4j.logger.atyAlogger=DEBUG, testA
- log4j.appender.testA=org.apache.log4j.FileAppender
- log4j.appender.testA.Threshold=warn
- log4j.appender.testA.ImmediateFlush=true
- log4j.appender.testA.Append=true
- log4j.appender.testA.File=c:/a.log
- log4j.appender.testA.layout=org.apache.log4j.PatternLayout
- log4j.appender.testA.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}]-[%t]-[%X{ip}]-[%l]-[%p] %m%n
- #avoid print to parent logger.
- log4j.additivity.atyAlogger= false
一般来说,我们都是使用默认的名称,这样虽然将类名和包名在log4j.properties写死了。但是方便java类里面获取logger。因为各个类都是根据自己类的全限定名来查找logger的,具体日志到底打印到哪里去,由配置文件决定。
log4j框架logger的继承关系以及使用场景的更多相关文章
- Swing框架的继承关系
---------------siwuxie095 Java SE 8 (截止 2017/4/1 最新)在线 API 文档: http://docs.oracle.com/javase/8/docs/ ...
- ABP VNext框架基础知识介绍(1)--框架基础类继承关系
在我较早的时候,就开始研究和介绍ABP框架,ABP框架相对一些其他的框架,它整合了很多.net core的新技术和相关应用场景,虽然最早开始ABP框架是基于.net framework,后来也全部转向 ...
- 重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试
原文:重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试 [源码下载] 重新想象 Windows 8 Store ...
- 如何自建appender扩展Log4j框架
1.log4j 概述 log4j 环境包括三个主要组件: logger(日志记录器):控制要启用或禁用哪些日志记录语句.可以对日志记录器指定如下级别: ALL . DEBUG . INFO . WAR ...
- 使用IntelliJ IDEA查看类的继承关系图形
最近正好也没什么可忙的,就回过头来鼓捣过去的知识点,到Servlet部分时,以前学习的时候硬是把从上到下的继承关系和接口实现记得乱七八糟. 这次利用了IDEA的diagram,结果一目了然,也是好用到 ...
- iOS学习——iOS 整体框架及类继承框架图
整理自:IOS 整体框架类图值得收藏 一 整体框架 在iOS开发过程中,对iOS的整理框架的了解和学习是必不可少的一个环节,今天我们就好好来了解一下iOS的整体框架.首先贴一个关于iOS的框架介绍:i ...
- phpstorm查看类的继承关系
在看一些框架源码时,有些类有很多的继承或者接口,有一款神奇的帮助很重要 选中一个类文件,右键,选择diagrams->show diagrams 即可得到类的继承关系,如上右图 使用函数 fun ...
- java集合继承关系图
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式. 数组虽然也可以存储对象,但长度是固定的:集合长度是可变的,数组中可以存储基 ...
- MVC值提供组件ValueProvider的继承关系
MVC请求过程中中各组件调用顺序:值提供组件(IValueProvider)->模型绑定组件(IModelBinder)->模型验证组件 值提供组件接口 public interface ...
随机推荐
- C#中引用类型和值类型的区别,分别有哪些
C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型. C#的引用类型包括:数组,用户定义的类.接口.委托,object,字符串. 数组的元素,不管是引用类型还是值类型, ...
- js实现页面跳转的八种方式
整理一下JavaScript八种跳转方式,欢迎评论补充! 第一种方法: <script> window.location.replace('http://www.cnblogs.com/c ...
- Angular4 step by step.1
1.官网地址 :https://angular.cn/guide/quickstart 2.在线学习地址:https://embed.plnkr.co/?show=preview 3.效果截图哇哈哈
- MyBatis 学习(一)
一.MyBatis 1.MyBatis 介绍(百度) MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数 ...
- MyBatis_注解式开发
一.注解式开发 mybatis的注解主要替换映射文件. 二.基础语法 注解首字母大写,因为注解与类.接口是同一级别的(类同一层级的:类,接口,注解,枚举).一个注解,后台对应着一个@interface ...
- untiy3d小工具——修改scene与prefab中的sprite
坑1:因为替换图片要获取所有包含image的组件,开始我使用的是gameobject.getComponents<Image>()和FindObjectsOfType<Image&g ...
- maven(04)--一个简单的项目
简单介绍 一个maven项目,使用hibernate框架,实现向mysql数据库中添加和获取操作,其他操作也是类似 如果你没有hibernate,那么也不要紧,这里主要介绍如何在一个maven项目中引 ...
- Bzoj3105:[CQOI2013]新Nim游戏
题面 传送门 Sol 也是拿出一些数,使剩下的异或起来不为\(0\) 而线性基内的数异或不出\(0\) 那么从大到小加到线性基内 然后中途为\(0\)了,就取走它 这样我们使最大的在线性基内,剩下的是 ...
- layui-学习02-全局样式
CSS内置公共基础类 类名(class) 说明 布局 layui-main 用于设置一个宽度为 1140px 的水平居中块(无响应式) layui-inline 用于将标签设为内联块状元素 layui ...
- MySQL基于mysqldump快速搭建从库
MySQL主从搭建总的来说大致分为3个步骤: 1. 为主从实例添加复制所需参数以及创建复制用的账户 2. 需要 […]