动态更改log4j日志级别的不同方法有哪些,因此我不必重新部署应用程序。在这些情况下,这些变化是永久性的吗?
答案 0 :(得分:85)
Log4j能够查看log4j.xml
文件以了解配置更改。如果更改log4j文件,log4j将根据您的更改自动刷新日志级别。有关详细信息,请参阅org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
的文档。检查之间的默认等待时间为60秒。由于您直接更改文件系统上的配置文件,因此这些更改将是持久的。您需要做的就是一次调用DOMConfigurator.configureAndWatch()。
警告:由于线程泄漏,configureAndWatch方法在J2EE环境中使用是不安全的
另一种设置日志级别(或通常重新配置)log4j的方法是使用JMX。 Log4j将其记录器注册为JMX MBean。使用应用程序服务器MBeanServer控制台(或JDK的jconsole.exe),您可以重新配置每个单独的记录器。这些更改不会持久,并且会在重新启动应用程序(服务器)后重置为配置文件中设置的配置。
如Aaron所述,您可以以编程方式设置日志级别。您可以按照自己希望的方式在应用程序中实现它。例如,您可以使用GUI,用户或管理员更改日志级别,然后在记录器上调用setLevel()
方法。您是否将设置保留在某处取决于您自己。
答案 1 :(得分:80)
更改日志级别很简单;修改配置的其他部分将提供更深入的方法。
LogManager.getRootLogger().setLevel(Level.DEBUG);
这些变化在Logger
的生命周期中是永久性的。在重新初始化时,将读取并使用配置,因为在运行时设置级别不会持续更改级别。
更新:如果您使用的是Log4j 2,则应根据documentation删除对setLevel
的调用,因为这可以通过实现类来实现。
不支持调用logger.setLevel()或类似方法 API。应用程序应删除这些。等效功能是 在Log4j 2实现类中提供但可能会离开 应用程序易受Log4j 2内部变化的影响。
答案 2 :(得分:5)
可以将Log4j2配置为通过以给定间隔扫描log4j 2 .xml文件(或等效文件)来刷新其配置。只需将“ monitorInterval ”参数添加到配置标记即可。请参阅示例log4j 2 .xml文件的第2行,该文件告诉log4j在上次日志事件后超过5秒后重新扫描其配置。
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="warn" monitorInterval="5" name="tryItApp" packages="">
<Appenders>
<RollingFile name="MY_TRY_IT"
fileName="/var/log/tryIt.log"
filePattern="/var/log/tryIt-%i.log.gz">
<Policies>
<SizeBasedTriggeringPolicy size="25 MB"/>
</Policies>
...
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MY_TRY_IT"/>
</Root>
</Loggers>
</Configuration>
如果要部署到tomcat实例,IDE内部或使用spring boot,还有其他步骤可以使其工作。这似乎有点超出了范围,可能还有一个单独的问题。
答案 3 :(得分:2)
使用log4j 1.x我发现最好的方法是使用DOMConfigurator提交一组预定义的XML日志配置(例如,一个用于正常使用,一个用于调试)。
利用这些可以通过以下方式完成:
public static void reconfigurePredefined(String newLoggerConfigName) {
String name = newLoggerConfigName.toLowerCase();
if ("default".equals(name)) {
name = "log4j.xml";
} else {
name = "log4j-" + name + ".xml";
}
if (Log4jReconfigurator.class.getResource("/" + name) != null) {
String logConfigPath = Log4jReconfigurator.class.getResource("/" + name).getPath();
logger.warn("Using log4j configuration: " + logConfigPath);
try (InputStream defaultIs = Log4jReconfigurator.class.getResourceAsStream("/" + name)) {
new DOMConfigurator().doConfigure(defaultIs, LogManager.getLoggerRepository());
} catch (IOException e) {
logger.error("Failed to reconfigure log4j configuration, could not find file " + logConfigPath + " on the classpath", e);
} catch (FactoryConfigurationError e) {
logger.error("Failed to reconfigure log4j configuration, could not load file " + logConfigPath, e);
}
} else {
logger.error("Could not find log4j configuration file " + name + ".xml on classpath");
}
}
只需使用适当的配置名称调用它,并确保将模板放在类路径上。
答案 4 :(得分:2)
这个答案无法帮助您动态更改日志记录级别,如果您没有重新启动,则需要重新启动服务 服务,请使用以下解决方案
我这样做是为了改变log4j日志级别,它对我有用,我没有提到任何文件。我使用此系统属性值来设置我的日志文件名称。我使用相同的技术来设置日志记录级别,并且它可以工作
将此作为JVM参数传递(我使用Java 1.7)
抱歉这不会动态更改日志记录级别,需要重新启动服务
java -Dlogging.level=DEBUG -cp xxxxxx.jar xxxxx.java
在log4j.properties文件中,我添加了这个条目
log4j.rootLogger=${logging.level},file,stdout
我试过
java -Dlogging.level=DEBUG -cp xxxxxx.jar xxxxx.java
java -Dlogging.level=INFO-cp xxxxxx.jar xxxxx.java
java -Dlogging.level=OFF -cp xxxxxx.jar xxxxx.java
这一切都奏效了。希望这有帮助!
我的pom.xml中有以下依赖项
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-extras</artifactId>
<version>1.2.17</version>
</dependency>
答案 5 :(得分:1)
对于log4j 2 API,您可以使用
Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));
答案 6 :(得分:0)
我成功地使用了这种方法来减少“ org.apache.http”日志的冗长程度:
ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.apache.http");
logger.setLevel(Level.TRACE);
logger.setAdditive(false);
答案 7 :(得分:-1)
如果您想要更改所有记录器的日志记录级别,请使用以下方法。这将枚举所有记录器并将记录级别更改为给定级别。请确保不要在log4j.appender.loggerName.Threshold=DEBUG
文件中设置log4j.properties
属性。
public static void changeLogLevel(Level level) {
Enumeration<?> loggers = LogManager.getCurrentLoggers();
while(loggers.hasMoreElements()) {
Logger logger = (Logger) loggers.nextElement();
logger.setLevel(level);
}
}
答案 8 :(得分:-3)
您可以使用以下代码段
((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));