• 一、什么是日志


    一、什么是日志?

    在生活上,日志是一种日记,用于记录我们生活的一点一滴,我们可以通过日志回忆美好,平淡抑或是痛苦的过往。对于我们的程序来说日志就是记录
    某个时刻应用执行的信息,错误等。

    在没有比较成熟,好用的日志框架出现之前,我们程序员该这么打印日志呢?一千个哈姆莱特有一千个实现,没有统一的标准,每个公司都是闭门造车,
    A公司造的车子是两个轮子的,B公司的是四个轮子,C公司不仅能在地上跑还能在天上飞,所以这三家公司的日志框架只能给自家用,无法开源给
    其他公司使用,每个公司可能都要根据自己的情况造自己的车。

    那么现在比较成熟,集大家之成,通用的框架实现有哪些呢?
    我们比较熟悉的有log4j,logback等,log4j和logback的作者都是Ceki Gülcü,也在此基础上抽象出了 slf4j api,全称为 The Simple Logging Facade for Java,用来定义日志门面,logback 是在log4j与slf4j基础上优化而来,所以logback的性能要优于log4j,所以本博文将研究logback的源码实现

    二、既然有那么多的日志实现,那如果我同时引入了log4j和logback等多个框架,将会使用哪个呢?

    启动项目的时候会打印警告信息,信息如下:
    SLF4J: Class path contains multiple SLF4J bindings.

    那么这个信息是怎么打出来的呢?

    // 获取日志上下文,内部会自动绑定当前存在的日志实现
    org.slf4j.ILoggerFactory loggerContext = org.slf4j.LoggerFactory.getILoggerFactory();
    
    • 1
    • 2

    上面这个方法会自定绑定日志实现,在绑定之前会判断当前系统中存在的实现是否有多个,如果有多个那么将会提示警告信息,具体代码
    如下:

    
    static Set<URL> org.slf4j.LoggerFactory.findPossibleStaticLoggerBinderPathSet() {
            // use Set instead of list in order to deal with bug #138
            // LinkedHashSet appropriate here because it preserves insertion order
            // during iteration
            Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
            try {
                ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
                Enumeration<URL> paths;
                if (loggerFactoryClassLoader == null) {
                    // STATIC_LOGGER_BINDER_PATH =》org/slf4j/impl/StaticLoggerBinder.class
                    paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
                } else {
                    paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
                }
                while (paths.hasMoreElements()) {
                    URL path = paths.nextElement();
                    staticLoggerBinderPathSet.add(path);
                }
            } catch (IOException ioe) {
                Util.report("Error getting resources from path", ioe);
            }
            return staticLoggerBinderPathSet;
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    上面这段代码会检查类路径下有多少个 org/slf4j/impl/StaticLoggerBinder.class,如果出现多个那么将会警告多个实现的日志,那么问题
    来了,既然只是警告没有抛出错误,那么它到底最后使用的是哪个日志实现呢?这个主要看系统加载文件的顺序了,在不同的系统上它的加载
    顺序可能不相同,比如我在mac电脑上启动能正常打印日志,但是在linux上却不能,所以最后一个系统里就只留一个日志实现,不要出现多个。

  • 相关阅读:
    js 实现图片纵向拼接并下载
    探花交友_第10章_实现推荐功能
    WMS仓储管理系统:从集成到面向未来的策略
    C++ Reference: Standard C++ Library reference: Containers: deque: deque
    【微信小程序】vertical属性、文章列表
    Oracle中给表赋予权限
    【RocketMQ】消息的高可用与负载均衡
    华为无线设备WLAN QoS配置命令
    一名优秀的软件测试人员,需要掌握哪些技能?
    Kafka(四)消费者消费消息
  • 原文地址:https://blog.csdn.net/qq_27785239/article/details/126281748