Java 日志系统

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

java的日志系统繁杂,今天趁着解决日志系统冲突的过程,顺带学习一下java的日志系统并做个记录

日志演化历史

  • 最开始出现的是log4j,也是应用最广泛的日志系统,成为了目前java日志系统事实上的标准,一切都是美好的
  • 但java的开发主体sun公司认为自己才是正统,为了干掉log4j在jdk1.4中增加了jul(因为在java.util.logging包下)日志的实现,造成了目前开发者的混乱,迄今为止仍饱受诟病
  • 各个日志系统互相没有关联,替换和统一变的非常麻烦。A项目用log4j作为日志系统,但同时引了B项目,而B项目用jul作为日志系统,那么你的应用就得使用两个日志系统
  • 为了搞定这个坑爹的问题,开源社区apache提供了一个日志框架作为日志的抽象,叫commons-logging,也被称为jcl(java common logging),jcl对各种日志接口进行抽象,抽象出一个接口层,对每个日志实现都适配或者转接,这样这些提供给别人的库都直接使用抽象层即可,较好的解决了上述问题
  • 但这时,作为元老级日志log4j的作者觉得jcl不够好,再度出山,搞出了一个更加牛逼的新的日志框架slf4j(这个也是抽象层),同时针对slf4j的接口实现了一套日志系统,即传说中的logback
  • 同时这个作者心情一好,又把log4j进行了改造,就是所谓的log4j2,同时支持jcl以及slf4j

JCL

使用JCL一般(如果是log4j可以不需要)需要一个配置commons-logging.properties在classpath上,这个文件有一行代码:

org.apache.commons.logging.LogFactory= org.apache.commons.logging.impl.LogFactoryImpl

用于通知JCL想要使用哪个日志系统。用户只要修改LogFactory的实现,就能动态的切换日志系统

SLF4J

slf4j的设计相对较为精巧,作者将接口以及实现分开,其中slf4j-api中定义了接口,开发者需要关心的就是这个接口,无需再关心下层如何实现,同时各个是slf4j接口的实现者只要遵循这个接口,就能够做到日志系统间的无缝兼容

  • slf4j-api的实现目前比较出名的是接口开发者实现的logback,性能相较log4j来讲更加优秀,也支持占位符等新特性。
  • 同时为了兼容log4j,slf4j-log4j12实现了slf4j-api,作为log4j兼容的适配器,使得用户用起来像在用log4j
  • 为了兼容jul,slf4j-jdk14也实现了slf4j-api,作为jul兼容的适配器,使得用户用起来像在用jul
  • 有了实现,还需要一个桥接器,桥接器将对jcl的调用转接到slf4j上:

    • jul-to-slf4j把对jul的调用桥接到slf4j上
    • jcl-over-slf4j把对jcl的调用桥接到slf4j上
    • log4j-over-slf4j把对log4j的调用桥接到slf4j上

日志系统的冲突

多种日志系统并不意味着程序中只能存在一种日志系统,比如log4j与logback是完全可以共存的。
目前日志系统的冲突主要分为两种:

  • 同一个日志系统的多个实现
  • 桥接接口与实现类

1) 同一个日志系统的多个实现

像slf4j接口实现的冲突,如:

slf4j-log4j、logback、slf4j-jdk14、log4j2之间的冲突

这点很好理解,这几个包都实现了slf4j的接口,同一接口只能有一个实现才能被jvm正确识别
但日志系统仍然非常容易冲突,与传统的jar冲突相同,当jvm发现两个一模一样的实现的时候,它就不知道选择哪个或选择了一个错误的,就会提示ClassNotFound.

2) 桥接jar与实现包
在日志系统中,最常见的就是桥接jar包与实现包的冲突,如:

  • jul-to-slf4jslf4j-jdk14
  • log4j-over-slf4jslf4j-log4j
  • jcl-over-slf4jjcl

因为转接的实现就是将其余的日志系统调用进行一个转发,既然要转发,就必须要定义与原有对象相同的类名、包名,才能正确的被调用,所以桥接jar包就必然与实现包产生冲突。

各个日志系统间的依赖关系

依赖关系可以见下图:
日志系统.png-13.5kB
其中

  • slf4j为纯日志接口
  • logback/slf4j-jdk14/slf4j-log4j12/log4j2均可认为是slf4j的实现类
  • jul/log4j作为最早开始的日志系统,本身就是一种日志的实现,没有任何框架
  • jul-to-slf4j/log4j-to-slf4j/jcl-over-slf4j/作为桥接接口,可以将原有接口的内容进行接收,然后通过slf4j进行输出

其余常见问题

  • slf4j的几个实现jar包一定会冲突,尤其要注意
  • slf4j-api和实现版本最好对应,尤其是1.6.x和1.5.x不兼容,直接升级到最新版本
  • log4j与logback可以同时使用,logback实现slf4j的接口,与log4j没有任何关系,完全可以同时使用
  • 建议选用slf4j + logback,或slf4j + log4j2
  • 日志系统在正常情况下是不会影响应用性能的,但应该注意量,太大量的日志会拖累性能

标签(空格分隔): java


java的日志系统繁杂,今天趁着解决日志系统冲突的过程,顺带学习一下java的日志系统并做个记录

日志演化历史

  • 最开始出现的是log4j,也是应用最广泛的日志系统,成为了目前java日志系统事实上的标准,一切都是美好的
  • 但java的开发主体sun公司认为自己才是正统,为了干掉log4j在jdk1.4中增加了jul(因为在java.util.logging包下)日志的实现,造成了目前开发者的混乱,迄今为止仍饱受诟病
  • 各个日志系统互相没有关联,替换和统一变的非常麻烦。A项目用log4j作为日志系统,但同时引了B项目,而B项目用jul作为日志系统,那么你的应用就得使用两个日志系统
  • 为了搞定这个坑爹的问题,开源社区apache提供了一个日志框架作为日志的抽象,叫commons-logging,也被称为jcl(java common logging),jcl对各种日志接口进行抽象,抽象出一个接口层,对每个日志实现都适配或者转接,这样这些提供给别人的库都直接使用抽象层即可,较好的解决了上述问题
  • 但这时,作为元老级日志log4j的作者觉得jcl不够好,再度出山,搞出了一个更加牛逼的新的日志框架slf4j(这个也是抽象层),同时针对slf4j的接口实现了一套日志系统,即传说中的logback
  • 同时这个作者心情一好,又把log4j进行了改造,就是所谓的log4j2,同时支持jcl以及slf4j

JCL

使用JCL一般(如果是log4j可以不需要)需要一个配置commons-logging.properties在classpath上,这个文件有一行代码:

org.apache.commons.logging.LogFactory= org.apache.commons.logging.impl.LogFactoryImpl

用于通知JCL想要使用哪个日志系统。用户只要修改LogFactory的实现,就能动态的切换日志系统

SLF4J

slf4j的设计相对较为精巧,作者将接口以及实现分开,其中slf4j-api中定义了接口,开发者需要关心的就是这个接口,无需再关心下层如何实现,同时各个是slf4j接口的实现者只要遵循这个接口,就能够做到日志系统间的无缝兼容

  • slf4j-api的实现目前比较出名的是接口开发者实现的logback,性能相较log4j来讲更加优秀,也支持占位符等新特性。
  • 同时为了兼容log4j,slf4j-log4j12实现了slf4j-api,作为log4j兼容的适配器,使得用户用起来像在用log4j
  • 为了兼容jul,slf4j-jdk14也实现了slf4j-api,作为jul兼容的适配器,使得用户用起来像在用jul
  • 有了实现,还需要一个桥接器,桥接器将对jcl的调用转接到slf4j上:

    • jul-to-slf4j把对jul的调用桥接到slf4j上
    • jcl-over-slf4j把对jcl的调用桥接到slf4j上
    • log4j-over-slf4j把对log4j的调用桥接到slf4j上

日志系统的冲突

多种日志系统并不意味着程序中只能存在一种日志系统,比如log4j与logback是完全可以共存的。
目前日志系统的冲突主要分为两种:

  • 同一个日志系统的多个实现
  • 桥接接口与实现类

1) 同一个日志系统的多个实现

像slf4j接口实现的冲突,如:

slf4j-log4j、logback、slf4j-jdk14、log4j2之间的冲突

这点很好理解,这几个包都实现了slf4j的接口,同一接口只能有一个实现才能被jvm正确识别
但日志系统仍然非常容易冲突,与传统的jar冲突相同,当jvm发现两个一模一样的实现的时候,它就不知道选择哪个或选择了一个错误的,就会提示ClassNotFound.

2) 桥接jar与实现包
在日志系统中,最常见的就是桥接jar包与实现包的冲突,如:

  • jul-to-slf4jslf4j-jdk14
  • log4j-over-slf4jslf4j-log4j
  • jcl-over-slf4jjcl

因为转接的实现就是将其余的日志系统调用进行一个转发,既然要转发,就必须要定义与原有对象相同的类名、包名,才能正确的被调用,所以桥接jar包就必然与实现包产生冲突。

各个日志系统间的依赖关系

依赖关系可以见下图:
日志系统.png-13.5kB
其中

  • slf4j为纯日志接口
  • logback/slf4j-jdk14/slf4j-log4j12/log4j2均可认为是slf4j的实现类
  • jul/log4j作为最早开始的日志系统,本身就是一种日志的实现,没有任何框架
  • jul-to-slf4j/log4j-to-slf4j/jcl-over-slf4j/作为桥接接口,可以将原有接口的内容进行接收,然后通过slf4j进行输出

其余常见问题

  • slf4j的几个实现jar包一定会冲突,尤其要注意
  • slf4j-api和实现版本最好对应,尤其是1.6.x和1.5.x不兼容,直接升级到最新版本
  • log4j与logback可以同时使用,logback实现slf4j的接口,与log4j没有任何关系,完全可以同时使用
  • 建议选用slf4j + logback,或slf4j + log4j2
  • 日志系统在正常情况下是不会影响应用性能的,但应该注意量,太大量的日志会拖累性能
相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
2月前
|
JavaScript Java 大数据
基于JavaWeb的销售管理系统设计系统
本系统基于Java、MySQL、Spring Boot与Vue.js技术,构建高效、可扩展的销售管理平台,实现客户、订单、数据可视化等全流程自动化管理,提升企业运营效率与决策能力。
|
2月前
|
Prometheus 监控 Cloud Native
基于docker搭建监控系统&日志收集
Prometheus 是一款由 SoundCloud 开发的开源监控报警系统及时序数据库(TSDB),支持多维数据模型和灵活查询语言,适用于大规模集群监控。它通过 HTTP 拉取数据,支持服务发现、多种图表展示(如 Grafana),并可结合 Loki 实现日志聚合。本文介绍其架构、部署及与 Docker 集成的监控方案。
321 122
基于docker搭建监控系统&日志收集
WGLOG日志管理系统是怎么收集日志的
WGLOG通过部署Agent客户端采集日志,Agent持续收集指定日志文件并上报Server,Server负责展示与分析。Agent与Server需保持相同版本。官网下载地址:www.wgstart.com
|
3月前
|
消息中间件 Java Kafka
Java 事件驱动架构设计实战与 Kafka 生态系统组件实操全流程指南
本指南详解Java事件驱动架构与Kafka生态实操,涵盖环境搭建、事件模型定义、生产者与消费者实现、事件测试及高级特性,助你快速构建高可扩展分布式系统。
212 7
|
28天前
|
移动开发 监控 小程序
java家政平台源码,家政上门清洁系统源码,数据多端互通,可直接搭建使用
一款基于Java+SpringBoot+Vue+UniApp开发的家政上门系统,支持小程序、APP、H5、公众号多端互通。涵盖用户端、技工端与管理后台,支持多城市、服务分类、在线预约、微信支付、抢单派单、技能认证、钱包提现等功能,源码开源,可直接部署使用。
127 23
|
18天前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
167 8
|
4月前
|
存储 Java 数据库连接
java 初学者必看的系统知识结构图详解
本文详解Java知识结构图,涵盖Java语言基础、JVM原理、集合框架、并发编程、网络通信及主流框架(如Spring Boot、MyBatis),并结合学生信息管理系统实例,帮助初学者构建完整知识体系,提升实战开发能力。
130 0
|
29天前
|
安全 前端开发 Java
使用Java编写UDP协议的简易群聊系统
通过这个基础框架,你可以进一步增加更多的功能,例如用户认证、消息格式化、更复杂的客户端界面等,来丰富你的群聊系统。
158 11
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
Java与生成式AI:构建内容生成与创意辅助系统
生成式AI正在重塑内容创作、软件开发和创意设计的方式。本文深入探讨如何在Java生态中构建支持文本、图像、代码等多种生成任务的创意辅助系统。我们将完整展示集成大型生成模型(如GPT、Stable Diffusion)、处理生成任务队列、优化生成结果以及构建企业级生成式AI应用的全流程,为Java开发者提供构建下一代创意辅助系统的完整技术方案。
113 10
|
1月前
|
人工智能 监控 Java
Java与AI智能体:构建自主决策与工具调用的智能系统
随着AI智能体技术的快速发展,构建能够自主理解任务、制定计划并执行复杂操作的智能系统已成为新的技术前沿。本文深入探讨如何在Java生态中构建具备工具调用、记忆管理和自主决策能力的AI智能体系统。我们将完整展示从智能体架构设计、工具生态系统、记忆机制到多智能体协作的全流程,为Java开发者提供构建下一代自主智能系统的完整技术方案。
291 4