Ändern Sie die globale Einstellung für Logger-Instanzen
Lesezeit: 7 Minuten
Ich benutze java.util.logging.Logger als Logging-Engine für meine Anwendung. Jede Klasse verwendet ihren eigenen Logger, dh jede Klasse hat:
private final Logger logger = Logger.getLogger(this.getClass().getName());
Ich möchte für alle meine Klassen eine Protokollierungsebene festlegen und diese ändern können (dh die Einstellung an einem Ort haben). Gibt es eine Möglichkeit, dies zu tun, außer mit einer globalen Level Variable und jeden Logger manuell darauf einstellen?
Andi Thomas
Eine einfache Möglichkeit besteht darin, eine Protokollierungseigenschaftendatei zu verwenden, indem Sie dieses VM-Argument einfügen:
wobei „logging.properties“ der Pfad zu einer Datei ist, die die Protokollierungskonfiguration enthält. Bei relativen Pfaden ist das Arbeitsverzeichnis des Prozesses von Bedeutung.
Fügen Sie in dieser Datei eine Zeile wie diese ein:
.level= INFO
Dadurch wird die globale Ebene festgelegt, die für bestimmte Handler und Protokollierer überschrieben werden kann. Beispielsweise kann die Ebene eines bestimmten Loggers wie folgt überschrieben werden:
com.xyz.foo.level = SEVERE
Eine Vorlage für eine Protokollierungseigenschaftendatei erhalten Sie unter jre6\lib\logging.properties.
+1 Dies sollte die akzeptierte Antwort sein, und diese (einfache, prägnante) Antwort sollte mit all diesen java.util.logging-Fragen in SO verknüpft werden, die die Java-API fälschlicherweise verwenden, um java.util.logging zu optimieren. Ich weiß nicht, warum dieses Nugget praktisch in den Java-Dokumenten begraben ist, jeder müsste es tun. So wie es aussieht, ist die Verwendung von slf4j+logback einfacher als der Versuch, jul+logging.properties herauszufinden
– michael
26. Februar 2013 um 20:04 Uhr
Hinweis: Wenn Sie Handler haben, die auch Ebenen festlegen, müssen Sie diese ebenfalls setzen/zurücksetzen, da sie sonst Ihre anderen Protokollierungsebenen außer Kraft setzen. Wenn die Vorrangregeln verwirrend sind, können Sie beide setzen: java.util.logging.FileHandler.level=FINE + com.my.package.level=FINE
– michael
26. Februar 2013 um 20:07 Uhr
Ich habe entdeckt com.xyz.foo.level in meiner Log-Manager-Instanz, was mich dazu geführt hat jre/lib/logging.properties und die Tatsache, dass -Djava.util.logging.config.file="WEB-INF/classes/logging.properties" ist erforderlich, da JVM sich nicht die Mühe macht, den Klassenpfad zu durchsuchen.
– Vlastimil Ovčáčík
12. Februar 2016 um 7:35 Uhr
Interessanterweise sind die Eigenschaften auf Protokollebene (.level und [package].level) funktionieren bei mir in Java 8 nicht. Alle anderen Eigenschaften funktionieren so, wie sie sollen. Ich muss explizit Eigenschaften auf Handlerebene hinzufügen ([handler].level).
– Zenexer
28. April 2016 um 3:09 Uhr
@AndyThomas gibt es eine Möglichkeit, dies OHNE das JVM-Argument zu tun?
– Alvaro Pedraza
2. August 2017 um 22:03 Uhr
morja
Wie Andy antwortete, sollten Sie in den meisten Fällen die Eigenschaftsdatei und das VM-Argument verwenden, daher ist es unabhängig von Ihrem Code.
Aber wenn Sie aus irgendeinem Grund programmgesteuert vorgehen möchten (ich selbst hatte in einem Fall einen guten Grund), können Sie auch so auf die Handler zugreifen:
Logger rootLogger = LogManager.getLogManager().getLogger("");
rootLogger.setLevel(Level.INFO);
for (Handler h : rootLogger.getHandlers()) {
h.setLevel(Level.INFO);
}
BEARBEITEN Ich habe setLevel zum Root-Logger hinzugefügt, wie searchengine27 in seiner Antwort darauf hingewiesen hat.
Die Handler sind Datei- oder Konsolen-Handler, die Sie über die Eigenschaften oder auch programmgesteuert einrichten.
Ja, für alle, die dies als akzeptierte Antwort ansehen: Tu das nicht. Ändern Sie einfach die Eigenschaften in der Konfigurationsdatei. Die andere Antwort sollte die “akzeptierte” sein (dh die Einstellung java.util.logging.config.file=…). Code wie dieser macht den Wechsel zu slf4j/logback nur viel schwieriger 🙂
– michael
26. Februar 2013 um 20:01 Uhr
Ich stimme zu, die Verwendung der Konfigurationsdatei ist der richtige Weg. Ich wollte nur zeigen, wie man es manuell macht, da dies in der Frage gestellt wurde.
– morja
12. April 2013 um 10:46 Uhr
Es gibt Zeiten, in denen Sie dies programmgesteuert tun müssen, aber es sollte NICHT die Norm sein … es sollte ein außergewöhnlicher Bedarf sein.
– ssnyder
15. September 2017 um 15:19 Uhr
Mein Anwendungsfall für die dynamische Änderung der Protokollierung ist eine Tomcat-Anwendung, in der ich in 99 % der Fälle keine andere Protokollierung als CRITICAL benötige, aber wenn etwas nicht richtig funktioniert, möchte ich die Ebene erhöhen (verringern?). zu INFO, um alle meine Log-Meldungen zu sehen.
– Mark Stewart
9. Mai 2019 um 14:32 Uhr
Suchmaschine27
Ich mag also nicht alle Antworten hier ganz, also werde ich mich einmischen.
Verwendung der Konfigurationsdatei
Sie sehen hier viele Antworten, die Sie auffordern, die Konfigurationsdatei zu verwenden, da dies die beste Vorgehensweise ist. Ich möchte besser erklären, wie man das programmatisch macht, aber bevor ich das tue, möchte ich sagen, dass ich sehen kann, woher sie kommen, und in der Stimmung, objektiv zu sein, werde ich Sie ein wenig aufklären (vor allem, weil niemand sagt warum seine schlechte Praxis). Ich möchte eigentlich mitteilen, was jemand in einer separaten StackOverflow-Antwort gesagt hat, die sich auf das programmatische Einstellen des Logger-Levels bezieht (Warum werden die Level.FINE-Logging-Meldungen nicht angezeigt?):
Dies wird nicht empfohlen, da dies dazu führen würde, dass die globale Konfiguration außer Kraft gesetzt wird. Wenn Sie dies in Ihrer gesamten Codebasis verwenden, führt dies zu einer möglicherweise unüberschaubaren Protokollierungskonfiguration.
In diesem Sinne denke ich, dass Andy Thomas eine gute Antwort darauf hat, es nicht nicht-programmatisch zu tun.
Programmatisches Einstellen des Levels
Davon abgesehen möchte ich etwas detaillierter darauf eingehen, wie man es programmatisch macht, weil ich denke, dass es seinen Nutzen hat.
Stellen Sie sich ein Szenario vor, in dem Sie etwas mit einer Befehlszeilenschnittstelle schreiben und die Option haben, die Ausführlichkeit Ihrer Ausführung oder sogar den Ort anzugeben (wie in dynamischen Protokolldateien). Ich kann mich irren, aber Sie möchten dies wahrscheinlich nicht statisch in einer .conf-Datei tun. Vor allem, wenn Sie Ihre Benutzerbasis nicht dafür verantwortlich machen möchten, diese Dinge (aus welchem beliebigen Grund auch immer) in der Konfigurationsdatei einzustellen. Dies geht jedoch zu Lasten des obigen Zitats. Hier ist ein Beispiel dafür, wie Sie dies programmgesteuert tun können, indem Sie alle vorhandenen Handler auf dem Niveau halten, auf dem sie sich bereits befinden, und nur FileHandlernehmen wir das neue Level an:
public static void setDebugLevel(Level newLvl) {
Logger rootLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = rootLogger.getHandlers();
rootLogger.setLevel(newLvl);
for (Handler h : handlers) {
if(h instanceof FileHandler)
h.setLevel(newLvl);
}
}
Ich wollte dies aus einem bestimmten Grund über die akzeptierte Antwort hinaus ausführen. Wenn Sie dies programmgesteuert tun, möchten Sie nur sicherstellen, dass Sie den Pegel für den Logger festlegen und der/die Handler. Es funktioniert so, dass es prüft, ob die Anfrage zu niedrig für den Logger ist, und wenn ja, wird sie verworfen. Dann haben die Handler die gleiche Prüfung, also sollten Sie sicherstellen, dass sowohl die Protokollierer als auch die Handler auf die gewünschte Stufe eingestellt sind.
Auch, wenn Sie eine Desktop-Swing- oder FX-Anwendung erstellen. Sie sollten die Protokollierung dynamisch einstellen, um so viele Informationen wie möglich zu erhalten.
– Benutzer1363516
30. Juni 2015 um 14:45 Uhr
Nur um klarzustellen, "" ist der Root-Logger, kein anonymer Logger.
– Zenexer
28. April 2016 um 3:04 Uhr
Du hast Recht. Ich habe den Variablennamen im Code-Snippet aktualisiert, um ihn klarer zu machen.
– Suchmaschine27
28. April 2016 um 16:07 Uhr
hat dies positiv bewertet, um zu betonen, dass Sie das Niveau für festlegen Logger und der/die Handler
Sie werden also feststellen, dass bereits eine Standardkonfigurationsdatei vorhanden ist C:\Program Files\Java\jre1.8.0_221\lib\logging.properties
Ich empfehle, dass Sie eine neue Konfigurationsdatei unter Ihrem Projekt erstellen, um die Standardeinstellung zu überschreiben, gehen Sie wie folgt vor:
Name der Konfigurationsdatei, logging.propertiesalle Protokollebenen sind in zu finden Klassenstufe
handlers= java.util.logging.ConsoleHandler
.level= INFO
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format= [%1$tF %1$tT] [%4$-7s] %5$s %n
# your specific logger level
com.xyz.foo.level = SEVERE
Fügen Sie dann die jvm-Option hinzu, um die config