import org.apache.log4j.Appender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.varia.LevelRangeFilter;
public class LogLevelManager {
/**
* 動態設定指定 Appender 的最小日誌等級
* @param appenderName Appender 名稱 (對應 log4j.xml/appender name)
* @param levelStr 等級字串: DEBUG, INFO, WARN, ERROR, FATAL, OFF
*/
public static void setLogLevel(String appenderName, String levelStr) {
if (levelStr == null || appenderName == null) return;
// 1. 獲取根 Logger 的指定 Appender
Appender appender = Logger.getRootLogger().getAppender(appenderName);
if (appender == null) {
System.err.println("Appender not found: " + appenderName);
return;
}
// 2. 解析等級
Level level = Level.toLevel(levelStr);
if (level == null) {
System.err.println("Invalid level: " + levelStr);
return;
}
// 3. 遍歷 Filter 鏈,尋找 LevelRangeFilter
org.apache.log4j.spi.Filter filter = appender.getFilter();
while (filter != null) {
if (filter instanceof LevelRangeFilter) {
LevelRangeFilter lrf = (LevelRangeFilter) filter;
lrf.setLevelMin(level); // 設定最小等級
System.out.println("Updated " + appenderName + " LevelRangeFilter LevelMin to " + level);
break;
}
filter = filter.getNext();
}
// 4. 同步更新 Logger 等級 (確保生效)
Logger.getRootLogger().setLevel(level);
}
/**
* 獲取當前 Appender 實際等級
*/
public static Level getLogLevel(String appenderName) {
Appender appender = Logger.getRootLogger().getAppender(appenderName);
if (appender != null) {
org.apache.log4j.spi.Filter filter = appender.getFilter();
while (filter != null) {
if (filter instanceof LevelRangeFilter) {
return ((LevelRangeFilter) filter).getLevelMin();
}
filter = filter.getNext();
}
}
return Logger.getRootLogger().getLevel();
}
}
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logs/app.log"/>
<param name="MaxFileSize" value="10MB"/>
<param name="MaxBackupIndex" value="10"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%p] %c - %m%n"/>
</layout>
<!-- 關鍵:必須配置 LevelRangeFilter 才能動態調整 -->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="INFO"/>
<param name="LevelMax" value="FATAL"/>
</filter>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="FILE"/>
<appender-ref ref="CONSOLE"/>
</root>
public class TestLogLevel {
private static final Logger log = Logger.getLogger(TestLogLevel.class);
public static void main(String[] args) {
log.info("初始 INFO 級別");
log.debug("初始 DEBUG 級別 (不會輸出)");
// 動態開啟 DEBUG
LogLevelManager.setLogLevel("FILE", "DEBUG");
log.debug("動態調整後 DEBUG 級別 (會輸出)");
// 動態關閉 DEBUG
LogLevelManager.setLogLevel("FILE", "INFO");
log.debug("再次調整後 DEBUG 級別 (不會輸出)");
}
}
@Component
@ManagedResource(objectName = "com.example:type=LogManager", description = "動態日誌管理")
public class LogManagerMBean {
@ManagedAttribute(description = "檔案 Appender 日誌等級")
public String getFileAppenderLevel() {
return LogLevelManager.getLogLevel("FILE").toString();
}
@ManagedAttribute
public void setFileAppenderLevel(String level) {
LogLevelManager.setLogLevel("FILE", level);
}
@ManagedOperation(description = "設定所有 Appender 等級")
public void setAllAppendersLevel(String level) {
Logger root = Logger.getRootLogger();
for (Enumeration<Appender> e = root.getAllAppenders(); e.hasMoreElements();) {
Appender appender = e.nextElement();
LogLevelManager.setLogLevel(appender.getName(), level);
}
}
}
Logger.getLogger("com.xxx") 獲取特定 LoggerConfigurator.setLevel()、LoggerConfigimport org.apache.logging.log4j.Level;
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 Log4j2LevelManager {
public static void setLevel(String loggerName, String levelStr) {
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
loggerConfig.setLevel(Level.toLevel(levelStr));
ctx.updateLoggers(); // 關鍵:通知所有 Logger 更新
}
}
透過操作 Appender 的 LevelRangeFilter 實現 Log4j 1.x 動態調整日誌等級,核心步驟:獲取 Appender → 遍歷 Filter → 設定 LevelMin → 同步 Logger 等級。生產環境建議整合 JMX 或 Actuator 端點,提供安全的管理介面。