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?
Observe que (quase) tudo nesta página é sobre log4j, não log4j2. Esta página inteira é tão cheia de confusão e desorientação que é inútil. Vá para stackoverflow.com/questions/23434252/… como @slaadvak recomenda.
Lambart 03/02
Respostas:
86
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 setLevelacordo 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.
Apenas para dependências de tempo de execuçãoLogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
CelinHC
8
Observe que a API log4j 2 não fornece um método "setLevel".
ChrisCantrell
5
Mas isso apenas define o logger raiz, não é? Se níveis individuais forem definidos para os registradores na raiz, a configuração do registrador raiz não terá efeito sobre esses registradores. Não precisaríamos fazer algo como root.getLoggerRepository (). GetCurrentCategories (), iterar sobre cada instância do logger e definir LEVELs para cada logger? @AaronMcIver
O Log4j2 pode ser configurado para atualizar sua configuração, varrendo o arquivo log4j2.xml (ou equivalente) em intervalos determinados. Por exemplo, <Configuration status = "warn" monitorInterval = "5" name = "tryItApp" packages = "">
Kimball Robinson
89
Arquivo Watchdog
O Log4j pode observar o log4j.xmlarquivo 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
JMX
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).
Self made
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ê.
Uma palavra de cautela em relação à abordagem do log4j watchdog: "Como o configureAndWatch inicia um encadeamento de watchdog separado e como não há como interromper esse encadeamento no log4j 1.2, o método configureAndWatch não é seguro para uso em ambientes J2EE em que os aplicativos são reciclados". Referência: Log4J FAQ
Somu
Se eu fosse usar a funcionalidade configureAndWatch do Log4j, poderia interromper esse segmento de watchdog no método @PostDestroy do EJB (esse é um indicador suficientemente bom de quando o contêiner está sendo desligado) É isso? Ou há mais do que estou perdendo ..!
precisa saber é o seguinte
desculpe eu quis dizer @PreDestroy método
bajaj robin
"O Log4j registra seus loggers como JMX MBeans. ". Meu servlet usa log4j 1.2. Não vejo nenhum MBeans log4j.
Abdull
Tudo o que você precisa fazer é chamar DOMConfigurator.configureAndWatch () uma vez. Como posso conseguir isso?
gstackoverflow
5
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.
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.
@vsingh, você está implantando dentro de boot de primavera, tomcat ou contêiner ou com um IDE? Às vezes, pode haver etapas extras nesses casos (não é culpa do log4j2) - basicamente, o aplicativo não pode ver o arquivo sendo alterado porque ele foi copiado para outro local por uma estrutura ou ferramenta.
Kimball Robinson
Oi Eu testei isso no Jboss6.4 e atualizei o arquivo de configuração log4j2 sob o local (dentro do arquivo .war) onde o aplicativo pode ver o arquivo. No entanto, ainda não funcionou. Alguma sugestão?
MidTierDeveloper 27/02/19
3
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
Tudo o que você mencionou parece estar bem, mas a questão é alterar dinamicamente o nível de log.
Azim
Para fazer isso, você precisa reiniciar o serviço. Isso não altera os níveis de log dinamicamente.
kk.
2
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:
publicstaticvoid 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)){newDOMConfigurator().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.
qual é o ponto de disparo desse método? como ele sabe que esse método precisa ser chamado sempre que houver uma alteração na configuração do log4j?
31/03/16
Ainda não entendi o que você quer dizer "sob demanda". Você pode mostrar um trecho onde você conecta esse método?
precisa saber é
2
Aqui está: Este é um trecho do Controller onde o usamos. Temos uma página de administração com alguns links para reconfigurar dinamicamente o log, o que gera um GET para o link / admin / setLogLevel? Level = Erro e capturamos isso no controlador como este @RequestMapping (value = "setLogLevel", method = RequestMethod.GET) public ModelAndView setLogLevel (@RequestParam (value = "level", required = true) Nível da string) {Log4jReconfigurator.reconfigureExisting (level);
ISparkes
Assim, "on demand" significa "Quando o usuário clica no botão" no meu caso
ISparkes
Ah, peguei você. Portanto, seu console administrativo precisa fazer uma solicitação para chamar esse método.
ASGs
0
Eu usei esse método com êxito para reduzir a verbosidade dos logs "org.apache.http":
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=DEBUGpropriedades definidas no seu log4j.propertiesarquivo.
Respostas:
Alterar o nível do log é simples; modificar outras partes da configuração representará uma abordagem mais aprofundada.
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.fonte
LogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
Arquivo Watchdog
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 deorg.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
JMX
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).
Self made
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ê.fonte
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.
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.
fonte
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
no arquivo log4j.properties, adicionei esta entrada
eu tentei
Tudo funcionou. espero que isto ajude!
Eu tenho as seguintes dependências no meu pom.xml
fonte
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:
Apenas chame isso com o nome de configuração apropriado e certifique-se de colocar os modelos no caminho de classe.
fonte
Eu usei esse método com êxito para reduzir a verbosidade dos logs "org.apache.http":
fonte
Para a API log4j 2, você pode usar
fonte
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 seulog4j.properties
arquivo.fonte
Você pode usar o seguinte snippet de código
fonte