面试题答案
一键面试设计思路
- 日志分类存储:通过不同的Appender将业务日志、系统日志、访问日志分别存储到不同的文件或目标,便于后续管理和分析。
- 动态配置:利用Log4j 2的Configuration API实现日志级别和格式的动态调整,无需重启应用。
- 统一管理:采用集中式的配置文件(如XML、JSON等)对所有类型日志进行统一配置,便于维护。
关键实现步骤
- 引入依赖:在项目的
pom.xml
中添加Log4j 2相关依赖。
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
- 配置文件编写:创建
log4j2.xml
配置文件。
<Configuration status="WARN">
<Appenders>
<!-- 业务日志Appender -->
<File name="BusinessFile" fileName="business.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
<!-- 系统日志Appender -->
<File name="SystemFile" fileName="system.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
<!-- 访问日志Appender -->
<File name="AccessFile" fileName="access.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<!-- 业务日志Logger -->
<Logger name="businessLogger" level="info" additivity="false">
<AppenderRef ref="BusinessFile"/>
</Logger>
<!-- 系统日志Logger -->
<Logger name="systemLogger" level="info" additivity="false">
<AppenderRef ref="SystemFile"/>
</Logger>
<!-- 访问日志Logger -->
<Logger name="accessLogger" level="info" additivity="false">
<AppenderRef ref="AccessFile"/>
</Logger>
<Root level="info">
<AppenderRef ref="BusinessFile"/>
<AppenderRef ref="SystemFile"/>
<AppenderRef ref="AccessFile"/>
</Root>
</Loggers>
</Configuration>
- 动态调整日志级别:通过代码获取
Configuration
对象,修改Logger
的级别。
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
public class LogLevelChanger {
public static void changeLevel(String loggerName, String level) {
LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration config = context.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
loggerConfig.setLevel(org.apache.logging.log4j.Level.getLevel(level));
context.updateLoggers();
}
}
- 动态调整日志格式:类似动态调整日志级别,获取
Configuration
对象,修改PatternLayout
中的模式。
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.layout.PatternLayout;
public class LogFormatChanger {
public static void changeFormat(String loggerName, String newPattern) {
LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration config = context.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
Appender appender = loggerConfig.getAppenders().values().iterator().next();
PatternLayout layout = PatternLayout.newBuilder()
.withPattern(newPattern)
.build();
appender.setLayout(layout);
context.updateLoggers();
}
}
在实际应用中,可通过REST API等方式调用上述方法,实现动态调整日志级别和格式。