有什么不同的方法可以动态更改log4j日志级别,这样我就不必重新部署应用程序。在这种情况下,更改是否是永久性的?
有什么不同的方法可以动态更改log4j日志级别,这样我就不必重新部署应用程序。在这种情况下,更改是否是永久性的?
Answers:
更改日志级别很简单;修改配置的其他部分将构成更深入的方法。
LogManager.getRootLogger().setLevel(Level.DEBUG);
这些变化在生命周期中是永久的Logger
。重新初始化时,将读取配置并将其用作运行时设置级别,而不保留级别更改。
更新:如果您正在使用Log4j 2,则应删除setLevel
对文档的调用,因为可以通过实现类来实现。
API不支持调用logger.setLevel()或类似方法。应用程序应删除这些。Log4j 2实现类中提供了等效的功能,但可能会使应用程序容易受到Log4j 2内部的更改的影响。
LogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
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()
在记录器上调用方法。是否将设置持久化取决于您自己。
可以将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时,还有一些额外的步骤可以使此工作正常进行。这似乎有点超出范围,可能值得提出一个单独的问题。
此答案不会帮助您动态更改日志记录级别,需要重新启动服务,如果可以很好地重新启动服务,请使用以下解决方案
我这样做是为了更改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>
使用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");
}
}
只需使用适当的配置名称调用它,并确保将模板放在类路径上即可。
如果要更改所有记录器的记录级别,请使用以下方法。这将枚举所有记录器,并将记录级别更改为给定级别。请确保你不要有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);
}
}
您可以使用以下代码段
((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));