日志组件:

  我们经常在开发项目的时候,需要打印记录项目过程中的一些日志。那我们经常大概会用到 log4j、jul、jcl、slf4j、simple、nop、logback 等等,那我们就详细介绍下这些组件是怎么做日志打印的

JUL:

JUL全称Java util Logging是java原生的日志框架,使用时不需要另外引用第三方类库,相对其他日志框架使用方便,学习简单,能够在小型应用中灵活使用。
架构介绍:

  

  Loggers :被称为记录器,应用程序通过获取Logger对象,调用其API来发布日志信息。Logger通常为应用程序访问日志系统的入口程序。
  Appenders :也被称为Handlers,每个Logger都会关联一组Handlers,Logger会将日志交给关联Handlers处理,由Handlers负责将日志做记录。Handlers在此是一个抽象,其具体的实现决定了日志记录的位置可以是控制台、文件、网络上的其他日志服务或操作系统日          志等。
  Layouts :也被称为Formatters,它负责对日志事件中的数据进行转换和格式化。Layouts决定了数据在一条日志记录中的最终形式。
  Level :每条日志消息都有一个关联的日志级别。该级别粗略指导了日志消息的重要性和紧迫,我可以将Level和Loggers,Appenders做关联以便于我们过滤消息。
  Filters :过滤器,根据需要定制哪些信息会被记录,哪些信息会被放过。

  总结:
    用户使用Logger来进行日志记录,Logger持有若干个Handler,日志的输出操作是由Handler完成的。
    在Handler输出日志前,会经过Filter的过滤,判断哪些日志级别过滤放行哪些拦截,
    Handler会将日志内容输出到指定位置(日志文件、控制台等)。Handler在输出日志时会使用Layout,将输出内容进行排版

  案例: 

public class JULTest {

    @Test
public void test01() {
// 1.获取日志记录器对象
Logger logger = Logger.getLogger("jul");
// 2.日志记录输出
logger.info("jul");
}
} 

日志的级别:

  jul中定义的日志级别

    java.util.logging.Level中定义了日志的级别:
      SEVERE(最高值)
      WARNING  警告信息
      INFO (默认级别)
      CONFIG  配置信息
      FINE  debug级别信息,信息颗粒度最小
      FINER  debug级别信息
      FINEST(最低值)debug级别信息,信息颗粒度最大
    还有两个特殊的级别:
      OFF,可用来关闭日志记录。
      ALL,启用所有消息的日志记录。

日志级别案例:

@Test
public void testLogLevel() {
// 1.获取日志对象
Logger logger = Logger.getLogger("jul");
// 2.日志记录输出
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}

  由于默认级别是info, 所以以上日志只会打印 info以上级别的日志

修改日志级别:

@Test
public void testLogConfig() throws IOException {
// 1.创建日志记录器对象
Logger logger = Logger.getLogger("jul"); // 一、自定义日志级别
// a.关闭系统默认配置
logger.setUseParentHandlers(false);
// b.创建handler对象
ConsoleHandler consoleHandler = new ConsoleHandler();
// c.创建formatter对象(简单格式转换对象)
SimpleFormatter simpleFormatter = new SimpleFormatter();
// d.进行关联
consoleHandler.setFormatter(simpleFormatter);
logger.addHandler(consoleHandler);
// e.设置日志级别
logger.setLevel(Level.FINE);
consoleHandler.setLevel(Level.FINE); // 二、输出到日志文件
FileHandler fileHandler = new FileHandler("d:/jul.log");
fileHandler.setFormatter(simpleFormatter); logger.addHandler(fileHandler);
// 2.日志记录输出
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}

JCL:

JCL全称为Jakarta Commons Logging,是Apache提供的一个通用日志API。
  它是为 "所有的Java日志实现"提供一个统一的接口,它自身也提供一个日志的实现,但是功能非常弱(SimpleLog)。所以一般不会单独使用它。
  他允许开发人员使用不同的具体日志实现工具: Log4j, Jdk自带的日志(JUL)
  JCL 有两个基本的抽象类:Log(基本记录器)和LogFactory(负责创建Log实例)。

  默认使用 jul 的实现

  案例:

    1.添加依赖

  

  <dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>

    2. 测试

public class JCLTest {

    @Test
public void test() {
// 创建日志对象
Log log = LogFactory.getLog("jcl");
// 日志记录输出
log.info("info");
}
}

  

JCL原理:

  1. 通过LogFactory动态加载Log实现类

    

  2 . 日志门面支持的日志实现数组

    

  3 . 获取具体的日志实现

    

LOG4J:

  Log4j是Apache下的一款开源的日志框架,通过在项目中使用 Log4J,我们可以控制日志信息输出到控制台、文件、甚至是数据库中。我们可以控制每一条日志的输出格式,通过定义日志的输出级别,可以更灵活的控制日志的输出过程。方便项目的调试

  log4j.properties(最简单配置)

log4j.rootLogger=INFO,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n

  案例:

  1. 添加依赖

    <dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>

  2. 测试

@Test
public void test01() {
// 获取日志记录器对象
Logger logger = Logger.getLogger(Log4jTest.class);
// 日志记录输出
logger.info("hello log4j"); // 日志测试
logger.info("info");
}

  

日志的级别:

  每个Logger都有一个日志级别(log level),用来控制日志信息的输出。日志级别从高到低分为:
    fatal 指出每个严重的错误事件将会导致应用程序的退出。
    error 指出虽然发生错误事件,但仍然不影响系统的继续运行。
    warn 表明会出现潜在的错误情形。
    info 一般和在粗粒度级别上,强调应用程序的运行全程。
    debug 一般用于细粒度级别上,对调试应用程序非常有帮助。(默认级别)
    trace 是程序追踪,可以用于输出程序运行中的变量,显示执行的流程。
  还有两个特殊的级别:
    OFF,可用来关闭日志记录。
    ALL,启用所有消息的日志记录。

  注:一般只使用 4个级别,优先级从高到低为 ERROR > WARN > INFO > DEBUG

slf4j: 

  简单日志门面(Simple Logging Facade For Java) SLF4J主要是为了给Java日志访问提供一套标准、规范的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如log4j和logback等。当然slf4j自己也提供了功能较为简单的实现,但是一般很少用到。对于一般的Java项目而言,日志框架会选择slf4j-api作为门面,通过绑定器绑定具体的实现框架(log4j、logback等)进行日志打印,与第三方其它框架统一日志的时候,中间使用桥接器完成桥接。
SLF4J是目前市面上最流行的日志门面。现在的项目中,基本上都是使用SLF4J作为日志系统。
SLF4J日志门面主要提供两大功能:

  1. 日志框架的绑定
  2. 日志框架的桥接

  入门案例:

  1. 添加依赖  

    <dependencies>
<!--slf4j core 使用slf4j必須添加-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<!--slf4j 自带的简单日志实现 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.27</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>

  2. 测试

public class Slf4jTest {

    // 声明日志对象
public final static Logger LOGGER =
LoggerFactory.getLogger("slf4j"); @Test
public void test01() {
//打印日志信息
LOGGER.info("info");
}
}

  

绑定日志的实现(Binding):

  SLF4J支持各种日志框架。SLF4J发行版附带了几个称为“SLF4J绑定”的jar文件,每个绑定对应一个受支持的框架。

  使用slf4j的日志绑定流程:
    1. 添加slf4j-api的依赖
    2. 使用slf4j的API在项目中进行统一的日志记录
    3. 绑定具体的日志实现框架
      1. 绑定已经实现了slf4j的日志框架,直接添加对应依赖
      2. 绑定没有实现slf4j的日志框架,先添加日志的适配器,再添加实现类的依赖
    4. slf4j有且仅有一个日志实现框架的绑定(如果出现多个默认使用第一个依赖日志实现)

  通过maven引入常见的日志实现框架:(根据实际情况选择使用,除了引入下面其中一个,还不能少了 slf4j-api 的引用)

  官方绑定器API地址: http://www.slf4j.org/manual.html

  1. logback

<!-- logback 日志实现 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>

  2. nop

<!-- nop 日志开关(不使用日志功能) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.2</version>
</dependency>

  3. log4j

<!-- 绑定 log4j 日志实现,需要导入适配器,还需要添加 log4j.properties 配置文件 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.26</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

  4. jul

<!-- 绑定 jul 日志实现,需要导入适配器 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.25</version>
</dependency>
<!-- 因为是java原生的日志框架,已经内置了具体实现 -->

  原理:

桥接其它框架日志的实现(Bridging):

  桥接解决的是项目中日志的遗留问题,当系统中存在之前的日志API,可以通过桥接转换到slf4j的实现

    1. 先去除之前老的日志框架的依赖
    2. 添加SLF4J提供的桥接组件
    3. 为项目添加SLF4J的具体实现

    4. 统一应用和框架的日志实现

  迁移的方式:

    如果我们要使用SLF4J的桥接器,替换原有的日志框架,那么我们需要做的第一件事情,就是删除掉原有项目中的日志框架的依赖。然后替换成SLF4J提供的桥接器。

  官方api地址: http://www.slf4j.org/legacy.html

原理:

 

  1. log4j

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<!-- 配置 log4j 的桥接器 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.25</version>
</dependency>

  2. logback

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<!-- 配置 log4j 的桥接器 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.25</version>
</dependency>
<!-- logback 日志实现 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>

  3. jcl

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<!-- 配置 jcl 的桥接器 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.8</version>
</dependency>

  4. jul

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<!-- 配置 jul 的桥接器 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.25</version>
</dependency>

  注:    

    1. jcl-over-slf4j.jar(桥接)和 slf4j-jcl.jar(适配)不能同时部署。前一个jar文件将导致JCL将日志系统的选择委托给SLF4J,后一个jar文件将导致SLF4J将日志系统的选择委托给JCL,从而导致无限循环 。

    2. log4j-over-slf4j.jar和slf4j-log4j12.jar不能同时出现,原因同上

    3 . jul-to-slf4j.jar和slf4j-jdk14.jar不能同时出现,原因同上

    4. 所有的桥接都只对Logger日志记录器对象有效,如果程序中调用了内部的配置类或者是Appender,Filter等对象,将无法产生效果。

关于log4j、jul、jcl、slf4j等等日志组件的理解的更多相关文章

  1. Spring Boot使用Log4j Implemented Over SLF4J生成日志并在控制台打印

    Spring Boot设置切面,执行方法的时候在控制台打印出来,并生成日志文件 引入依赖: <!--日志--> <dependency> <groupId>org. ...

  2. 001-log-log体系-log4j、jul、jcl、slf4j,日志乱象的归纳与统一

    一.概述 log4j→jul→jcl→slf4j之后就开始百花齐放[slf4j适配兼容新老用户] 1.1.log4j阶段 在JDK出现后,到JDK1.4之前,常用的日志框架是apache的log4j. ...

  3. 怎样在自己的 Web 中加入强大的日志系统系统?slf4j 的日志插件必须要知道!

    对于程序猿来讲,一个应用程序的日志管理是极为重要的.因为,它可以帮助我们随时查看应用程序的运行状态.执行效果等信息,从而监控软件系统.或是根据日志信息解决一些重要的问题. 但是在 Java 应用程序中 ...

  4. Java 日志框架概述(slf4j / log4j / JUL / Common-logging(JCL) / logback)

    一.简介 JAVA日志在初期可能官方并没有提供很好且实用的规范,导致各公司或OSS作者选择自行造轮子,这也导致了目前初学者觉得市面上 Java 日志库繁杂的局面. 现在市面流行以 slf4j(Simp ...

  5. 常见java日志系统的搭配详解:关于slf4j log4j log4j2 logback jul jcl commons-logging jdk-logging

    先看一张图: 是不是有点晕, 晕就对了.这个仅仅是 slf4j 的情况,实际上, 我们不仅要接触到 slf4j ,有时候还会接触其他的日志系统.且看下文分解. 1 直接使用各个日志系统 1.1 直接使 ...

  6. java日志组件介绍(common-logging,log4j,slf4j,logback )

    转自:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging是apache提供的一个通用的日志 ...

  7. 转:java日志组件介绍(common-logging,log4j,slf4j,logback )

    原网址:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging common-logging是 ...

  8. 【转】java日志组件介绍(common-logging,log4j,slf4j,logback )

    common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, comm ...

  9. Log4j,Log4j2,logback,slf4j日志学习

    日志学习笔记 Log4j Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.数据库等:我们也可以控制每一条日志的输出格式:通过定义每一条 ...

随机推荐

  1. 将java中Map对象转为有相同属性的类对象(json作为中间转换)

    java中Map对象转为有相同属性的类对象(json作为中间转换) 准备好json转换工具类 public class JsonUtil { private static ObjectMapper o ...

  2. 【Pytest04】全网最全最新的Pytest框架fixture应用篇(2)

    一.Fixture参数之params参数可实现参数化:(可以为list和tuple,或者字典列表,字典元祖等) 实例如下: import pytest def read_yaml(): '] @pyt ...

  3. iOS 状态栏显示/隐藏

    iOS 10为止,将在plist文件中将 View controller-based status bar appearance 设置为NO,就可以用UIApplication设置状态栏. 注意,要在 ...

  4. go语言学习基础-编译文件

    1.创建工程在go的src目录下,比如我的go目录为/Users/yinxin/go,我创建文件夹 test路径为/Users/yinxin/go/src/test; 2.创建文件 main.go , ...

  5. Spring的IOC操作

    Spring的IOC操作 把对象的创建交给spring ioc操作两个部分 (1)ioc的配置文件方式 (2)ioc基于注解的方式 IOC 的底层原理 1.ioc底层原理使用技术 (1)xml配置文件 ...

  6. 001_Three.js中的跨域问题

    001_Three.js中的跨域问题 [情景描述]: 在初始化模型,引入字体和纹理皮肤图片的时候,由于跨域问题,出现了以下提示: Access to image at 'file:///F:/User ...

  7. chrome浏览器的json格式化插件

    JSON-Handle   下载地址:         http://jsonhandle.sinaapp.com/ 插件下载后,在浏览器输入:chrome://extensions/ 将下载后的文件 ...

  8. 1053 Path of Equal Weight (30分)(并查集)

    Given a non-empty tree with root R, and with weight W​i​​ assigned to each tree node T​i​​. The weig ...

  9. Spring Boot入门系列(十)如何使用拦截器,一学就会!

    前面介绍了Spring Boot 如何整合定时任务已经Spring Boot 如何创建异步任务,不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhon ...

  10. flask-script的基本使用

    Flask-Script flask-script的作用是可以通过命令行的形式来操作Flask.例如通过命令跑一个开发的服务器.设置数据库等. 命令的添加方式 1 .使用manage.command: ...