springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结

springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结_第1张图片

摘要背景

自己公司项目使用了日志配置文件log4j2.xml,但是由于项目较大,导致生成的日志文件及目录较多,在导致自己定位bug的是否照不清楚哪个类或者哪个输出文件在哪个路径下,所以特意写个demo测试使用日志配置文件log4j2.xml,并把自己的总结写进去。

Readme.md

市面上常见的日志框架有很多,比如:JCL、SLF4J、Jboss-logging、jUL、log4j、log4j2、logback等等,我们该如何选择呢?

市面上的日志框架;
JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j…
# 一.Java常用的日志框架介绍
## 日志的抽象层:JCL(Jakarta Commons LoggingSLF4jSimple Logging Facade for Java) jboss-logging
- JCL:(Jakarta Commons Logging):就是Apach的commons-logging.jar
- SLF4J:(Simple Logging Facade for Java)有调侃的人取了个好听的别名(酸辣粉4斤),超级强大的一款日志框架
## 日志实现:  Log4j JUL(java.util.logging) Log4j2 Logback
- JUL:(Java util logging )是位于java.util.logging包下面的一款日志框架,属于JDK自带的日志实现
- Log4j:现在是Apache基金会下面的一个开源项目
- logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现(springboot默认使用logback作为日志记录框架)
- Log4j2Log4j是log4j 1.x和logback的改进版


左边选一个抽象层、右边来选一个实现;类似与我们经常使用的JDBC一样,选择不同的数据库驱动。
- 下面我们先看看日志的抽象层:JCL大家应该很熟悉,Commons Logging,spring中常用的框架最后一次更新2014~~~;jboss-logging使用的场景太少了;就剩下SLF4j了也是我们springboot中使用的日志抽象层。
- 日志实现:大家应该看着都很熟悉把Log4j大家应该用的挺多的,LogbackLog4j的升级版本出至于同一个人开发的,考虑到以后的升级使用等问题,又写出了SLF4j的日志抽象层使用起来更加灵活。JUL(java.util.logging)一看就知道是java util包下的;Log4j2 咋一看像是Log4j的升级版本,其实并不是,它是apache下生产的日志框架。
SpringBoot选用 SLF4j和logback

一、springboot项目使用log4j2.xml

1)项目目录结构

springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结_第2张图片

2)pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-test</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>log-output-test</artifactId>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.starter.web.version}</version>
            <!--想要用log4j2,就要先排除springboot默认的logback-->
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
            <version>${spring.boot.starter.log4j2.version}</version>
        </dependency>
    </dependencies>
</project>

3)配置文件

springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结_第3张图片

二、log4j2.xml详情介绍使用说明

<?xml version="1.0" encoding="utf-8"?>

<!--
	关于日志level共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF
	Configuration配置节是log4j2.xml文件的根节点。该配置节有两个常用属性:status和monitorinterval。其中,
	status:用来打印到控制台的内部 Log4j 日志事件的级别,设置该属性是查找 Log4j 故障的第一手工具。用来看到Log4j2启动和加载配置文件时的打印信息
	monitorinterval:用于指定检查配置文件是否有更新的间隔秒数,单位是s,默认值是5s。另外,Configuration配置节有两个子节点:AppendersLoggers-->
<configuration status="debug" MonitorInterval="120" >
	<!--
			属性(可选),用来定义常量,之后在其他配置项中通过${变量名}引用。
			注意:linux与 windows 注意/ 与 \ 的区别,linux改为/
			%d{yyyy.MM.dd HH:mm:ss.SSS}		表示输出到毫秒的时间
			%t			输出当前线程名称
			%level		日志级别
			%-5level 	输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
  			%M%method	输出所在方法名
  			%msg 		日志文本
  			%n 			换行
  			%x			输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中
			%thread		线程名字
			%l			位置信息,等同于%C.%M(%F:%L)
			%L 			输出行号
			%C%class	完整类名
			%F%file	文件名
			%c{1.}		logger名字,比如LoggerName=org.apache.commons.FooResult=o.a.c.Foo
		-->
	<properties>
		<Property name="log-path">log-output-test/logs/ems_main</Property>
		<Property name="log_pattern">%d{yyyy.MM.dd HH:mm:ss.SSS} [%t]%-5level %class{36}  %M %L - %msg %xEx %n</Property>
	</properties>

	<!--输出源,用于定义日志输出的地方,常见的有三种子节点:ConsoleRollingFileFile、控制台ConsoleAppender、滚动文件FileAppenderRollingRandomAccessFile-->
	<appenders>
		<!--
			这个输出控制台的配置
			name:指定Appender的名字.
			target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT。
			PatternLayout:输出格式,不设置默认为:%m%n。
			ThresholdFilter属性:onMatch表示匹配设定的日志级别后是DENY还是ACCEPT,onMismatch表示不匹配设定的日志级别是DENY还是ACCEPT还是NEUTRAL
		 -->
<!--		<Console name="Console" target="SYSTEM_OUT">-->
<!--			<ThresholdFilter level="info" onMatch="ACCEPT" />-->
<!--			<PatternLayout	pattern="${log_pattern}" />-->
<!--		</Console>-->

		<!-- 日志文件输出 -->
<!--		<File name="file" fileName="${log-path}/bg_logs/myFile-${date:yyyy-MM-dd}.log">-->
			<!-- 日志输出格式 -->
<!--			<PatternLayout pattern="${log_pattern}"/>-->
<!--		</File>-->

		<!--
			<RollingRandomAccessFile>节点用来定义超过指定大小自动删除旧的创建新的的Appender,按照一定的策略滚动文件,网上有使用2种标签<RollingFile> vs <RollingRandomAccessFile>,后者有缓冲区Buffer的概念,缓冲区满了后才会写入磁盘,所以可能看不到实时滚动更新的日志(但其性能更好)。要看到实时滚动更新的日志,则用RollingFIle
				name:指定Appender的名字。
				fileName:指定输出日志的目的文件带全路径的文件名。
				filePattern:当发生滚动时,文件的转移和重命名规则,指定新建日志文件的名称格式。
			<ThresholdFilter>决定日志事件能否被输出
				ACCEPT(接受)DENY(拒绝)NEUTRAL(中立)、onMatch(该级别及以上)表示匹配设定的日志级别后是DENY还是ACCEPT、onMismatch(该级别以下)表示不匹配设定的日志级别是DENY还是ACCEPT还是NEUTRAL
			<PatternLayout>日志输出格式,不设置默认为:%m%n。
			<Policies>指定滚动日志的策略,就是什么时候进行新建日志文件输出日志。
				TimeBasedTriggeringPolicyPolicies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am…而不是7am。
				SizeBasedTriggeringPolicyPolicies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小。
			<DefaultRolloverStrategy>默认滚动策略,用来指定同一个文件夹下最多有几个日志文件,默认为最多同一文件夹下7个文件,超出时开始删除最旧的,创建新的(通过max属性)-->
		<RollingFile name="Console" fileName="${log-path}/bg_logs/log-${date:yyyy-MM-dd}.log" filePattern="${log-path}/bg_logs/log/log-%d{yyyy-MM-dd-HH}.log-%i.gz">
			<PatternLayout	pattern="${log_pattern}" />
			<ThresholdFilter level="debug" onMatch="ACCEPT" />
			<Policies>
				<SizeBasedTriggeringPolicy size="30MB" />
				<TimeBasedTriggeringPolicy modulate="true"  interval="24" />
			</Policies>
			<DefaultRolloverStrategy max="50" />
		</RollingFile>
		<!-- user日志文件 -->
		<RollingFile name="user" fileName="${log-path}/bg_logs/user-${date:yyyy-MM-dd}.log" filePattern="${log-path}/bg_logs/user/user-%d{yyyy-MM-dd-HH}.log-%i.gz">
			<PatternLayout	pattern="${log_pattern}" />
			<Policies>
				<SizeBasedTriggeringPolicy size="30MB" />
				<TimeBasedTriggeringPolicy modulate="true"  interval="24" />
			</Policies>
			<DefaultRolloverStrategy max="40" />
		</RollingFile>
	</appenders>

	<!--
		只有定义了logger并引入的appender,appender才会生效,常见的有两种:RootLogger
		<Root>:节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出
			AppenderRef:指定该日志输出到哪个Appender
		<level>:日志输出级别,如果没有指定该属性,则默认为 ERROR
			name:该Logger所适用的类或者类所在的包路径
			additivity :设置日志事件是否在Root logger输出,为避免重复输出,可设置为false。如果没有指定该属性,则默认为 true
			includeLocation:默认情况下,异步日志记录器不会将location信息传递给I/O线程,如果你的layouts或custom过滤器需要location信息,你需要在所有相关日志记录器(包括根日志记录器)的配置中设置“includeLocation=true-->
	<Loggers>
		<root level="debug" includeLocation="true">
			<appender-ref ref="Console" />
		</root>

		<logger name="com.log.controller.LogOutputController" level="info" includeLocation="true" additivity="true">
			<appender-ref ref="user" />
		</logger>
<!--		<logger name="com.example.demo.bean.Teacher" level="info" includeLocation="true" additivity="true">-->
<!--			<appender-ref ref="file" />-->
<!--		</logger>-->
	</Loggers>
</configuration>

三、注意点说明

注意点1

注意点1

注意点1:控制文件内日志输出级别由<RollingFile><ThresholdFilter>的level属性和<Loggers>中的level属性共同控制,而不是由<configuration>的status属性控制。

注意点2

注意点2

注意点2:标签<RollingFile> vs <RollingRandomAccessFile>
	1)后者有缓冲区Buffer的概念,缓冲区满了后才会写入磁盘,所以可能看不到实时滚动更新的日志(但其性能更好)。要看到实时滚动更新的日志,则用RollingFIle2)另外<RollingFile><RollingRandomAccessFile>指定滚动日志,当TimeBasedTriggeringPolicySizeBasedTriggeringPolicy只要满足其中一项就会生成新的滚动日志文件。

注意点3

注意点3

注意点3<Loggers>的name属性指定打印该Logger所适用的类或者类所在的包路径,该name属性配置有2个使用问题点需要注意,
	1)说明场景1:假设我在LogOutputController中对User对象进行日志打印,那么这个name属性应该配置\logger name="com.log.controller.LogOutputController">,而不是配置<logger name="com.log.bean.User">,即这个name属性只是指向要打印被调用接口的路径下的所有日志信息,而不是哪个实体类被使用才指向谁。
	2)说明场景2:假设根路径设置debug级别<root level="debug">,当LogOutputController设置info级别且additivity="true"<logger name="com.log.controller.LogOutputController" level="info" additivity="true">,那这样调用接口后产生的效果是无论根路径所在日志log-xx.log还是user-xxx.log都不会打印debug级别信息,只会打印info及info以上的级别信息,详情如图1、如图23)说明场景3LogOutputController只配置controller所在的路径<logger name="com.log.controller.LogOutputController">,但是根路径文件内会打印controller层信息及关联使用的service下的所有日志信息(如图3),而user-xxx.log却只会打印controller层的日志信息(如图4)。

springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结_第4张图片

如图1

在这里插入图片描述

如图2

springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结_第5张图片

如图3

在这里插入图片描述

如图4

注意点4

注意点4

注意点4:\<configuration status="OFF">,configuration中设置status属性只是用来看到Log4j2启动和加载配置文件时的打印信息,而其他接口及关联类的日志打印输出不由它控制。设置\<configuration status="debug">效果如图7,设置\<configuration status="OFF">如图8

springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结_第6张图片

如图7

springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结_第7张图片

如图8

注意点5

注意点5

注意点5:使用log4j2.xml后控制台就无法使用了,哪怕调用接口也不会打印输出,只会在关联的日志文件内进行打印输出。

注意点6

注意点6

注意点6:举例说明滚动日志生成效果,比如设置<SizeBasedTriggeringPolicy size="1KB"/>,结果如图5,详情打开如图6

springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结_第8张图片

如图5

springboot项目使用log4j2,日志配置文件log4j2.xml的使用说明及个人注意点总结_第9张图片

如图6

你可能感兴趣的:(log4j,spring,boot,xml,使用log4j2,日志配置文件)