文档章节

slf4j查看

dxbj1010
 dxbj1010
发布于 2015/10/10 10:20
字数 517
阅读 36
收藏 0
点赞 0
评论 0

###slf4j查看

  1. 先从LoggerFactory这个类入手,起始于getLogger方法

    public static Logger getLogger(String name) {
    	ILoggerFactory iLoggerFactory = getILoggerFactory();
    	return iLoggerFactory.getLogger(name);
    }
    

getILoggerFactory调用后找寻的是类路中StaticLoggerBinder的实现类。

	private final static void bind() {
	    try {
	      Set staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
	      reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
	      // the next line does the binding
	      StaticLoggerBinder.getSingleton();
	      INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
	      reportActualBinding(staticLoggerBinderPathSet);
	      emitSubstituteLoggerWarning();
	    } catch (NoClassDefFoundError ncde) {
	      String msg = ncde.getMessage();
	      if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
	        INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
	        Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
	        Util.report("Defaulting to no-operation (NOP) logger implementation");
	        Util.report("See " + NO_STATICLOGGERBINDER_URL
	                + " for further details.");
	      } else {
	        failedBinding(ncde);
	        throw ncde;
	      }
	    } catch (java.lang.NoSuchMethodError nsme) {
	      String msg = nsme.getMessage();
	      if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
	        INITIALIZATION_STATE = FAILED_INITIALIZATION;
	        Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
	        Util.report("Your binding is version 1.5.5 or earlier.");
	        Util.report("Upgrade your binding to version 1.6.x.");
	      }
	      throw nsme;
	    } catch (Exception e) {
	      failedBinding(e);
	      throw new IllegalStateException("Unexpected initialization failure", e);
	    }
	  }

进入到findPossibleStaticLoggerBinderPathSet方法:

	private static Set findPossibleStaticLoggerBinderPathSet() {
	    // use Set instead of list in order to deal with  bug #138
	    // LinkedHashSet appropriate here because it preserves insertion order during iteration
	    Set staticLoggerBinderPathSet = new LinkedHashSet();
	    try {
	      ClassLoader loggerFactoryClassLoader = LoggerFactory.class
	              .getClassLoader();
	      Enumeration paths;
	      if (loggerFactoryClassLoader == null) {
	        paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
	      } else {
	        paths = loggerFactoryClassLoader
	                .getResources(STATIC_LOGGER_BINDER_PATH);
	      }
	      while (paths.hasMoreElements()) {
	        URL path = (URL) paths.nextElement();
	        staticLoggerBinderPathSet.add(path);
	      }
	    } catch (IOException ioe) {
	      Util.report("Error getting resources from path", ioe);
	    }
	    return staticLoggerBinderPathSet;
	  }

通过classLoader加载的类是org/slf4j/impl/StaticLoggerBinder.class是否在类路径存在。如果有多个会或者0个会提示报错信息。

最后间接使用的loggerFactory是Log4jLoggerFactory

private StaticLoggerBinder() {
    loggerFactory = new Log4jLoggerFactory();
    try {
        @SuppressWarnings("unused")
        Level level = Level.TRACE;
    } catch (NoSuchFieldError nsfe) {
        Util.report("This version of SLF4J requires log4j version 1.2.12 or later. See also http://www.slf4j.org/codes.html#log4j_version");
    }
}

通过getLogger方法得到是log4j jar包里面的org.apache.log4j.Logger log4jLogger

public Logger getLogger(String name) {
    Logger slf4jLogger = loggerMap.get(name);
    if (slf4jLogger != null) {
        return slf4jLogger;
    } else {
        org.apache.log4j.Logger log4jLogger;
        if (name.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME))
            log4jLogger = LogManager.getRootLogger();
        else
            log4jLogger = LogManager.getLogger(name);

        Logger newInstance = new Log4jLoggerAdapter(log4jLogger);
        Logger oldInstance = loggerMap.putIfAbsent(name, newInstance);
        return oldInstance == null ? newInstance : oldInstance;
    }
}

ConcurrentMap会多一个方法putIfAbsent相对于普通map。不存在的时候插入,存在的时候不改变。--相对也是线程安全的。

logger返回时候 还是要包装一下成org.slf4j.Logger接口,方便通用。

public void debug(String format, Object arg) {
    if (logger.isDebugEnabled()) {
        FormattingTuple ft = MessageFormatter.format(format, arg);
        logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
    }
}

举出其中一个的例子,logger.isDebugEnabled代替了以前代码里面很繁琐的判断过程。使用装饰器对log4j的logger进行了加强。还支持message占位符支持。也算是一个不错的优点了。

© 著作权归作者所有

共有 人打赏支持
dxbj1010
粉丝 4
博文 11
码字总数 7474
作品 0
武汉
程序员
SLF4J: Multiple bindings were found on the class path

众所周知,SLF4J是一个日志门面框架,它的作用是用于定义统一的日志接口,而具体的日志实现是由各个日志框架实现的,比如log4j,logback等。 问题 在使用SLF4J时,当class path同时包含了多个...

勇敢的飞石 ⋅ 05/17 ⋅ 0

Java混乱的日志体系(logback)(转)

作为一名 Java 程序员,日常开发工作中肯定会接触日志系统,但是众多的框架,包括 Log4j、Log4j2、Logback、Slf4j、Apache Common logging 等等,引用的 maven 依赖众多,到底可以去掉哪些,...

easonjim ⋅ 2017/12/27 ⋅ 0

slf4j 是怎么绑定具体的日志框架的

SLF4J 英文全称是 Simple Logging Facade for Java, 是一个门面(外观)接口或者说各种日志框架的抽象,比如 java.util.logging, logback, log4j 等;使用这货,我们可以不用关心具体的实现...

holysu ⋅ 05/13 ⋅ 0

ssm项目中添加日志 log4j

添加 log4j 环境 1. 导入环境 pom.xml <!-- 12.log4j 下面三个--> <dependency> <groupId>org.bgee.log4jdbc-log4j2</groupId> <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> <version>......

Lucky_Me ⋅ 06/06 ⋅ 0

Log4j 2.0在开发中的高级使用详解

log4j与slf4j、logback比较 而log4j slf4j logback就是目前主流的日志框架。但后两者效率高是第一个。推荐使用:slf4j 或者 logback(spring-boot默认日志实现) log4j是apache实现的一个开源日...

spinachgit ⋅ 04/22 ⋅ 0

如何在ABAP Netweaver和CloudFoundry里记录并查看日志

Netweaver 要记录日志需要有一个checkpoint group,可以自行创建也可以使用标准的。这里我重用标准的group:DEMOCHECKPOINTGROUP。 tcode SAAB,点Display <->Activate进入编辑模式,将Logpo...

JerryWang_SAP ⋅ 06/10 ⋅ 0

Java日志框架-logback的介绍及配置使用方法(纯Java工程)(转)

说明:内容估计有些旧,2011年的,但是大体意思应该没多大变化,最新的配置可以参考官方文档。 一、logback的介绍 Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块...

easonjim ⋅ 2017/11/07 ⋅ 0

每个项目中,你必须知道的11个Java第三方类库。

Java第三方library ecosystem是一个很广阔的范畴。不久前有人撰文:每个项目中,你必须知道的11个Java第三方类库。 单元测试 1.DBUnit DBunit是一个基于junit扩展的数据库测试框架。它提供了...

thinkyoung ⋅ 2015/01/07 ⋅ 0

分布式链路追踪中间件 - SOFATracer

SOFATracer 是一个用于分布式系统调用跟踪的组件,通过统一的 将调用链路中的各种网络调用情况以日志的方式记录下来,以达到透视化网络调用的目的。这些日志可用于故障的快速发现,服务治理等...

匿名 ⋅ 05/31 ⋅ 0

Spring Boot中Starter是什么

比如我们要在Spring Boot中引入Web MVC的支持时,我们通常会引入这个模块spring-boot-starter-web,而这个模块如果解压包出来会发现里面什么都没有,只定义了一些POM依赖。 经过研究,Start...

easonjim ⋅ 2017/09/30 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL 数据库设计总结

规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。 注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的所有字段的长度之和不能超过1000字节...

OSC_cnhwTY ⋅ 45分钟前 ⋅ 0

多线程(四)

线程池和Exector框架 什么是线程池? 降低资源的消耗 提高响应速度,任务:T1创建线程时间,T2任务执行时间,T3线程销毁时间,线程池没有或者减少T1和T3 提高线程的可管理性。 线程池要做些什...

这很耳东先生 ⋅ 52分钟前 ⋅ 0

使用SpringMVC的@Validated注解验证

1、SpringMVC验证@Validated的使用 第一步:编写国际化消息资源文件 编写国际化消息资源ValidatedMessage.properties文件主要是用来显示错误的消息定制 [java] view plain copy edit.userna...

瑟青豆 ⋅ 今天 ⋅ 0

19.压缩工具gzip bzip2 xz

6月22日任务 6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具 6.1 压缩打包介绍: linux中常见的一些压缩文件 .zip .gz .bz2 .xz .tar .gz .tar .bz2 .tar.xz 建立一些文...

王鑫linux ⋅ 今天 ⋅ 0

6. Shell 函数 和 定向输出

Shell 常用函数 简洁:目前没怎么在Shell 脚本中使用过函数,哈哈,不过,以后可能会用。就像java8的函数式编程,以后获取会用吧,行吧,那咱们简单的看一下具体的使用 Shell函数格式 linux ...

AHUSKY ⋅ 今天 ⋅ 0

单片机软件定时器

之前写了一个软件定时器,发现不够优化,和友好,现在重写了 soft_timer.h #ifndef _SOFT_TIMER_H_#define _SOFT_TIMER_H_#include "sys.h"typedef void (*timer_callback_function)(vo...

猎人嘻嘻哈哈的 ⋅ 今天 ⋅ 0

好的资料搜说引擎

鸠摩搜书 简介:鸠摩搜书是一个电子书搜索引擎。它汇集了多个网盘和电子书平台的资源,真所谓大而全。而且它还支持筛选txt,pdf,mobi,epub、azw3格式文件。还显示来自不同网站的资源。对了,...

乔三爷 ⋅ 今天 ⋅ 0

Debian下安装PostgreSQL的表分区插件pg_pathman

先安装基础的编译环境 apt-get install build-essential libssl1.0-dev libkrb5-dev 将pg的bin目录加入环境变量,主要是要使用 pg_config export PATH=$PATH:/usr/lib/postgresql/10/bin 进......

玛雅牛 ⋅ 今天 ⋅ 0

inno安装

#define MyAppName "HoldChipEngin" #define MyAppVersion "1.0" #define MyAppPublisher "Hold Chip, Inc." #define MyAppURL "http://www.holdchip.com/" #define MyAppExeName "HoldChipE......

backtrackx ⋅ 今天 ⋅ 0

Linux(CentOS)下配置php运行环境及nginx解析php

【part1:搭建php环境】 1.选在自己需要安装的安装包版本,wget命令下载到服务器响应目录 http://php.net/releases/ 2.解压安装包 tar zxf php-x.x.x 3.cd到解压目录执行如下操作 cd ../php-...

硅谷课堂 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部