日志组件:

  我们经常在开发项目的时候,需要打印记录项目过程中的一些日志。那我们经常大概会用到 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. 图解JVM类加载机制和双亲委派模型

    我们都知道以 .java 结尾的 Java 源文件,经过编译之后会变成 .class 结尾的字节码文件.JVM 通过类加载器来加载字节码文件,然后再执行程序. 什么时候加载一个类 那么,什么时候类加载 ...

  2. Material Design 组件之 AppBarLayout

    AppBarLayout 是一个垂直方向的 LinearLayout,它实现了许多符合 Material Design 设计规范的状态栏应该具有的功能,比如滚动手势. AppBarLayout 一般直 ...

  3. Mitmproxy 安装

    Mitmproxy Python 安装步骤 官方文档 安装mitmproxy 在cmd中输入 pip install mitmproxy 安装完成后,在cmd中输入 mitmdump(windows不 ...

  4. BFS、DFS ——J - Nightmare

    J - Nightmare Ignatius had a nightmare last night. He found himself in a labyrinth with a time bomb ...

  5. 《Three.js 入门指南》3.1.1 - 基本几何形状 -圆环面(TorusGeometry)

    3.1 基本几何形状 圆环面(TorusGeometry) 构造函数 THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments ...

  6. touch多点触摸事件

    touch--单点 targetTouches. changeTouches 多点: targetTouches--当前物体上的手指数 *不同物体上的手指不会互相干扰 不需要做多点触摸的时候---平均 ...

  7. Java中的数据结构-HashMap

    Java数据结构-HashMap 目录 Java数据结构-HashMap 1. HashMap 1.1 HashMap介绍 1.1.1 HashMap介绍 1.1.2 HashMap继承图 1.2 H ...

  8. 2016蓝桥杯报纸页数(C++C组)

    题目: 报纸页数X星球日报和我们地球的城市早报是一样的,都是一些单独的纸张叠在一起而已.每张纸印有4版.比如,某张报纸包含的4页是:5,6,11,12,可以确定它应该是最上边的第2张报纸.我们在太空中 ...

  9. MySQL学习之路5-数据表的常用操作

    排序 :order by  desc select * from <tablename> order by <字段名> desc:order by默认升序 desc 降序 分组 ...

  10. Python 操作mysql数据库之 SQLAlchemy 案例详解

      前言: 字段声明类型中,最右边的是数据库中对应的字段,我们依然可以使用,其左边的的 SQLAchemy 则是其自身封装的自定义类型. 本篇不会讲太多的理论知识,因为这个实用性更强,所以通篇全部都是 ...