• Logger之Logger.getLogger(CLass)使用(转载)


    之前一直在使用System.out.println()来调试.但是用这种方式开发项目部署到生产环境,会因为众多的控制台输出降低应用的性能.这时候Log4J就成为可平衡开发和部署应用的利器了.

    在项目中使用Log4J并不是一件困难的事情,简单粗暴的方式就是在每个类A中声明一个Logger私有属性

    private static Logger logger = Logger.getLogger(A.class);  
    

    这样虽然简单,但是带来有两个问题:

    1.增加系统开销-每个使用Log4J的类都增加了对象属性.

    2.麻烦:每个使用Logger的类都要重复声明上面Logger对象.

    其实不难发现可以使用重构手法,声明一个公用的类Log4jUtils,处理Logger的公共操作.

    不过呢,问题不这么简单.首先要解决一个问题,Logger.getLogger(A.class)中的A.class有什么用?A.class可以不可以瞎写?

    先做个试验,先简单配置log4j.properties文件

    #日志级别,输出目的地
    log4j.rootLogger=debug,stdout
    
    log4j.appender.stdout=org.apache.log4j.Conso
    leAppender
    log4j.appender.stdout.Target=System.out
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    

    输出格式

    log4j.appender.stdout.layout.ConversionPattern=%c %d{ABSOLUTE} %5p %c{1}:%L - %m%n

    测试类

    import org.apache.log4j.Logger;
    
    /**
     * Created by li on 2015/5/24.
     */
    
    public class LoggerTest {
        private static Logger logger = Logger.getLogger(Object.class);
    
        public static void main(String[] args) {
            logger.debug("Hello World!");
        }
    }
    

    查看结果:

    img

    结合log4j.properties配置的

    log4j.appender.stdout.layout.ConversionPattern=%c %d{ABSOLUTE} %5p %c{1}:%L - %m%n
    

    不难知道%c输出所属的类目,通常就是所在类的全名。但是我们追踪的其实是LoggerTest类,结果返回的却是java.lang.Object,简直就是误导(虽然可以瞎写,但是不建议,因为我们可能需要知道输入日志的类是哪个).

    这时候将LoggerTest类的代码修改

    private static Logger logger = Logger.getLogger(LoggerTest.class);
    

    运行结果变为:

    img

    要的结果终于出现了.至此,明白了getLogger(class)的参数用途:追踪产生此日志的类.

    现在就出现了新的问题:若要使用一个类Log4jUtils来专门处理Logger对象的声明等操作,那么如何处理getLogger(class)的参数问题?

    也就是如何在Log4jUtils得到调用logger对象的类型.

    解决这个困难可以是使用Java的反射机制

    看下面的代码:

    /**
     * Created by li on 2015/5/23.
     */
    public class Log4JUtils{
    
        private static Logger logger =  null;
    
        public static Logger getLogger(){
           if (null == logger){
               //Java8 废弃了Reflection.getCallerClass()
               logger = Logger.getLogger(Reflection.getCallerClass().getName());
               logger.debug("调用者类名"+Reflection.getCallerClass().getName());
           }
            return logger;
        }
    }
    

    修改类LoggerTest的代码:

    /**
     * Created by li on 2015/5/24.
     */
    
    public class LoggerTest {
    //    private static Logger logger = Logger.getLogger(LoggerTest.class);
    
        public static void main(String[] args) {
            Log4JUtils.getLogger().debug("Hello World!");
        }
    }
    

    运行结果:

    img

    看到这个结果就很爽了.以后项目就可以放弃使用System.out.println()打印语句了.

    log4j中的Logger.getLogger()可以不用加载一个类,也可以传字符串的,这是一种通用做法,比如

    Logger logger = Logger.getLogger("com.MyLog");
    logger.info("...");
    那么Logger首先会去找log4j.properties中的log4j.category.com.MyLog对应的Appender来写日志,当然如果你配置了rootAppender的话不用配其他的Appender也没关系。

    示例:

    /**
     * @Author xiayuxuanmin
     * @Date 2019/8/10
     * @Description
     */
    public class LoggerTest {
        private static Logger logger = Logger.getLogger("myLog");
    
        public static void main(String[] args) {
            logger.info("我是日志");
        }
    }
    

    控制台输出:

    img

    由上可知:可以直接在getLogger()方法中传入一个string类型的字符串,那么就可以省去类的开销(这里也可以瞎写的,但是最好和当前类保持一致,这样在看日志的时候可以知道是哪个类产生的日志...)

    原文链接:https://my.oschina.net/u/2331760/blog/3086024

    保持对优秀的热情
  • 相关阅读:
    关于this的指向问题
    blued面经
    数美(sm)面经
    xue球 面经
    jquery中的$("#id")与document.getElementById("id")的区别
    如何知道iframe文件下载download完成
    前端linux基础
    Vue.js 初级面试题
    React 面试题
    从输入URL到页面加载的过程
  • 原文地址:https://www.cnblogs.com/luckforefforts/p/13684432.html
Copyright © 2020-2023  润新知