dynamic更改log4j日志级别
dynamic更改log4j日志级别有哪些不同的方法,以便我不必重新部署应用程序。 在这些情况下,这些变化是永久性的吗?
更改日志级别很简单; 修改configuration的其他部分将构成更深入的方法。
LogManager.getRootLogger().setLevel(Level.DEBUG);
Logger
的生命周期中的变化是永久的。 在重新初始化时,configuration将被读取和使用,因为在运行时设置级别不会保持级别改变。
更新:如果您正在使用Log4j 2,则应该删除对每个文档的 setLevel
调用,因为这可以通过实现类来实现。
API中不支持调用logger.setLevel()或类似的方法。 应用程序应删除这些。 在Log4j 2实现类中提供了等效的function,但可能会使应用程序易受Log4j 2内部的更改影响。
文件看门狗
Log4j能够监视log4j.xml
文件的configuration更改。 如果您更改log4j文件,log4j将根据您的更改自动刷新日志级别。 有关详细信息org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
请参阅org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
)的文档。 检查之间的默认等待时间是60秒。 由于您直接更改文件系统上的configuration文件,因此这些更改将保持不变。 所有你需要做的就是调用DOMConfigurator.configureAndWatch()一次。
警告:由于线程泄漏,configureAndWatch方法在J2EE环境中不安全
JMX
设置日志级别(或一般重新configuration)的另一种方法是使用JMX。 Log4j将其logging器注册为JMX MBean。 使用应用程序服务器MBeanServer控制台(或JDK的jconsole.exe),可以重新configuration每个单独的logging器。 这些更改不是永久性的,重新启动应用程序(服务器)后,将重置为configuration文件中设置的configuration。
自制
如Aaron所述,您可以通过编程方式设置日志级别。 您可以按照您希望的方式在您的应用程序中实现它。 例如,您可以有一个GUI,用户或pipe理员可以更改日志级别,然后调用logging器上的setLevel()
方法。 无论你是否坚持设置取决于你。
Log4j2可以configuration为通过以给定的时间间隔扫描log4j 2 .xml文件(或同等文件)来刷新其configuration。 只需将“ monitorInterval ”参数添加到您的configuration标签。 请参阅示例log4j 2 .xml文件的第2行,该文件告诉log4j在自上次日志事件以来已超过5秒的情况下重新扫描其configuration。
<?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>
使用log4j 1.x,我发现最好的方法是使用DOMConfigurator提交一组预定义的XML日志configuration(比如,一个用于正常使用,一个用于debugging)。
利用这些可以完成这样的事情:
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"); } }
只需使用相应的configuration名称来调用它,并确保将模板放在类path中。
我这样做,以dynamic更改log4j日志级别,它为我工作,我没有提到任何文件。 我使用这个系统属性值来设置我的日志文件名称。 我也使用相同的技术来设置日志logging级别,它工作
通过这个作为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>
如果您想要更改所有logging仪的logging级别,请使用以下方法。 这将枚举所有logging器并将logging级别更改为给定级别。 请确保您的log4j.properties
文件中没有设置log4j.appender.loggerName.Threshold=DEBUG
属性。
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));