LOG4J2+SL4J 配置使用全流程

本文介绍了一个使用 Log4j2 和 Slf4j 的日志管理系统配置实例,详细展示了如何设置不同级别的日志输出、日志滚动策略及过滤条件等。通过示例代码演示了如何在应用中实现日志记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 1.文件目录:

这里写图片描述

  1. 2.pom:

<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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.zh</groupId>
  <artifactId>logtest</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>logtest</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    

  
  <!-- log配置:Log4j2 + Slf4j -->
      <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.11.0</version>
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.0</version>
  </dependency>
<dependency> <!-- 桥接:告诉Slf4j使用Log4j2 -->
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.11.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-jcl</artifactId>
    <version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>


  </dependencies>
</project>

  1. 3resource log4j2.xml内容:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
	<!-- 变量配置 -->
	<Properties>
		<Property name="log_path">./logs</Property>
	</Properties>

	<!-- appender配置 -->
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT">
			<PatternLayout
				pattern="%d{yy-MM-dd HH:mm:ss}-- %X{uuid}- %m%n" />
		</Console>
		
		<!--filepattern 为新文件夹命名规则 %i 可以生成序列号名称  -->
		<RollingFile name="DailyRollingFile"
			fileName="${log_path}/zhTest.log"
			
			filePattern="${log_path}/zHTest%d{yyyy-MM-dd}-%i.log">
			<PatternLayout
				pattern="%d{yy-MM-dd HH:mm:ss} %X{uuid}-S%m%n" />

<!-- 用于确定是否应发生翻转的策略 -->
			<Policies>
				<OnStartupTriggeringPolicy />
				<CronTriggeringPolicy schedule="0 0 0 1/1 * ? *"/>
				<SizeBasedTriggeringPolicy size="20 kb" />
				<TimeBasedTriggeringPolicy />
			</Policies>
<!-- 用于确定归档文件的名称和位置的策略  ifall==&&  ifany=|| glob里面为正则表达式-->
			<DefaultRolloverStrategy>
				<Delete basePath="./logs" maxDepth="2">
					<IfAll>
						<IfAny>
							<IfLastModified age="7d" />
							<IfAccumulatedFileCount exceeds="6" />
						</IfAny>
						<IfFileName glob="zHTest20*" />
					</IfAll>
				</Delete>
			</DefaultRolloverStrategy>
		</RollingFile>
	</Appenders>
//异步日志,保留7天,每天翻转
	<RollingFile name="ZH" fileName="${log_path}/system.log"
			filePattern="${log_path}/system.log.%d{yyyy-MM-dd}">
			<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} %5p %X{uuid} -- %m%n" />
			<Policies>
			<CronTriggeringPolicy schedule="0 0 0 * * ? *" />
			</Policies>
			<Filters>
				<ThresholdFilter level="warn" onMatch="DENY"
					onMismatch="NEUTRAL" />
				<ThresholdFilter level="info" onMatch="ACCEPT"
					onMismatch="NEUTRAL" />
			</Filters>
			<DefaultRolloverStrategy max="7">
			 <Delete basePath="${log_path}" maxDepth="3">
			   <IfFileName glob=".log.*" />
         	 <IfLastModified age="7d" />
        </Delete>
			</DefaultRolloverStrategy>
		</RollingFile>
	
	
	<Loggers>
	     <AsyncLogger name="com.zh" level="info" additivity="false">
        <AppenderRef ref="ZH" level="info"/>
        <AppenderRef ref="ZH1" />
    </AsyncLogger>
		<Root level="info">
		     <AppenderRef ref="ZH" level="info"/>
        <AppenderRef ref="ZH1" />
			<AppenderRef ref="Console" level="info"/>
			<AppenderRef ref="DailyRollingFile" level="error"/>
		</Root>
	</Loggers>
</Configuration>
  1. 4代码:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

/**
 * Hello world!
 *
 */
public class App 
{

	 static public Logger logger = LoggerFactory.getLogger(App.class);
    public static void main( String[] args )
    {
    
    	new Thread(new Runnable() {
			
			@Override
			public void run() {
				int ii=1;
				while(true) {
//						Thread.sleep(1000);
						MDC.put("uuid", StringUtils.getUUID());
						ii++;
						logger.info( "Hello World!" );
						logger.error("haha"+ii,"haha"+ii);
	
				}
			}
		}).start();
    	
    }
}



Utils:

package com.zh.logtest;

import java.util.ArrayList;
import java.util.UUID;

public class StringUtils {
	 /** 
	    * 获得指定数目的UUID 
	    * @param number int 需要获得的UUID数量 
	    * @return String[] UUID数组 
	    */ 
	    public static ArrayList<String> getUUID(int number){
	        ArrayList<String> list=new ArrayList<>();
	    if(number < 1){ 
	    return null; 
	    } 
	    for(int i=0;i<number;i++){ 
	    list.add(getUUID()); 
	    } 
	    return list; 
	    }

	    /** 
	    * 获得一个UUID 
	    * @return String UUID 
	    */ 
	    public static String getUUID(){ 
	    String uuid = UUID.randomUUID().toString(); 
	    //去掉“-”符号 
	    return uuid.replaceAll("-", "");
	    }
}

标准日志输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
	<!-- 变量配置 -->
	<Properties>
		<Property name="log_path">./logs</Property>
	</Properties>

	<!-- appender配置 -->
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT">
			<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} %5p %X{uuid} - %m%n" />
		</Console>
		<!--filepattern 为新文件夹命名规则 %i 可以生成序列号名称 -->
		<RollingFile name="TRACE" fileName="${log_path}/trace.log"

			filePattern="${log_path}/trace.log.%d{yyyy-MM-dd}-%i.log">
			<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} %5p %X{uuid} - %m%n" />

			<!-- 用于确定是否应发生翻转的策略 -->
			<Policies>
				<CronTriggeringPolicy schedule="0 0 0 1/1 * ? *" />
			</Policies>


			<!-- 用于确定归档文件的名称和位置的策略 ifall==&& ifany=|| glob里面为正则表达式 -->
			<DefaultRolloverStrategy>
				<Delete basePath="./logs" maxDepth="2">
					<IfFileName glob="trace.log.*">
						<IfAny>
							<IfLastModified age="7d" />
							<IfAccumulatedFileCount exceeds="8" />
						</IfAny>
					</IfFileName>
				</Delete>
			</DefaultRolloverStrategy>
		</RollingFile>


		<!--filepattern 为新文件夹命名规则 %i 可以生成序列号名称 -->
		<RollingFile name="SYSTEM" fileName="${log_path}/system.log"

			filePattern="${log_path}/system.log.%d{yyyy-MM-dd}-%i.log">
			<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} %5p %X{uuid} - %m%n" />

			<!-- 用于确定是否应发生翻转的策略 -->
			<Policies>
				<CronTriggeringPolicy schedule="0 0 0 1/1 * ? *" />
			</Policies>
			<Filters>
				<ThresholdFilter level="warn" onMatch="DENY"
					onMismatch="NEUTRAL" />
				<ThresholdFilter level="info" onMatch="ACCEPT"
					onMismatch="NEUTRAL" />
					
		
			</Filters>
			<!-- 用于确定归档文件的名称和位置的策略 ifall==&& ifany=|| glob里面为正则表达式 -->
			<DefaultRolloverStrategy>
				<Delete basePath="./logs" maxDepth="2">
					<IfFileName glob="system.log.*">
						<IfAny>
							<IfLastModified age="2d" />
							<IfAccumulatedFileCount exceeds="8" />
						</IfAny>
					</IfFileName>
				</Delete>
			</DefaultRolloverStrategy>
		</RollingFile>



		<RollingFile name="ERROR" fileName="${log_path}/error.log"

			filePattern="${log_path}/error.log.%d{yyyy-MM-dd}-%i.log">
			<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} %5p %X{uuid} - %m%n" />

			<Policies>
				<CronTriggeringPolicy schedule="0 0 0 1/1 * ? *" />
			</Policies>

			<Filters>
				<ThresholdFilter level="error" onMatch="ACCEPT"
					onMismatch="NEUTRAL" />
				<ThresholdFilter level="trace" onMatch="DENY"
					onMismatch="NEUTRAL" />
			</Filters>
			<DefaultRolloverStrategy>
				<Delete basePath="./logs" maxDepth="2">
					<IfFileName glob="error.log.*">
						<IfAny>
							<IfLastModified age="7d" />
							<IfAccumulatedFileCount exceeds="8" />
						</IfAny>
					</IfFileName>
				</Delete>
			</DefaultRolloverStrategy>
		</RollingFile>


		<RollingFile name="AUDIT" fileName="${log_path}/audit.log"

			filePattern="${log_path}/audit.log.%d{yyyy-MM-dd}-%i.log">
			<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} %5p %X{uuid} - %m%n" />
			<Policies>
				<CronTriggeringPolicy schedule="0 0 0 1/1 * ? *" />
					<SizeBasedTriggeringPolicy  size=""/>
		<!-- 						<TimeBasedTriggeringPolicy /> -->
			</Policies>

			<Filters>
				<ThresholdFilter level="error" onMatch="DENY"
					onMismatch="NEUTRAL" />
				<ThresholdFilter level="warn" onMatch="ACCEPT"
					onMismatch="NEUTRAL" />
				<ThresholdFilter level="trace" onMatch="DENY"
					onMismatch="NEUTRAL" />
			</Filters>
			<DefaultRolloverStrategy>
				<Delete basePath="./logs" maxDepth="2">
					<IfFileName glob="audit.log.*">
						<IfAny>
							<IfLastModified age="7d" />
							<IfAccumulatedFileCount exceeds="8" />
						</IfAny>
					</IfFileName>
				</Delete>
			</DefaultRolloverStrategy>
		</RollingFile>
	</Appenders>
	<Loggers>
		<Root level="info">
			<AppenderRef ref="Console" level="info" />
			<AppenderRef ref="TRACE" />
			<AppenderRef ref="SYSTEM" />
			<AppenderRef ref="ERROR" />
			<AppenderRef ref="AUDIT" />
		</Root>
	</Loggers>
</Configuration>

<think>好的,我需要解释用户关于slf4j-api和log4j-slf4j-impl的关系的问题。用户之前已经询问过MDC及其适配器的原理,现在转向这两个库的关系。首先,我需要回忆SLF4J的基本架构和它与不同日志实现的关系。 SLF4J是门面模式的应用,作为日志门面,提供统一的API,而具体实现由其他日志库如Logback、Log4j2等提供。用户提到的log4j-slf4j-impl可能是Log4j2SLF4J绑定。但需要确认是否正确,因为常见的绑定是log4j-slf4j-impl属于Log4j 1.x的适配器,而Log4j2通常使用log4j-slf4j2-impl。可能存在混淆,需要查证。 接下来,用户可能想知道这两个库如何协同工作。slf4j-api是接口,log4j-slf4j-impl是适配层,将SLF4J的调用桥接到Log4j的实现。需要解释桥接的过程,以及如何配置依赖关系。可能还要提到版本兼容性问题,例如Log4j的不同版本对应的适配器不同。 另外,用户可能遇到绑定冲突的问题,比如同时存在多个SLF4J绑定导致问题。需要说明SLF4J的绑定机制,即通过StaticLoggerBinder确定具体实现,多个绑定会报错。同时,可能需要提到如何排除冲突的依赖。 需要确保使用正确的术语,比如“适配器”、“绑定”、“桥接”等,并举例说明Maven依赖配置。还要注意用户可能对Log4j 1.x和Log4j2的区别不清楚,需要明确指出log4j-slf4j-impl对应的版本,避免误导。 最后,总结两者的关系,强调门面与实现的分层结构,以及正确配置的重要性。可能还需要提醒用户常见的坑,比如版本不匹配或依赖冲突。</think>### 分步解析:`slf4j-api` 与 `log4j-slf4j-impl` 的关系 --- #### **1. 核心定位** - **`slf4j-api`** SLF4J(Simple Logging Facade for Java)的**核心接口层**,提供统一的日志API(如 `Logger`、`LoggerFactory`)。它是日志系统的“门面”,不包含具体实现,开发者通过它编写日志代码,实现与底层日志框架(如 Log4j、Logback)的解耦。 - **`log4j-slf4j-impl`** Apache Log4j 2.x 提供的**SLF4J绑定层**(旧版Log4j 1.x的绑定是 `slf4j-log4j12`)。它实现了SLF4J的接口,将SLF4J的日志调用桥接到Log4j 2.x的底层实现。 --- #### **2. 协作流程** 1. **开发者代码** 通过 `slf4j-api` 的 `LoggerFactory.getLogger()` 创建日志对象: ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Demo { private static final Logger logger = LoggerFactory.getLogger(Demo.class); public void logExample() { logger.info("Hello SLF4J with Log4j2"); } } ``` 2. **绑定层(`log4j-slf4j-impl`)** - 实现SLF4J的 `ILoggerFactory` 接口,返回适配Log4j2的 `Logger` 实例。 - 将SLF4J的日志级别(如 `INFO`)映射到Log4j2的级别。 - 传递日志事件到Log4j2的核心引擎处理。 3. **底层日志库(Log4j2)** 实际执行日志输出(控制台、文件等),依赖Log4j2的核心配置(如 `log4j2.xml`)。 --- #### **3. 依赖关系** 典型Maven配置示例: ```xml <!-- 门面接口 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.36</version> </dependency> <!-- SLF4JLog4j2的绑定 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.20.0</version> </dependency> <!-- Log4j2核心库 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> </dependency> ``` --- #### **4. 关键机制** - **静态绑定** SLF4J在类路径中查找 `org.slf4j.impl.StaticLoggerBinder` 类(由 `log4j-slf4j-impl` 提供),完成与Log4j2的绑定。 **注**:如果存在多个绑定(如同时依赖 `log4j-slf4j-impl` 和 `logback-classic`),SLF4J会报错 `Multiple bindings found`。 - **桥接模式** `log4j-slf4j-impl` 通过 `org.apache.logging.slf4j.SLF4JLogger` 实现SLF4J的 `Logger` 接口,将调用转发给Log4j2的 `Log4jLogger`。 --- #### **5. 常见问题** - **版本冲突** 需确保 `slf4j-api` 与 `log4j-slf4j-impl` 版本兼容。例如: - SLF4J 1.7.x → 兼容Log4j2 2.x - SLF4J 2.x → 需搭配Log4j2 2.20.0+SLF4J 2.x与旧版不兼容) - **日志不输出** 检查是否缺少Log4j2配置文件(如 `log4j2.xml`)或绑定层未正确引入。 --- ### 总结 - **`slf4j-api`**:定义日志接口,开发者直接使用。 - **`log4j-slf4j-impl`**:桥接层,将SLF4J调用转发到Log4j2实现。 - **协作本质**:门面模式 + 适配器模式,实现日志框架的解耦与灵活切换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值