一文讲透java日志框架

在项目开发过程中,有一个必不可少的环节就是记录日志,相信只要是个程序员都用过,可是咱们自问下,用了这么多年的日志框架,你确定自己真弄懂了日志框架的来龙去脉嘛?下面笔者就详细聊聊java中常用日志框架的关系及使用方法。

如上图,在开发过程中常用的日志框架大概包括:log4j、jul、jcl、slf4j几种,其中log4j和jul是两种具体的日志实现框架,而jcl和slf4j则不是一个具体的实现框架,而只是日志框架的搬运工,他们定义了日志的接口,底层具体使用的是log4j或jul,具体关系可以参考上图所示。朋友们是不是有个疑问,既然有了Log4j和jul这种日志实现框架,那为啥还要有jcl和slf4j两个框架呢?这里根据具体的项目来说明。

在实际的项目开发过程中,随着项目的变动,什么新需求,人员变动都是很正常的,假如有一个项目很早的时候架构师使用的是jul作为日志框架,当项目运行一段实践后,新来了一个项目经理,接到了一个新的需求,需要更换成log4j日志框架(原因有很多),请问这时候需要怎么办呢?如果要更换,那么修改的成本就比较高了,需要修改整个系统了,复杂度可想而知。可是如果使用的是jcl或者slf4j这种框架,那情况就完全不一样了,因为jcl和slf4j采用的是面向“接口编程”的设计方式,它不是一种具体的日志实现,可以灵活支持其他的日志实现框架,这样如果需要从原来的使用jul更换成log4j,那就轻松多了,只要修改下依赖就可以搞定了。

好了,废话少说,下面详细描述每种日志框架的具体应用及实现原理:

一、log4j

log4j是java日志框架的一种具体实现,可以说是目前java项目中使用最广泛的日志框架,使用步骤如下:

1.添加log4j依赖

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2.使用demo

import org.apache.log4j.Logger;
public class Log4jTest {
    private final static Logger logger = Logger.getLogger("logTest");
    public static void main(String[] args) {
        logger.info("log4j test");
    }
}

二、jul

jul全程是java Util Log,它是jdk自带的日志实现,不需要引入其他依赖包,直接使用即可。

import java.util.logging.Logger;
public class JulLogTest { 
    private final static Logger logger = Logger.getLogger("JulLogTest");
    public static void main(String[] args) {
        logger.info("jul test");
    }
}

三、jcl

jcl是java commons logging的简称,它不是具体的日志实现框架,而是一种日志框架的抽象,使用步骤如下:

1.添加commons logging依赖包

注意log4j的依赖包不是必须的,如果没有引入log4j依赖包,则使用的是jul日志实现:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

<!--log4j日志配置-->
 <dependency>
       <groupId>log4j</groupId>
       <artifactId>log4j</artifactId>
       <version>1.2.17</version>
</dependency>

2.使用demo

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class JclLogTest {
    private final static Log log = LogFactory.getLog("jclLogTest");
    public static void main(String[] args) {
        log.info("jcl test");
    }
}

3.原理分析

jcl是如何实现灵活使用不同的日志实现框架的呢?从上述实例中,咱们进入LogFactory的具体实现类LogFactoryImpl的getInstance方法,这个方法是获取具体Log对象的方法:

public Log getInstance(String name) throws LogConfigurationException {
    Log instance = (Log) instances.get(name);
    if (instance == null) {
        instance = newInstance(name);
        instances.put(name, instance);
    }
    return instance;
}

在newInstance方法中有一段代码:

instance = discoverLogImplementation(name);

这段代码调用discoverLogImplementation去发现日志的具体实现:

for(int i=0; i<classesToDiscover.length && result == null; ++i) {
    result = createLogFromClass(classesToDiscover[i], logCategory, true);
}

在discoverLogImplementation方法中,默认情况下,会进入如上代码逻辑,其中classesToDiscover数组列出了jcl默认支持的日志实现类,如下代码所示,好了,现在大家清楚了嘛?jcl是循环加载这个数组中的对象,加载到了就返回了,所以从代码中咱们可以看出,jcl优先的日志实现是有先后顺序的,优先使用的是log4j:

private static final String[] classesToDiscover = {
        "org.apache.commons.logging.impl.Log4JLogger",
        "org.apache.commons.logging.impl.Jdk14Logger",
        "org.apache.commons.logging.impl.Jdk13LumberjackLogger",
        "org.apache.commons.logging.impl.SimpleLog"
};

四、slf4j

1.添加slf4j依赖包

<!--
	slf4j配置
    slf4j-api是接口包,必须引入
		以下三个随便选择一个:
    slf4j绑定的依赖,slf4j-jcl绑定jcl,也就是绑定jcl作为具体的日志实现
    slf4j-log4j12则是绑定log4j,使用log4j作为具体的日志实现
    slf4j-jdk14绑定JDK,使用jdk默认的日志实现
-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.2</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-jcl</artifactId>
    <version>1.7.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-jdk14</artifactId>
    <version>1.7.2</version>
    <scope>runtime</scope>
</dependency>

2.使用demo

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Slf4jLogTest {
    private final static Logger logger = LoggerFactory.getLogger("Slf4jLogTest");
    public static void main(String[] args) {
        logger.info("slf4j test");
    }
}

3.原理分析

slf4j采用的是绑定机制来确定具体的日志实现框架,具体如何绑定呢?这里我们进入LoggerFactory.getLogger方法:

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

这里返回的Logger对象是从ILoggerFactory接口的具体实现类返回的,继续进入getILoggerFactory方法,在该方法中我们可以看到有如下代码:

return StaticLoggerBinder.getSingleton().getLoggerFactory();

好了,核心就是这个StaticLoggerBinder实现类,这个实现类在slf4j-log4j12、slf4j-jcl、slf4j-jdk14这三个不同的依赖jar包中都有自己的实现,从而通过不同的日志工厂类(ILoggerFactory)得到不同的Logger对象。

以上就是咱们项目过程中常用的日志框架关系整理,欢迎大家一起来交流学习。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ESD(Electrostatic Discharge,静电放电)是一种瞬时放电现象,通常是由人体或设备上积累的静电电荷引起的。一般来说,ESD会导致电子设备损坏或误操作,因此必须采取措施来避免ESD。 在设计中,ESD保护应该开始于PCB的物理设计。一个好的物理设计将使ESD泄放的能量尽可能地均匀地分散到整个电路板上。这种物理设计包括有效的接地,涂覆和排列PCB层。同时,这也需要考虑到整个系统的电缆结构、机箱接地和隔离等因素,从而最大限度地提高整个系统的耐ESD能力。 此外,在设计电路时,还需要考虑到ESD保护措施。主要的保护措施包括使用可靠的ESD保护器件,如TVS器件、瞬变压抑器和热释电器件,以保护线路免受ESD的影响。此外,在设计输入、输出和供电接口时,还应该采用合适的线路过滤器和电容器,以进一步提高系统的ESD耐受性。 最后,测试是ESD保护设计的重要环节。ESD测试可以验证保护设计的有效性,并排除措施上的缺陷。通常,测试人员会使用标准ESD模拟器来模拟真实的ESD事件。在测试过程中,应注意对设备进行预处理,如去静电和适当的人体模拟。此外,还应该制定合适的检验标准以确保测试的准确性和可重复性。 总之,ESD保护设计至关重要,因为它能够保护电子设备免受静电放电的损害。为了实现可靠的ESD保护,这需要考虑物理设计和电路设计,以及有效的测试工具。最后,只有将所有这些因素合理结合,才能实现有效的ESD保护设计。 ### 回答2: ESD(Electrostatic Discharge,静电放电)指的是在两个带有不同电荷的物体接触或者靠近时,电荷之间发生放电的现象。这种放电可以对各种电子元器件和电路造成损害,从而影响设备的性能和寿命。 ESD的原理可以通过三种方式传递:空气中的放电、直接接触和电感耦合。在实际应用中,ESD对硅芯片、存储器、晶体管等电子元件的损害是非常严重的,这些元件的特性和结构容易受到ESD的影响。 为了防止ESD对电子元件和电路的损坏,需要在设计中采用一些专门的技术,比如在元器件和电路板上增加ESD保护电路、在设备外壳上增加处理工艺等。对于集成电路芯片而言,可以采用对基底和指的进行控制,以及在芯片电路设计过程中合理选择元器件和适当布局等。 总之,ESD保护是电子元器件和电路设计中非常重要的一环,需要采用针对性的技术来减缓和防止ESD对设备的影响,从而保证设备的长期稳定性和可靠性。 ### 回答3: ESD全程为静电放电,是由于静电在两者之间产生的高电压放电引起的电感和电容的相互作用。在现代电子系统中,由于设备的电路越来越小,因此更容易受到静电干扰,人们不得不在设计中考虑如何避免或降低这种静电干扰。本文将从ESD的原理出发,简要介绍如何在电路设计中考虑防止ESD干扰。 ESD的产生是由于静电的积累导致的高电压放电,因此防止ESD干扰的基本原则是减小静电的积累。在电路设计中,静电主要通过两个方面来进行干扰:一是直接放电干扰,即静电直接放电到电路中,导致电路损坏;二是间接放电干扰,即静电放电到设备的金属外壳等部位,导致电磁场干扰影响电路的正常工作。因此,在设计中,需要采用一些措施来减小这些干扰。 1. 选择合适的元器件:在元器件的选择上,要选择一些抗ESD干扰的元器件,如采用ESD保护二极管等,能够减小ESD对电路的影响。 2. 优化电路结构:在电路设计中,要优化电路结构,减少电路间的交叉干扰,避免电路产生高电位差,这样能够减少静电的积累和ESD的辐射。 3. 采用ESD保护电路:在设计电路时,引入一些ESD保护电路,能够有效地减小ESD对电路的影响。例如采用Zener二极管、TVS二极管等保护电路。 在总体设计中,需要综合以上措施,采用一些适合的方案来消除ESD对电路的干扰。同时,在实际使用中,也需要对电路进行定期维护和检测,保证电路的正常运行。在电子技术的快速发展中,ESD防护的问题只会越来越重要,只有对其进行深入的研究和应用,才能更好地保证电子设备的稳定运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值