Quali sono i diversi approcci per modificare dinamicamente il livello di log log4j, in modo che non dovrò ridistribuire l'applicazione. Le modifiche saranno permanenti in questi casi?
Quali sono i diversi approcci per modificare dinamicamente il livello di log log4j, in modo che non dovrò ridistribuire l'applicazione. Le modifiche saranno permanenti in questi casi?
Risposte:
La modifica del livello di registro è semplice; la modifica di altre parti della configurazione pone un approccio più approfondito.
LogManager.getRootLogger().setLevel(Level.DEBUG);
I cambiamenti sono permanenti attraverso lo stile di vita del Logger
. Alla reinizializzazione, la configurazione verrà letta e utilizzata in quanto l'impostazione del livello in fase di esecuzione non persiste la modifica del livello.
AGGIORNAMENTO: Se si utilizza Log4j 2, è necessario rimuovere le chiamate in setLevel
base alla documentazione poiché ciò può essere ottenuto tramite le classi di implementazione.
Le chiamate a logger.setLevel () o metodi simili non sono supportate nell'API. Le applicazioni dovrebbero rimuovere questi. Funzionalità equivalenti sono fornite nelle classi di implementazione di Log4j 2 ma possono lasciare l'applicazione suscettibile alle modifiche interne a Log4j 2.
LogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
Log4j è in grado di guardare il log4j.xml
file per le modifiche alla configurazione. Se si modifica il file log4j, log4j aggiornerà automaticamente i livelli di registro in base alle modifiche. Vedi la documentazione diorg.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
) per i dettagli. Il tempo di attesa predefinito tra i controlli è di 60 secondi. Queste modifiche sarebbero persistenti, poiché si modifica direttamente il file di configurazione sul filesystem. Tutto quello che devi fare è invocare DOMConfigurator.configureAndWatch () una volta.
Attenzione: il metodo configureAndWatch non è sicuro per l'uso in ambienti J2EE a causa di una perdita di thread
Un altro modo per impostare il livello di log (o riconfigurare in generale) log4j è usando JMX. Log4j registra i suoi logger come MBM JMX. Utilizzando le console MBeanServer dei server applicazioni (o jconsole.exe di JDK) è possibile riconfigurare ogni singolo logger. Queste modifiche non sono persistenti e verrebbero ripristinate sulla configurazione come impostato nel file di configurazione dopo il riavvio dell'applicazione (server).
Come descritto da Aaron, è possibile impostare il livello di registro a livello di codice. È possibile implementarlo nell'applicazione nel modo desiderato. Ad esempio, è possibile disporre di una GUI in cui l'utente o l'amministratore modifica il livello di registro e quindi chiama i setLevel()
metodi nel logger. A prescindere dal fatto che tu mantenga le impostazioni da qualche parte o meno, dipende da te.
Log4j2 può essere configurato per aggiornare la sua configurazione eseguendo la scansione di log4j 2 file .xml (o equivalente) a determinati intervalli. Aggiungi semplicemente il parametro " monitorInterval " al tuo tag di configurazione. Vedere la riga 2 del file di esempio log4j 2 .xml, che indica a log4j di ripetere la scansione della sua configurazione se sono trascorsi più di 5 secondi dall'ultimo evento di registro.
<?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>
Esistono ulteriori passaggi per farlo funzionare se si sta eseguendo la distribuzione in un'istanza Tomcat, all'interno di un IDE o quando si utilizza l'avvio a molla. Sembra un po 'fuori portata qui e probabilmente merita una domanda separata.
Questa risposta non ti aiuterà a cambiare dinamicamente il livello di registrazione, devi riavviare il servizio, se stai bene riavviando il servizio, usa la soluzione qui sotto
Ho fatto questo per cambiare il livello di log log4j e ha funzionato per me, non ho fatto riferimento a nessun documento. Ho usato questo valore della proprietà di sistema per impostare il nome del mio file di registro. Ho usato la stessa tecnica anche per impostare il livello di registrazione, e ha funzionato
passato questo come parametro JVM (utilizzo Java 1.7)
Siamo spiacenti, questo non cambierà dinamicamente il livello di registrazione, richiede un riavvio del servizio
java -Dlogging.level=DEBUG -cp xxxxxx.jar xxxxx.java
nel file log4j.properties, ho aggiunto questa voce
log4j.rootLogger=${logging.level},file,stdout
Provai
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
Tutto ha funzionato. spero che questo ti aiuti!
Ho queste seguenti dipendenze nel mio 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>
Con log4j 1.x trovo che il modo migliore sia usare un DOMConfigurator per inviare una di una serie predefinita di configurazioni di log XML (diciamo, una per uso normale e una per il debug).
Fare uso di questi può essere fatto con qualcosa del genere:
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");
}
}
Basta chiamarlo con il nome di configurazione appropriato e assicurarsi di inserire i modelli nel percorso di classe.
Ho usato questo metodo con successo per ridurre la verbosità dei registri "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);
Per l'API log4j 2, è possibile utilizzare
Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));
Se si desidera modificare il livello di registrazione di tutti i logger, utilizzare il metodo seguente. Ciò enumererà tutti i logger e cambierà il livello di registrazione a un determinato livello. Assicurati di NON avere log4j.appender.loggerName.Threshold=DEBUG
proprietà impostate nel tuo log4j.properties
file.
public static void changeLogLevel(Level level) {
Enumeration<?> loggers = LogManager.getCurrentLoggers();
while(loggers.hasMoreElements()) {
Logger logger = (Logger) loggers.nextElement();
logger.setLevel(level);
}
}
Puoi utilizzare il seguente frammento di codice
((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));