java中log使用小结

 更新时间:2023年09月11日 09:14:30   作者:2021不再有雨  
本文主要介绍了java中log使用小结,一文搞清楚java所有日志框架,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、概述

本文乃博主呕心沥血之作,一文搞清楚java所有日志框架。阅读前请先收藏。

1.1. 核心日志框架

核心日志框架,就是实际干活的日志框架。总体而言,市面上的使用日志框架体系主要有

  • jul(java.util.logging) jdk1.4加入,为了对抗log4j,效率灵活性较差使用较少
  • log4j 最广泛应用的日志框架,成为事实上的标准
  • logback 基于slf4j-api接口实现,性能高于log4j
  • log4j2 重写了log4j,性能高于log4j,logback

1.2 门面日志框架

核心日志框架能单独使用,但多框架集成使用时使用会有冲突。所以出现了门面日志框架。

门面日志框架特征有:

  • 提供统一日志使用接口,核心日志框架去实现门面日志框架的接口。
  • 应用不使用具体的核心日志框架,只使用门面日志框架。不依赖核心日志框架,只依赖门面日志框架。
  • 这样就算底层换核心框架依赖,不影响现有日志的使用。

目前主流的门面框架主要有JCL和SLF4J:

  • JCL(commings-log) Apache提供的comming-log
  • SLF4J(simple log facade for java) Log4j、Logback、Log4j2作者提供

二、最佳实践

2.1 核心日志框架API包

各核心日志框架单独使用的依赖,demo里的version不限制。

  • log4j
<!-- log4j的API包 -->
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
</dependency>
  • log4j2
<!-- log4j2的两个API包 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.9.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.9.1</version>
</dependency>
  • logback
        <!-- logback的两个API包-->
				<!-- logback无法单独使用,只能和slf4j集合使用-->
			  <!-- logback-classic实现了slf4j向logback的转换-->
			  <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
  • jul

jdk自带API,无依赖包

2.2 门面日志框架依赖

  • jcl
        <!-- jcl的API包 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>

slf4j

   <!-- slf4j的API -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency>

2.3 集成使用

2.3.1 集成jcl

总结如下:

  • JCL集成其他日志框架,只有log4j/jul没有中间包
  • JCL同时集成其他核心日志框架,使用JCL打印日志优先级: log4j2>log4j>jul
  • JCL同时和jul/log4j/log4j2集成,jcl没有全局整合能力各日志全部生效
  • JCL同时和jul/log4j/log4j2集成,此时使用JCL打印日志生效的是log4j2
  • slf4j转向JCL前提是没有slf4j的实现框架依赖,否则slf4j实现优先级更高

集成jul

默认jcl就是集成jul的

        <!-- jcl的API包 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
        </dependency>

集成log4j

        <!-- jcl的API包 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
        </dependency>
        <!-- log4j的API -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

集成log4j2

        <!-- jcl的API包 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- log4j2的两个API包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.9.1</version>
        </dependency>
        <!-- 适配包:jcl转向log4j2  -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jcl</artifactId>
            <version>2.9.1</version>
        </dependency>

集成slf4j

 <!-- slf4j的API包 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配包:slf4j转向jcl -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jcl</artifactId>
            <version>1.7.25</version>
        </dependency>
			 <!-- JCL的实现包,可以为jul/log4j/logj42,这里省略。默认是jul -->

2.3.2 集成slf4j

2.3.2.1 slf4j集成单一框架

总结如下:

  • SLF4J转向其他日志框架都需要对应适配包
  • 其他日志框架经过JCL转向SLF4J时,一般可以省略JCL通过匹配包直接转向SLF4J不再展开
  • SLF4J和具体日志框架的双向适配包不能同时存在(需排除冲突),否则会循环依赖栈溢出.包括:
    • slf4j-jdk14和jul-to-slf4j(运行时直接栈溢出)
    • slf4j-log4j12和log4j-over-slf4j(启动会检测报错)
    • log4j-slf4j-impl和log4j-to-slf4j(运行时直接栈溢出)
    • slf4j-jcl和jcl-over-slf4j(启动会检测报错)

集成jul

   			<!-- slf4j的API -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配包:slf4j转向jul -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.7.25</version>
        </dependency>
				<!-- 适配包:jul转向slf4j -->
        <!-- 若和slf4j-jdk14包同时存在会造成jul和slf4j循环转化造成栈溢出,所以要排除 -->
<!--        <dependency>-->
<!--            <groupId>org.slf4j</groupId>-->
<!--            <artifactId>jul-to-slf4j</artifactId>-->
<!--            <version>1.7.25</version>-->
<!--        </dependency>-->

集成log4j

        <!-- log4j的API包 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- slf4j的API -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- log4j对slf4j的实现:log4j转slf4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配包:log4j转向slf4j -->
        <!-- log4j-over-slf4j和slf4j-log4j12同时存在会循环依赖栈溢出,需要排除-->
<!--        <dependency>-->
<!--            <groupId>org.slf4j</groupId>-->
<!--            <artifactId>log4j-over-slf4j</artifactId>-->
<!--            <version>1.7.25</version>-->
<!--        </dependency>-->

集成log4j2

        <!-- log4j2的两个API包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.9.1</version>
        </dependency>
        <!-- slf4j的API -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配包: slf4j转向log4j2 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.9.1</version>
        </dependency>
        <!-- 适配包: log4j2转向slf4j -->
        <!-- log4j-to-slf4j和log4j-slf4j-impl同时存在会循环依赖栈溢出,需要排除-->
<!--        <dependency>-->
<!--            <groupId>org.apache.logging.log4j</groupId>-->
<!--            <artifactId>log4j-to-slf4j</artifactId>-->
<!--            <version>2.9.1</version>-->
<!--        </dependency>-->

集成logback

<!-- slf4j的API包 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- logback的两个API包-->
        <!-- logback的Log相关API和包路径和slf4j一样,所以logback可以看作是slf4j的默认实现包-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

集成JCL

        <!-- jul默认是JCL默认的实现包,也可以指定为log4j/log4j2 -->
				<!-- jcl的API包 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- slf4j的API包 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配包: slf4j转向jcl -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jcl</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- jcl-over-slf4j和slf4j-jcl同时存在会循环依赖栈溢出,需要排除-->
        <!-- 适配包: jcl转向slf4j -->
<!--        <dependency>-->
<!--            <groupId>org.slf4j</groupId>-->
<!--            <artifactId>jcl-over-slf4j</artifactId>-->
<!--            <version>1.7.25</version>-->
<!--        </dependency>-->

2.3.2.2 slf4j整合混合框架

slf4j获取具体框架的流程如下,可得知slf4j最终只能转向单个日志框架。

LoggerFactory.getLogger触发初始化
-> 根据classLoader查找org/slf4j/impl/StaticLoggerBinder.class,check不能有多个
-> 触发org.slf4j.impl.StaticLoggerBinder(不同集成框架路径相同实现不同)的getBean初始化
-> 报告StaticLoggerBinder的实际采用
-> slf4j版本检验
-> 根据StaticLoggerBinder获取org.slf4j.ILoggerFactory
-> 根据ILoggerFactory获取到org.slf4j.Logger

两个或以上的日志框架使用时,需要整合。达到以下目标:

  • 全部日志API生效,能正常输出日志
  • 排除冲突,避免循环转换栈溢出
  • 排除冲突,避免slf4j转向实现框架

根据最终转向的日志框架分类:

最终整合为jul

最终整合为log4j

最终整合为log4j2

最终整合为logback

三、总结

3.1 所有相关包

3.1.1 核心日志框架包

        <!-- log4j的API包 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- log4j2的两个API包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.9.1</version>
        </dependency>
				<!-- logback的两个API包-->
        <!-- logback的Log相关API和包路径和slf4j一样,所以logback可以看作是slf4j的默认实现包-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

3.1.2 门面日志框架

<!-- slf4j的API -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
			  <!-- jcl的API包 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>

3.1.3 适配包

        <!-- 适配包:slf4j转向jul -->
        <!-- jul-to-slf4j和slf4j-jdk14包同时存在会造成jul和slf4j循环转化,所以要排除 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配包:jul转向slf4j -->
        <!-- jul-to-slf4j和slf4j-jdk14包同时存在会造成jul和slf4j循环转化,所以要排除 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>
				<!-- 适配包:slf4j转向log4j -->
        <!-- log4j-over-slf4j和slf4j-log4j12同时存在会循环依赖栈溢出,需要排除-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配包:log4j转向slf4j -->
        <!-- log4j-over-slf4j和slf4j-log4j12同时存在会循环依赖栈溢出,需要排除-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配包: slf4j转向log4j2 -->
        <!-- log4j-to-slf4j和log4j-slf4j-impl同时存在会循环依赖栈溢出,需要排除-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.9.1</version>
        </dependency>
        <!-- 适配包: log4j2转向slf4j -->
        <!-- log4j-to-slf4j和log4j-slf4j-impl同时存在会循环依赖栈溢出,需要排除-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-to-slf4j</artifactId>
            <version>2.9.1</version>
        </dependency>
        <!-- 适配包: slf4j转向jcl -->
        <!-- jcl-over-slf4j和slf4j-jcl同时存在会循环依赖栈溢出,需要排除-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jcl</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- jcl-over-slf4j和slf4j-jcl同时存在会循环依赖栈溢出,需要排除-->
        <!-- 适配包: jcl转向slf4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配包:jcl转向log4j2  -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jcl</artifactId>
            <version>2.9.1</version>
        </dependency>

3.2 依赖冲突解决总结

双向适配包循环依赖

slf4j-jdk14和jul-to-slf4j(运行时直接栈溢出)
slf4j-log4j12和log4j-over-slf4j(启动会检测报错)
log4j-slf4j-impl和log4j-to-slf4j(运行时直接栈溢出)
slf4j-jcl和jcl-over-slf4j(启动会检测报错)

slf4j单个实现类

使用slf4j整合其他框架时,只能转向单个日志框架,即class路径只能有一个org.slf4j.impl.StaticLoggerBinder

因此以下包不能同时使用,只能出现一个:

slf4j-jdk14

slf4j-log4j12

log4j-slf4j-impl

logback-classic

slf4j-jcl

其他冲突

比如:

log4j.jar 低版本的和高版本冲突:目前测试下来:log4j1.2.6和1.2.17 两个jar同时引入导致日志不能打印

到此这篇关于java中log使用小结的文章就介绍到这了,更多相关java log使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot整合Redis实现高并发数据缓存的示例讲解

    SpringBoot整合Redis实现高并发数据缓存的示例讲解

    这篇文章主要介绍了SpringBoot整合Redis实现高并发数据缓存,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • Java调用Python代码的几种方法小结

    Java调用Python代码的几种方法小结

    Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Python代码,从而最大化利用两个语言的优势,需要的朋友可以参考下
    2025-01-01
  • SpringBoot临时属性设置方法

    SpringBoot临时属性设置方法

    这篇文章主要介绍了SpringBoot临时属性设置方法,SpringBoot工程可以基于java环境独立进行jar文件启动服务,文中给大家提到了命令行启动常见问题以及解决方案,需要的朋友可以参考下
    2022-09-09
  • 浅析JavaMail发送邮件后再通过JavaMail接收格式问题

    浅析JavaMail发送邮件后再通过JavaMail接收格式问题

    这篇文章主要介绍了JavaMail发送邮件后再通过JavaMail接收格式问题 ,本文通过代码实例给大家详细解说,需要的朋友可以参考下
    2019-06-06
  • SpringBoot2.x配置多数据源方式

    SpringBoot2.x配置多数据源方式

    这篇文章主要介绍了SpringBoot2.x配置多数据源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Java设计模式之组合模式的示例详解

    Java设计模式之组合模式的示例详解

    组合模式,又叫部分整体模式,它创建了对象组的数据结构组合模式使得用户对单个对象和组合对象的访问具有一致性。本文将通过示例为大家详细介绍一下组合模式,需要的可以参考一下
    2022-03-03
  • 关于SpringBoot拦截器拦截静态资源的问题

    关于SpringBoot拦截器拦截静态资源的问题

    这篇文章主要介绍了关于SpringBoot拦截器拦截静态资源的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 详解在spring boot中消息推送系统设计与实现

    详解在spring boot中消息推送系统设计与实现

    这篇文章主要介绍了详解在spring boot中消息推送系统设计与实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • Mybatis + js 实现下拉列表二级联动效果

    Mybatis + js 实现下拉列表二级联动效果

    这篇文章给大家介绍基于Mybatis + js 实现下拉列表二级联动效果,实现代码分为前端界面实现和后端处理方法,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-06-06
  • Maven的配置文件pom.xml详解(含常用plugin)

    Maven的配置文件pom.xml详解(含常用plugin)

    pom.xml是Maven项目的核心配置文件,它是 项目对象模型 - Project Object Model(POM)的缩写,本文我们将全面解析pom.xml,了解其结构和属性,以及如何使用它来管理项目,感兴趣的朋友跟随小编一起看看吧
    2024-08-08

最新评论