2024年java基础413讲解

java基础413讲解本篇文章中涉及到的所有代码都已经上传到 gitee 中 gitee com sss123a log java 日志系列全解 00 java 志之发展史 01 java 日志之原生的日志框架 jul 02 java 日志之 log4j 入门及 xml 配置详解 03 java 日志之 log4j 的基础组件和各种 Appender 04 java 日志之 jcl 门面 05

大家好,我是讯享网,很高兴认识大家。



本篇文章中涉及到的所有代码都已经上传到gitee中: gitee.com/sss123a/log…

java日志系列全解

# 00.java⽇志之发展史

# 01.java日志之原生的日志框架jul

# 02.java日志之log4j入门及xml配置详解

# 03.java日志之log4j的基础组件和各种Appender

# 04.java日志之jcl门面

# 05.java日志之slf4j门面

# 06.java日志之logback源码和xml解析

# 07.java日志之logback内部状态数据Status

# 08.java日志之logabck各环境配置

# 09.java日志之logback的appender标签及其子标签全解析

Log4j官方源码和文档链接:logging.apache.org/log4j

日志框架发展史:

下一篇

# log4j的基础组件和各种Appender

Hello world!

引入maven依赖:

 
讯享网 

第一个log4j程序:

讯享网

输出结果如下: image.png 这里红色提示其实是log4j内部使用LogLog工具类打印的,我们可以调用LogLog.setQuietMode(true); 来禁用log4j内部一切日志输出。具体可以参考LogLog类中的静态代码块支持更强大的功能配置。

那至于为什么log4j要输出这样的提示信息,那是因为还缺少对Logger的进一步配置。 比如我们可以调用BasicConfigurator.configure(); 。其本质是为该logger对象增加了一个ConsoleAppender,它负责将日志输出到console。原理就等同于jul中的java.util.logging.ConsoleHandler类。具体代入如下:

 

另外,log4j默认支持xml格式和properties格式的配置文件,对应log4j中的两个工具类:

  • DOMConfigurator:解析xml文件
  • PropertyConfigurator 解析properties文件

接下来我们以xml配置文件为例来配置我们的log4j:

1.如果xml文件在在resources目录下,且文件名为log4j.xml,那么log4j可以自动读取该文件,具体可以参考org.apache.log4j.LogManager的静态代码块

2.如果xml文件在resources目录下:

讯享网

3.如果xml文件在磁盘上任意位置:

 

4.也可以把xml文件放到一个指定的位置,并且使用环境变量log4j.configuration来完成配置文件的指定。注意,在log4j.configuration的值中,可以使用文件名称或者url的方式。比如:
log4j.configuration=log4jconfig.properties (resources目录下) log4j.configuration=file:/c:/log4jconfig.xml

log4j.xml配置文件解析

 

该接口主要有两个核心实现类

  • DOMConfigurator:解析xml文件
  • PropertyConfigurator 解析properties文件

两者实现方式大同小异,我们以xml文件为例解剖log4j内部实现:

 

根节点:log4j:configuration

DOMConfigurator#parse(Element)

用法如下:

 

重点: 可以通过${}从系统属性中获取,也可以固定写死

类型描述默认值log4j:configuration根标签同configurationdebug属性是否打印log4j内部debug日志,同configDebug,LogLog.setInternalDebugging(boolean);falsereset属性如果为true则调用LoggerRepository.resetConfiguration();threshold属性默认的日志level,LoggerRepository.setThreshold();Level.ALL

loggerFactory同categoryFactory:自定义LoggerFactory

如果配置了该标签,那么该xml文件中所有logger都会通过该loggerFactory去生成,不走默认的了

DOMConfigurator#parseCategoryFactory(Element)

可以同时存在多个,但是最后一个才生效

 
类型描述loggerFactory标签用户可以自定义LoggerFactory,同categoryFactory标签class属性LoggerFactory具体实现类,如果没有设置class属性,则直接跳过该标签param标签通过反射将value设置给class类中的属性param.name属性class类中的属性名称param.value属性class类中的属性值

class属性:可以通过${}从系统属性中获取,比如

System.setProperty("matio.log4j.loggerFactory.class", "com.matio.log4j.loggerfactory.CusLoggerFactory");

也可以固定写死,比如class="com.matio.log4j.loggerfactory.CusLoggerFactory"

备注:如果class实现类实现了UnrecognizedElementHandler接口,那么我们还可以解析自定义xml标签,示例代码:

 

logger同category

定义一个logger对象

DOMConfigurator#parseCategory(Element)

可以同时存在多个logger标签

 
类型描述logger标签创建一个logger对象,同category标签class属性通过该类名反射调用其内部的getLogger()方法去生成logger对象name属性该logger的nameadditivity属性是否遵循缺省的继承机制,默认trueappender-ref标签appender的name,这个时候才开始去解析目标appender标签level标签该logger的日志level,可以通过class属性自定义levelpriority标签同levelparam标签通过反射将value设置给class类中的属性param.name属性class类中的属性名称param.value属性class类中的属性值

在每个logger标签被解析完成后,如果发现该logger类实现了org.apache.log4j.spi.OptionHandler接口,就会回调其activateOptions()方法

java基础413讲解

root

只能存在一个root标签

 
类型描述appender-ref标签appender的name,这个时候才开始去解析目标appender标签level标签该logger的日志level,可以通过class属性自定义levelpriority标签同levelparam标签通过反射将value设置给class类中的属性param.name属性class类中的属性名称param.value属性class类中的属性值

在root标签被解析完成后,如果发现该logger类实现了org.apache.log4j.spi.OptionHandler接口,就会回调其activateOptions()方法

renderer

不知道大家有没有注意到logger.info();方法接收的参数类型是什么.其实都是Object类型(jul接受的都是string类型),这说明log4j可以打印任意类型的日志,比如:

 

以上两行代码打印结果如下:

 

我们都知道输出一个对象其实就是输出其string()方法,但是log4j提供了一个工具来用户根据指定的日志对象类型输出对应的日志,这个工具就是org.apache.log4j.or。ObjectRenderer,其接口定义是如下:

 

参数o就是我们上面的User对象和Test1对象,返回值就是最终要打印的日志结果

这里为了更好的理解什么是ObjectRenderer,附带了一个DEMO,它不需要xml配置文件,示例如下:

 

自定义ObjectRenderer,用于处理User类型和Test1类型的消息:

 

其打印结果如下:

 

那么在xml文件中我们该如何配置renderer呢,具体可以参考:

DOMConfigurator#parseRenderer(Element);

renderer在xml中的配置如下,支持多个:

 
类型描述renderer标签真的指定类型的日志,就调用CusObjectRenderer.doRender()二次处理生成新的日志renderingClass属性ObjectRenderer的实现类renderedClass属性日志类型

throwableRenderer

什么是throwableRenderer?

它可以将Throwable转成String,对应log4j中的接口定义如下:

 

log4j默认使用DefaultThrowableRenderer

没有注册自定义ThrowableRenderer之前,实例代码如下:

 

输出结果如下:

 

当注册一个自定义的ThrowableRenderer后代码如下:

 
 

输出结果如下:

 

那么在xml中如何声明throwableRenderer呢,具体参考

DOMConfigurator#parseThrowableRenderer(Element);

 
类型描述throwableRenderer标签自定义ThrowableRendererclass属性ThrowableRendere的实现类param标签通过反射将value设置给class类中的属性param.name属性class类中的属性名称param.value属性class类中的属性值

在throwableRenderer标签被解析完成后,如果发现该throwableRenderer类实现了org.apache.log4j.spi.OptionHandler接口,就会回调其activateOptions()方法

appender

每一个handler标签都会被实例化成一个Appender对象(它其实就等同于jul中的Handler),负责将日志输出到console上、保存到文件中,保存到数据库中、或者通过socket发送给远端等

image.png

DOMConfigurator#parseAppender(Element);

 
类型描述appender标签对应jul中的handler对象class属性Appender实现类name属性该appender的nameparam标签通过反射将value设置给class类中的属性param.name属性class类中的属性名称param.value属性class类中的属性值layout标签定义该appender的日志输出样式,见parseLayout()filter标签定义该appender的日志过滤器,见parseFilters()errorHandler标签输出日志时如果出现异常就交给该handler处理,见parseErrorHandler()appender-ref标签只有该appender实现了AppenderAttachable接口才有效,就是代表真正的appender,可以有多个

在每个appender标签被解析完成后,如果发现该appender类实现了org.apache.log4j.spi.OptionHandler接口,就会回调其activateOptions()方法

最后再添加到对应的logger中

下一篇

小讯
上一篇 2025-01-02 14:17
下一篇 2025-01-02 07:29

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/10122.html