全网最全、最细致的Java日志框架以及门面技术(一)。

简介: 对于一个应用程序来说日志记录是必不可少的一部分。线上问题追踪,基于日志的业务逻辑统计分析等都离不日志。java领域存在多种日志框架,目前常用的日志框架包括Log4j 1,Log4j 2,Commons Logging,Slf4j,Logback,Jul。

Java日志框架


1. Java日志介绍


  • Java日志框架内中的xml配置文件中的标签是固定的,不可以自定义
  • 配置文件基本结构:
    以标签开头,
    包含0或多个子标签,
    包含0或多个标签,
    最多只能有一个标签。

微信截图_20220609163050.png

以下是SLF4J门面技术。

微信截图_20220609163122.png

这个是SLF4J门面技术这个深绿色的代表网络适配器。

  • 日志文件是用于记录系统操作事件的文件集合。
  • 日志文件他具有处理历史数据、诊断问题的追踪以及理解系统的活动等重要作用。
  • 日志主要分为两种:调试日志与系统日志(工作中大部分使用)
// 使用反射机制的这个类只要是该项目的 src下的类都可以。
Logger logger = LogManager.getLogger(入门案例.class);
复制代码


1.1 调试日志


  • 我们平时使用的debug功能只能暂时查看运行信息,而不能长期的保存这些运行信息。而调试日志可以更加方便的“重新”这些问题,即可以保存这些运行信息。


1.2 系统日志


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


2.日志框架


2.1 日志框架的作用


  • 控制日志输出的内容和格式。
  • 控制日志输出的位置。
  • 日志文件相关的优化,如异步操作、归档、压缩。
  • 日志系统的维护。
  • 面向接口开发——日志的门面。


2.2 日志框架的价值


  • 我们可以直接使用别人写好的日志框架,提高开发效率。


2.3 市面流行的日志框架


  • JUL:java util logging  Java原生日志框架。
  • Log4j:Apache的一个开源项目。
  • Logbcak :由Log4j之父做的另一个开源项目,业界中称为 log4j 后浪。他是一个可靠、通用且灵活的Java日志框架。
  • Log4j2 :Log4j的第二个版本,各个方面与Logback及其相似。具有插件式结构、配置文件优化等特征,在Spring Boot1.4版本之后就不在支持 log4j ,所以出现了第二个版本的。
  • JCL
  • SLF4j


2.4 日志门面和日志框架的区别


  • 日志框架技术 :JUL、Log4j、Logbcak、Log4j2
  • 日志门面技术 :JCL、SLF4j

为什么要使用日志门面技术:

  • 每一种日志框架都有自己单独的API,要使用对应的框架就要使用对应的API,这就大大的增加了应用程序代码对于日志框架的耦合性。使用日志门面技术之后,不论底层是什么日志框架,我们拿到代码之后可以使用自己习惯的日志框架就行解读,不用修改一行代码。

微信截图_20220609163251.png

  • 其实框架1调用的是自己的方法a() ,框架2调用的自己的方法b() ,此时将这两个方法抽取出来称为方法c();


3. JUL


3.1 JUL 简介


  • JUL全程 Java Util Logging,它是java原生的日志框架,使用时不需要另外引入第三方的类库,相对于其他的框架使用方便,学习简单,主要使用在小型应用中。


3.2 JUL 组件介绍

微信截图_20220609163340.png

微信截图_20220609163430.png

3.3 日志的级别(Level)

微信截图_20220609163456.png微信截图_20220609163508.png微信截图_20220609163517.png

  • 注意:其中包含这个800,也就是info
  • info是默认的打印信息级别。
Logger logger = Logger.getLogger("com.yunbocheng.JUL.JULTest.test01");
logger.severe("severe信息");
logger.warning("warining信息");
logger.info("info信息");
logger.config("config信息");
logger.fine("fine信息");
logger.finer("finer信息");
logger.finest("finest信息");
复制代码

此时打印的结果是 :只有info级别以及比info级别高的日志信息

微信截图_20220609163603.png

3.4 入门案例


  • 见项目 “入门以及默认级别展示” 。


3.5 自定义日志级别


  • 见项目 “自定义日志级别 ”

总结 :

  • 用户使用Logger来进行日志的记录,Logger可以同时持有多个处理器Handler。(同时在控制台和自定义位置进行日志信息的输出)
  • 日志的记录使用的是Logger,日志的输出使用的是Handler。
  • 添加了哪些handler对象,就相当于需要根据所添加的handler将日志信息输出到指定的位置上,例如:控制台、指定位置文件.....


3.6 JUL Logger中的父子关系。


  • 见项目”JUL中的父子关系“


3.7 JUL配置文件解析


  • 见项目”JUL配置文件“
以上所有的配置相关的操作,都是一Java硬编码的形式进行的。
我们可以使用更加清晰,更加专业的一种做法,就是配置文件。
如果我们没有自己添加这个配置文件,则会使用系统默认的配置文件。
这个配置文件:
 java.home --> 找到jre文件夹 --> lib --> logging.properties
复制代码

配置文件中的#代表的注释,可以删除掉。

微信截图_20220609163737.png

3.8 自定义配置文件


  • 我们将配置文件修改为自定义的输出级别
    微信截图_20220609163825.png
  • 如果想要获取到这个自定义的配置文件,此时一定需要一个输入流来读取这个文件。项目见”JUL配置文件“


3.9 日志信息的追加


  • 只需要在日志配置文件中加入 :java.util.logging.FileHandler.append = true


3.10 JUL日志框架使用方式总结(原理解析)

微信截图_20220609163902.png

4. Log4j


4.1 Log4j简介


  • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、CUI组件,甚至可以是套接口服务器、NT的事件记录器。只要是我们需要的地方,一般都可以输出日志信息。
  • 我们可以控制每一条日志信息输出的格式。
  • 通过定义每一条日志信息的级别,我们能够更加细致的控制日志的生成过程。
  • 这些设置可以通过一个配置文件来灵活的进行配置,而不需要修改应用的代码。
  • Log4j --> Log for java
  • 我们使用log4j技术,主要使用的是其配置文件,我们也可以使用硬代码的格式在Java中来写这个日志配置信息。
  • 从时间上讲,log4j的产生时间要比JUL早。


4.2 Log4j组件

微信截图_20220609164002.png微信截图_20220609164012.png微信截图_20220609164024.png微信截图_20220609164036.png

微信截图_20220609164138.png

4.3 日志输出格式说明

微信截图_20220609164241.png

4.4 Log4j的级别

微信截图_20220609164251.png

  • 其中 debug 是我们在没有进行设置的情况下,默认的日志输出级别。


4.5 配置文件


  • 将项目中的项目”配置文件“

微信截图_20220609164333.png

4.6 使用默认配置文件打印日志


  • 代码在项目“配置文件”中
  • 注意:这个日志配置文件必须在main-->rescoures文件下,且名字必须是log4j.properties文件。此时log4j日志文件会自动加载这个配置文件。
  • 注意:在properties配置文件中,每一条命令后不要加分号,否则会报错。
# 以下是配置文件的代码信息
# 这行代码代表让这个日志执行指定的配置信息
# 这个trace代表的是输出级别,这个console是我们自定义的一个名称(见名思意)appenderName
# 这个可以设置打印到多个地方,中间用逗号隔开。
# 这个Logger是继承的根节点rootLogger。
log4j.rootLogger = trace,console
#配置appender输出方法
log4j.appender.console = org.apache.log4j.ConsoleAppender
#配置输出信息的格式
log4j.appender.console.layout = org.apache.log4j.SimpleLayout
复制代码
  • 以上使用的是默认的日志信息打印格式。(SimpleLayout)
// 以下是输出日志信息的代码
public void test01(){
    Logger logger = Logger.getLogger(配置文件.class);
    // 打印输出信息
    logger.fatal("fatal信息");
    logger.error("error信息");
    logger.warn("warn信息");
    logger.info("info信息");
    logger.debug("debug信息");
    logger.trace("trace信息");
}
复制代码


4.7 自定义配置打印日志信息格式


  • 代码在项目“配置文件”中
#这行代码的代表打印到控制台
log4j.rootLogger = trace,console
#配置appender输出位置
log4j.appender.console = org.apache.log4j.ConsoleAppender
#配置输出信息的格式
log4j.appender.console.layout = org.apache.log4j.PatternLayout
#这行是设置自定义的日志信息打印格式
log4j.appender.console.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS}
复制代码
  • 这个是使用的自定义日志信息打印格式 PatternLayout,这个时候只需要在默认的配置文件中加入一行指定打印日志信息格式的代码即可。


4.8 将日志输出到指定文件中的配置


  • 源代码见项目“日志信息输出到文件”
#这行代码的代表打印到控制台
log4j.rootLogger = trace,file
#配置appender输出位置
log4j.appender.file = org.apache.log4j.ConsoleAppender
#配置输出信息的格式
log4j.appender.console.file = org.apache.log4j.PatternLayout
#这行是设置自定义的日志信息打印格式
log4j.appender.file.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n
#第一个file是我们自己命名的appenderName,第二个file是用来指定文件的位置。
log4j.appender.file.file = E://log4j.log
#设置输出日志的编码格式(输出中文的日志信息)
log4j.appender.file.encoding = UTF-8
复制代码
  • 此时这个日志信息会输出到这个指定位置的文件中。


4.9 将日志信息输出到多个位置


  • 源代码见项目“日志信息输出到文件”
  • 同时输入到控制台和指定文件中
# 需要将以上输出到控制台和文件的代码都要写上
# 最主要的是修改打印到的位置代码,这是代表可以在 appenderName 为这个两个的地方输出
# 这个 file,console是我们自定义的名称,(见名思意原则就是代表控制台和文件)
log4j.rootLogger = trace,file,console
复制代码


4.10 根据文件大小拆分配置文件(RollingFileAppender)


  • 源代码见项目“日志信息输出到文件”
log4j.rootLogger = trace,rollingFile,console
# RollingFileAppender的配置,我们可以针对实际含义起名
log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n
log4j.appender.rollingFile.file = E://log4j.log
log4j.appender.rollingFile.encoding = UTF-8
# 指定日志文件的大小
log4j.appender.rollingFiler.maxFileSize = 1MB
# 指定日志文件的数量
log4j.appender.rollingFiler.maxBackupIndex = 5
复制代码

微信截图_20220609164515.png

  • 这个时候日志6会覆盖掉日志1。以下就是生成的5个文件。这5个文件会以序号进行排列。

微信截图_20220609164533.png

4.11 根据时间来拆分日志文件(DailyRollingFileAppender)


  • 源代码见项目“日志信息输出到文件”
  • 这个会根据你输入的时间间隔来生成新的日志信息,这个时间可以是一天,也可以是一秒,需要注意的是这个并不是自动为我们生成新的日志文件,是我们手动生成的日志文件,比如:你设置的间隔是 yyyy-MM-dd ,这个时候如果你现在输出了一个日志文件,那么在这个时间开始的后24个小时内都不会生成新的日志文件,在这24小时内输出的日志文件都会存储到这个一个旧的日志文件中。即使过了24个小时,系统也不会为我们自动生成一个新的日志文件,需要程序员自己生成一个新的日志文件,加可以精确到秒,那么一秒就会为我们生成一个新的日志文件。
# DailyRollingFileAppender的配置,我们可以针对实际含义起名
log4j.appender.dailyRollingFile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyRollingFile.layout = org.apache.log4j.PatternLayout
log4j.appender.dailyRollingFile.layout.conversionPattern = [%p]%r %c%t%d{yyyy-mm-dd HH:mm:ss:SSS} %m%n
log4j.appender.dailyRollingFile.file = E://log4j.log
log4j.appender.dailyRollingFile.encoding = UTF-8
#不要忘记前边的那个点
appender.dailyRollingFile.datePattern = '.'yyyy-MM-dd HH:mm:ss
复制代码
  • 在这个类中没有提供覆盖的方法。

微信截图_20220609164617.png

4.12 日志持久化(将日志信息存储到数据库)


  • 项目源码见 “日志持久化_将数据存储到数据库”
  • 第一步 :需要在Maven中添加mysql依赖。
  • 第二步 :在配置文件中配置连接数据库的信息并且设置插入语句。
    注意:这个插入语句必须在一行上。
# 持久化日志信息 将日志信息存储到数据库
log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout = org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
log4j.appender.logDB.URL = jdbc:mysql://localhost/log
log4j.appender.logDB.User = root
log4j.appender.logDB.Password = 567cybtfboys
# 此时要像数据库中插入数据,使用insert语句
log4j.appender.logDB.Sql =  INSERT INTO tab_log(id,name,create,level,category,fileName,message) values('project_log','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%m')
复制代码
  • 第三步 :在主方法中输出日志信息
Logger logger = Logger.getLogger(日志持久化_将数据存储到数据库.class);
// 输出日志信息
logger.fatal("fatal信息");
logger.error("error信息");
logger.warn("warn信息");
logger.info("info信息");
logger.debug("debug信息");
logger.trace("trace信息");
复制代码


4.13 自定义Logger的配置


  • 见项目 “自定义Logger配置”
  • 第一步 :配置自定义logger
# 使用最高父类rootLogger配置logger,这个时候继承的是父logger(根节点)
log4j.rootLogger = trace,console
# 配置自定义logger,此时使用的是自定义的父logger (自定义)
log4j.logger.com.yunbocheng = info,file
复制代码
  • 输出结果
从输出的位置来看,控制台输出了信息,日志文件也会输出信息。所以可以得出结论,如果根节点的logger和自定义父logger配置的输出位置是不同的则取二者的并集,也就是配置的位置都会进行日志的输出。
如果二者配置的日志级别不同,主要以按照我们自定义的父logger的级别输出为主。
复制代码

5.JCL (日志门面技术)


5.1 JCL简介


  • JCL是Apache提供的一个通用日志API

微信截图_20220609164826.png微信截图_20220609164837.png

LoggerFactory  // 这个叫日志工厂
复制代码


5.2 入门案例以及JCL是如选择日志框架的


  • 详细信息见 “入门案例”



相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
9月前
|
监控 Cloud Native Java
Quarkus 云原生Java框架技术详解与实践指南
本文档全面介绍 Quarkus 框架的核心概念、架构特性和实践应用。作为新一代的云原生 Java 框架,Quarkus 旨在为 OpenJDK HotSpot 和 GraalVM 量身定制,显著提升 Java 在容器化环境中的运行效率。本文将深入探讨其响应式编程模型、原生编译能力、扩展机制以及与微服务架构的深度集成,帮助开发者构建高效、轻量的云原生应用。
973 44
|
9月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
804 1
|
10月前
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
325 4
|
9月前
|
人工智能 Java 开发者
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
JManus是阿里开源的Java版OpenManus,基于Spring AI Alibaba框架,助力Java开发者便捷应用AI技术。支持多Agent框架、网页配置、MCP协议及PLAN-ACT模式,可集成多模型,适配阿里云百炼平台与本地ollama。提供Docker与源码部署方式,具备无限上下文处理能力,适用于复杂AI场景。当前仍在完善模型配置等功能,欢迎参与开源共建。
3247 58
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
|
8月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
8月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
725 8
|
8月前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
225 7
|
8月前
|
存储 安全 Java
《数据之美》:Java集合框架全景解析
Java集合框架是数据管理的核心工具,涵盖List、Set、Map等体系,提供丰富接口与实现类,支持高效的数据操作与算法处理。
|
10月前
|
存储 缓存 安全
Java集合框架(二):Set接口与哈希表原理
本文深入解析Java中Set集合的工作原理及其实现机制,涵盖HashSet、LinkedHashSet和TreeSet三大实现类。从Set接口的特性出发,对比List理解去重机制,并详解哈希表原理、hashCode与equals方法的作用。进一步剖析HashSet的底层HashMap实现、LinkedHashSet的双向链表维护顺序特性,以及TreeSet基于红黑树的排序功能。文章还包含性能对比、自定义对象去重、集合运算实战和线程安全方案,帮助读者全面掌握Set的应用与选择策略。
1199 23
|
9月前
|
SQL Java 数据库连接
区分iBatis与MyBatis:两个Java数据库框架的比较
总结起来:虽然从技术角度看,iBATIS已经停止更新但仍然可用;然而考虑到长期项目健康度及未来可能需求变化情况下MYBATISS无疑会是一个更佳选择因其具备良好生命周期管理机制同时也因为社区力量背书确保问题修复新特征添加速度快捷有效.
810 12