java日志框架

**0.**学习目标

  1. 日志的作用和目的
  2. 日志的框架
  3. JUL的使用
  4. LOG4J的使用
  5. JCL的使用

**1.**日志的概念

1.1****日志文件

日志文件是用于记录系统操作事件的文件集合 ,可分为 事件 日志和 消息 日志。具有处理历史数据、诊断 问题的追踪以及理解系统的活动等重要作用。
在计算机中,日志文件是记录在操作系统或其他软件运行中发生的事件或在通信软件的不同用户中间的消息的文件,记录是保持日志的行为。在最简单的情况下,消息被写入单个日志文件。
许多操作系统,软件框架和程序包括日志系统。广泛使用的日志标准是在因特网工程任务组。

1.1.1****调试日志

软件开发中,我们经常需要去调试程序,做一些信息,状态的输出便于我们查询 程序的运行状况 。该日志主要是为了重现问题

1.1.2****系统日志

系统日志是记录系统中硬件、软件和系统问题的信息,同时还可以监视系统中发生的事件。用户可以通过它来检查错误发生的原因,或者寻找受到攻击时留下的痕迹。系统日志包括系统日志、应用程序日志和安全日志。

2. Java****日志框架

问题:

  1. 控制日志输出的内容和格式
  2. 控制日志输出的位置
  3. 日志优化:异步日志,日志文件的归档和压缩
  4. 日志系统的维护
  5. 面向接口开发------日志的门面

2.1****为什么要用日志框架

因为软件系统发展到今天已经很复杂,特别是服务器端软件,涉及到的知识、内容、问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。而且框架一般是成熟的,他可以处理系统很多细节问题,比如:事务处理、安全性、数据流控制等问题。

2.2****现有的日志框架

日志实现: JUL(java util logging) 、 logback 、 log4j 、 log4j2
日志门面: JCL 、 SLF4J

3. JUL****学习

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

3.1 JUL****入门

3.1.1****架构介绍

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

3.1.2****快速入门

**3.1.3日志级别设置---**控制台输出

**3.1.4日志级别设置---**文件输出

加多一个处理器

3.1.5 Logger****对象父子关系

logger通过命名的方式确定父子级别,当父对象开启日志级别和处理器输出时,子对象也会继承父对象的设置。

3.1.6 JUL****配置入门

可以通过 LoggerMananger 中, logger 对象是通过日志配置进行生成的


handlers 可以支持多个处理器,按,分开, pattern 是文件输出处理器的文件输出路径

3.1.7 JUL****配置详解

  1. 设置消息的编码和消息的格式


    xmlFormatter 是有 xml 标签的, simpleFormatter 是以下的简单格式



    3.1.7 JUL 执行原理和流程
  2. 初始化 LogMananger
  • LogMananger加载logging.properties配置
  • 添加Logger到LogManager
  1. 从单例 LogManager 获取 Logger
  2. 设置级别 Level ,并指定日志记录 LogRecord
  3. Filter 提供了日志级别之外更细粒度的控制
  4. Handler 是用来处理日志输出位置
  5. Formatter 是用来格式化 LogRecord

4. Log4j****学习

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

4.1 Log4j****入门

  1. 创建 maven 工程
  2. 导入 maven 依赖
  3. demo


  4. 日志级别

    log4j 的默认级别是 debug

4.2 Log4j****的组件和配置文件

Log4j 主要 Loggers( 日志记录器 ) 、 Appenders( 输出端 ) 和 Layout( 日志格式化器 ) 组成。其中 Loggers 控制日志的输出级别与日志是否输出 ; Appenders 指定日志的 输出方式 ( 输出到控制台、文件等 ) ; Layout 制日志信息的输出格式

4.2.1 Loggers

日志记录器,负责收集处理日志记录,实例的命名就是类 "XX" 的 full quailed name( 类的全限定名 ) ,Logger的名字大小写敏感,其命名有继承机制,例如: name 为 org.apache.commons 的 logger 会继承name为 org.apache 的 logger 。
Log4j 中有一个特殊的 Logger 叫做 "root" ,他是所有 logger 的跟,也就意味着其他所有的 logger 都会直接或者间接地继承root , root logger 可以用 logger.getRootLogger() 方法获取。
但是,从 1.2 版本后 Logger 类已经取代了 Category 类,对于熟悉早期版本的人来说, logger==category


Log4j 的配置信息

4.3 Log4j****的内置日志记录

4.4 Log4jlayout****配置


PatternLayout 输出很强大,默认是只输出内容,使用 conversionPattern 可设置输出的格式

案例:

4.5 Log4jFileAppender****配置


按文件大小拆分

按时间将文件进行拆分

4.6 Log4jJDBCAppender****配置

4.7 Log4j的自定义logger

上面用的是 new logger( 类名 .class)

5. JCL****学习

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

5.1 JCL****入门

  1. 建立 maven 工程

  2. 添加依赖

  3. 入门代码

  4. 导入 log4j 的依赖查看区别

  5. 将 log4j.properties 配置信息加上

我们为什么使用日志门面?

  1. 面向接口开发,不再依赖具体的实现类,减少代码的耦合
  2. 项目通过导入不同的日志实现类,可以灵活切换日志框架
  3. 统一 API ,方便开发者学习和使用
  4. 统一配置便于项目日志的管理

5.2 JCL****原理


由于它的优先级无法动态修改,和 log4j 搭配很完美,但目前已经被淘汰了。

日志技术 下

**0.**学习目标

  1. 日志门面和日志体系
  2. SLF4J
  3. logback的使用
  4. log4j2的使用
  5. SpringBoote中的日志使用

**1.**日志门面

当我们的系统变得更加复杂的时候,我们的日志就容易发生混乱,随着系统开发的进行,可能会更新不同的日志框架,造成当前系统中存在不同的日志依赖,让我们难以统一的管理和控制,就算我们强制要求所有的模块使用相同的日志框架,系统中也难免使用类型spring 、 mybatis 等其他第三方框架,他们依赖于我们规定不同的日志框架,而且他们自身的日志系统就有不一致性,依然会出现日志框架的混乱。
所以我们需要借鉴 JDBC 的思想,为日志系统也提供一套门面,那么我们就可以面向这些接口规范开发,避免直接依赖具体的日志框架,这样我们的系统在日志中,就存在了日志的门面和日志的实现。
常见的日志门面:
JCL 、 slf4j
常见的日志实现:
JUL 、 log4j 、 logback 、 log4j2
日志门面和日志实现的关系:

日志框架出现的历史顺序:
log4j--JUL--JCL--slf4j--logback--log4j2

2. SLF4J****的使用

简单日志门面 SLF4J 主要是为了给 java 日志访问提供一套标准,规范的 API 框架,其主要意义在于提供接口,具体恶的实现可以交由其他日志框架,例如log4j ,当然 SLF4j 自己也提供了功能较为简单的实现,但是一般很少用到,对于一般的java 项目而言,日志框架会选择 slf4j-api 作为门面,配上具体实现框架,中间使用桥接器完成桥接。

2.1 SLF4J****入门

  1. 添加依赖

  2. 入门案例

2.2****绑定日志的实现

SLf4j 支持各种日志框架, SLF4j 发行版附带了几天称为 "SLF4J 绑定 " 的 jar 文件,每个绑定对应的受支持的框架。
使用 SLF4J 的日子绑定流程:

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

    通过 maven 引入常见的日志实现框架:

logback**:**


由于 slf4j-simple 未注释, slf4j 按照 maven 引入包的优先级优先使用 slf4j-simple 日志框架

下面是将 simple 框架注释打印的情况:

关闭日志开关:

log4j**:**

导入配置文件并 build :

jul**:**

由于 jul 是 java 内置的日志框架,所以只导入适配器即可

2.3 slf4j****的绑定日志原理

https://www.bilibili.com/video/BV1iJ411H74S/?p=24&spm_id_from=pageDriver&vd_source=e2627ba82e0c316aee9666dee0ca0d5f

2.4桥接旧的日志框架(Bridging)

通常,您依赖的某些组件依赖于 SLF4J 以外的日志记录 API 。您也可以假设这些组件在不久的将来不会切换到SLF4J 。为了解决这种情况, SLF4J 附带了几个桥接模块,这些模块将对 log4j , jcl 和 java.util.logging api的调用重定向,就好像他们是对 slf4j api 一样。
桥接解决的是项目中日志的遗留问题,当系统中存在之前的日志 API ,可以通过桥接转换到 slf4j 的实现

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

案例:

注释 Log4j 的依赖,升级成 slf4j 和 logback 的日志框架,还有 slf4j-api 依赖

注意问题:

  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等对象,将无法产生效果。

3. Logback****的使用

Logback 是由 log4j 创始人设计的另一个开源日志组件,性能比 log3j 要好
Logback 主要分为三个模块:

  • logback-core:其他两个模块的基础模块
  • logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j api
  • logback-access:访问模块与Servlet容器集成提供通过http来访问日志的功能

后续的日子代码都是通过 slf4j 日志门面搭建日志系统,所以在代码是没有区别,主要是通过修改配置文件和pom.xml 依赖

3.1 logback****入门

  1. 导入 maven 依赖

  2. demo

3.2 logback****配置

logback 会一次读取一下类型配置文件:

  • logback.groovy
  • logback-test.xml
  • logback.xml 如果均不存在会采用默认配置
  1. logback 组件之间的关系
  • Logger:日志的记录器,把它关联到应用的对应context上后,主要用于存放日志对象,也可 以定义日志类型、级别
  • Appender:用于指定日志输出目的地,目的地可以是控制台、文件、数据库等等。
  • Layout:负责把事件转换成字符串,格式化的日志信息的输出,在logback中Layout对象被封装在encoder中。
  1. 基本配置信息

3.3****日志拆分

3.4 logback的过滤器和异步日志和自定义logger


onMatch: 大于等于该 level , accept 表示通过
onMissMatch :小于该 level , deny 表示拦截

异步日志:需要记录日志的线程和记录日志的线程不是同一个线程

3.5 logbackaccess****模块

logback-access 模块与 Servlet 容器 ( 如 Tomcat 和 jetty) 集成,以提供 http 访问日志功能。我们可以使用 logback-access模块来替换 tomcat 的访问日志

  1. 将 logback-access.jar 与 logback-core.jar 复制到 $TOMCAT_HOME/lib/ 目录下

  2. 修改 $TOMCAT_HOME/conf/server.xml 中的 host 元素中添加:

  3. logback 默认会在 $TOMCAT_HOME/conf 下查找文件 logback-access.xml

4. log4j2****的使用

Apache log4j2 是对 log4j 的升级版,参考了 logback 的一些优秀的设计,并且修复了一些问题,因此带来了一些重大的提升,主要有:

  • 异常处理,在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制。
  • 性能提升,log4j2相较于log4j和logback都具有很明显的性能提升,后面有官方测试的数据。
  • 自动重载配置,参考了logback的设计,当然会提供自动刷新参数配置,最实用的就是我们在生产上可以动态的修改日志的级别而不需要重启应用。
  • 无垃圾机制,log4j2在大部分情况下,都可以使用其设计的一套无垃圾机制,避免频繁的日志收集导致的jvm gc

4.1 log4j2****的入门

目前市面上最主流的日志门面就是 SLF4j ,虽然 log4j2 也是日志门面,因为它的日志实现功能非常强大,性能优越看,所以大家一般还是将log4j2 看作日志的实现, slf4j+log4j2 应该是未来的大势所趋。

  1. 添加依赖

  2. demo


3. slf4j (上面的 maven 包不要注释)

4.2 log4j2****配置

log4j2 默认加载 classpath 下的 log4j2.xml 文件中的配置

4.3 log4j****的异步日志

log4j 的性能之所以高,和它的异步日志脱不了干系
log4j 最大的特点就是异步日志,其性能的提升主要也是从异步日志中收益。

  • 同步日志
  • 异步日志
  1. asyncAppender 方式

  2. AsyncLogger 方式
    AsyncLogger才是 log4j 的重头戏,也是官方推荐的异步方式。它可以是的调用 Logger.log 返
    回的更快。你可以有两种选择:全局异步和混合异步

  • 全局异步就是,所有日志都异步的记录,在配置文件上不用做任何改动,只需要添加一个log4j2.component.properties配置:
  • 混合异步就是,你可以在应用中同时使用同步日志和异步日志,这是的日志的配置方式更加灵活
  1. 使用异步日志需要注意的问题:
  • 如果使用异步日志,AsyncAppender、AsyncLogger和全局日志,不要同时出现。性能会和AsyncAppender一致,降至最低
  • 设置includerLocation=false,打印位置信息急剧降低异步日志的性能,比同步日志还要慢。

4.4 log4j2****的无垃圾机制

5. Springbboot****的日志使用

springboot 框架在企业中的使用越来越普遍, springboot 日志也是开发中常用的日志系统, springboot默认是使用slf4j 作为日志门面, logback 作为日志实现来记录日志。

5.1 springboot****的日志设计

maven 依赖:

其中 spring-boot-starter-web 就包含了 springboot 的日志系统

原理:

5.2 SpringBoot****的日志使用


两个日志记录是一模一样的,也就是说 springboot 的桥接器功能实现成功!
指定日志级别 类路径: resource 目录下


类路径: resource 目录下

相关推荐
thefool11226624 分钟前
随机链表的复制
java
jvmind_dev27 分钟前
SWT 堆外内存泄漏排查实录:一次 PNG 保存泄漏一张图,一行 g_free 治好
java·后端
CodeStats29 分钟前
《源纹天书》第三百四十六章至第三百五十章:边界的扩张、跨宇宙通信的尝试、其他宇宙的回应、新网络的形成、宇宙网络的创始者!
java·源纹天书
古法安卓2 小时前
Android-显示流程
android·java·android studio
l1t2 小时前
DeepSeek总结的DuckDB 如何更快地运行递归 CTE
java·开发语言·数据库·mysql·duckdb
小手cool2 小时前
使用递归对数组进行反转操作
java·数据结构·算法
MetaLite3 小时前
SpringBoot分页接口怎么设计-pageSize不设上限会发生什么
java·spring boot·后端
晚安code3 小时前
LangChain4j AiService 实战:会话记忆与结构化输出
java·langchain
晚安code3 小时前
LangChain4j 实战:RAG、工具调用、护轨与 SSE 流式输出
java·langchain