Quais são as diferentes abordagens para alterar o nível de log log4j dinamicamente, para que não precise reimplementar o aplicativo. As mudanças serão permanentes nesses casos?
Quais são as diferentes abordagens para alterar o nível de log log4j dinamicamente, para que não precise reimplementar o aplicativo. As mudanças serão permanentes nesses casos?
Respostas:
Alterar o nível do log é simples; modificar outras partes da configuração representará uma abordagem mais aprofundada.
LogManager.getRootLogger().setLevel(Level.DEBUG);
As mudanças são permanentes através do ciclo de vida do Logger
. Na reinicialização, a configuração será lida e usada, pois a definição do nível no tempo de execução não persiste na alteração do nível.
ATUALIZAÇÃO: Se você estiver usando o Log4j 2, remova as chamadas de setLevel
acordo com a documentação, pois isso pode ser alcançado através das classes de implementação.
As chamadas para logger.setLevel () ou métodos semelhantes não são suportadas na API. Os aplicativos devem removê-los. Funcionalidades equivalentes são fornecidas nas classes de implementação do Log4j 2, mas podem deixar o aplicativo suscetível a alterações nos componentes internos do Log4j 2.
LogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
O Log4j pode observar o log4j.xml
arquivo quanto a alterações na configuração. Se você alterar o arquivo log4j, o log4j atualizará automaticamente os níveis de log de acordo com suas alterações. Consulte a documentação de org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
) para obter detalhes. O tempo de espera padrão entre as verificações é de 60 segundos. Essas alterações seriam persistentes, pois você altera diretamente o arquivo de configuração no sistema de arquivos. Tudo o que você precisa fazer é chamar DOMConfigurator.configureAndWatch () uma vez.
Cuidado: o método configureAndWatch não é seguro para uso em ambientes J2EE devido a um vazamento de Encadeamento
Outra maneira de definir o nível de log (ou reconfigurar em geral) log4j é usando o JMX. O Log4j registra seus registradores como JMX MBeans. Usando os consoles MBeanServer dos servidores de aplicativos (ou o jconsole.exe do JDK), é possível reconfigurar cada registrador individual. Essas alterações não são persistentes e seriam redefinidas para a configuração conforme definida no arquivo de configuração após a reinicialização do aplicativo (servidor).
Conforme descrito por Aaron, você pode definir o nível de log programaticamente. Você pode implementá-lo em seu aplicativo da maneira que gostaria que acontecesse. Por exemplo, você pode ter uma GUI em que o usuário ou administrador altera o nível do log e, em seguida, chama os setLevel()
métodos no logger. Se você mantém as configurações em algum lugar ou não, é com você.
O Log4j2 pode ser configurado para atualizar sua configuração, varrendo o arquivo log4j 2 .xml (ou equivalente) em intervalos determinados. Basta adicionar o parâmetro " monitorInterval " à sua marca de configuração. Consulte a linha 2 do arquivo log4j 2 .xml de amostra , que instrui o log4j a verificar novamente sua configuração se mais de 5 segundos se passaram desde o último evento de log.
<?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>
Existem etapas extras para fazer isso funcionar se você estiver implantando em uma instância do tomcat, dentro de um IDE ou ao usar a inicialização por mola. Isso parece um pouco fora do escopo aqui e provavelmente merece uma pergunta separada.
Esta resposta não ajudará você a alterar o nível de log dinamicamente, você precisará reiniciar o serviço; se você estiver bem em reiniciar o serviço, use a solução abaixo
Fiz isso para alterar o nível de log do log4j e funcionou para mim; não enviei nenhum documento. Eu usei esse valor de propriedade do sistema para definir meu nome do arquivo de log. Eu usei a mesma técnica para definir o nível de log também, e funcionou
passou isso como parâmetro da JVM (eu uso Java 1.7)
Desculpe, isso não altera dinamicamente o nível de log, requer uma reinicialização do serviço
java -Dlogging.level=DEBUG -cp xxxxxx.jar xxxxx.java
no arquivo log4j.properties, adicionei esta entrada
log4j.rootLogger=${logging.level},file,stdout
eu tentei
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
Tudo funcionou. espero que isto ajude!
Eu tenho as seguintes dependências no meu 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>
Com o log4j 1.x, acho que a melhor maneira é usar um DOMConfigurator para enviar um de um conjunto predefinido de configurações de log XML (por exemplo, uma para uso normal e outra para depuração).
O uso destes pode ser feito com algo como isto:
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");
}
}
Apenas chame isso com o nome de configuração apropriado e certifique-se de colocar os modelos no caminho de classe.
Eu usei esse método com êxito para reduzir a verbosidade dos logs "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);
Para a API log4j 2, você pode usar
Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));
Se você deseja alterar o nível de log de todos os loggers, use o método abaixo. Isso enumerará todos os registradores e alterará o nível de registro para o nível especificado. Por favor, verifique se você NÃO possui log4j.appender.loggerName.Threshold=DEBUG
propriedades definidas no seu log4j.properties
arquivo.
public static void changeLogLevel(Level level) {
Enumeration<?> loggers = LogManager.getCurrentLoggers();
while(loggers.hasMoreElements()) {
Logger logger = (Logger) loggers.nextElement();
logger.setLevel(level);
}
}
Você pode usar o seguinte snippet de código
((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));