Die JavaDocs fürjava.util.logging.Level
state:
Die Ebenen in absteigender Reihenfolge sind:
SEVERE
(Höchster Wert)WARNING
INFO
CONFIG
FINE
FINER
FINEST
(niedrigster Wert)
Quelle
import java.util.logging.*;
class LoggingLevelsBlunder {
public static void main(String[] args) {
Logger logger = Logger.getAnonymousLogger();
logger.setLevel(Level.FINER);
System.out.println("Logging level is: " + logger.getLevel());
for (int ii=0; ii<3; ii++) {
logger.log(Level.FINE, ii + " " + (ii*ii));
logger.log(Level.INFO, ii + " " + (ii*ii));
}
}
}
Ausgabe
Logging level is: FINER
Jun 11, 2011 9:39:23 PM LoggingLevelsBlunder main
INFO: 0 0
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 1 1
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 2 4
Press any key to continue . . .
Problemstellung
In meinem Beispiel ist das Level
auf gesetzt FINER
, sodass ich erwartet hatte, dass für jede Schleife 2 Nachrichten angezeigt werden. Stattdessen sehe ich für jede Schleife eine einzelne Nachricht (die Level.FINE
Nachrichten fehlen).
Frage
Was muss geändert werden, um die FINE
( FINER
oder FINEST
) Ausgabe zu sehen?
Update (Lösung)
Dank der Antwort von Vineet Reynolds funktioniert diese Version gemäß meinen Erwartungen. Es werden 3 x INFO
Nachrichten und 3 x FINE
Nachrichten angezeigt .
import java.util.logging.*;
class LoggingLevelsBlunder {
public static void main(String[] args) {
Logger logger = Logger.getAnonymousLogger();
// LOG this level to the log
logger.setLevel(Level.FINER);
ConsoleHandler handler = new ConsoleHandler();
// PUBLISH this level
handler.setLevel(Level.FINER);
logger.addHandler(handler);
System.out.println("Logging level is: " + logger.getLevel());
for (int ii=0; ii<3; ii++) {
logger.log(Level.FINE, ii + " " + (ii*ii));
logger.log(Level.INFO, ii + " " + (ii*ii));
}
}
}
java
logging
java.util.logging
Andrew Thompson
quelle
quelle
Antworten:
Protokollierer protokollieren nur die Nachricht, dh sie erstellen die Protokolldatensätze (oder Protokollierungsanforderungen). Sie veröffentlichen die Nachrichten nicht an den Zielen, um die sich die Handler kümmern. Wenn Sie die Ebene eines Loggers festlegen, wird dieser nur erstellt Log - Aufzeichnungen , dass die Pegelanpassung oder höher.
Möglicherweise verwenden Sie eine
ConsoleHandler
(ich konnte nicht ableiten, wo Ihre Ausgabe System.err oder eine Datei ist, aber ich würde annehmen, dass es die erstere ist), die standardmäßig Protokolldatensätze der Ebene veröffentlichtLevel.INFO
. Sie müssen diesen Handler konfigurieren, um Protokolldatensätze der Ebene zu veröffentlichenLevel.FINER
und höher für das gewünschte Ergebnis zu veröffentlichen.Ich würde empfehlen, das Handbuch zur Java-Protokollierungsübersicht zu lesen , um das zugrunde liegende Design zu verstehen. Das Handbuch behandelt den Unterschied zwischen dem Konzept eines Loggers und eines Handlers.
Bearbeiten der Handler-Ebene
1. Verwenden der Konfigurationsdatei
Die Eigenschaftendatei java.util.logging (standardmäßig ist dies die
logging.properties
Datei inJRE_HOME/lib
) kann geändert werden, um die Standardstufe des ConsoleHandler zu ändern:2. Erstellen von Handlern zur Laufzeit
Dies wird nicht empfohlen, da dies dazu führen würde, dass die globale Konfiguration überschrieben wird. Die Verwendung dieser Option in Ihrer gesamten Codebasis führt zu einer möglicherweise nicht verwaltbaren Logger-Konfiguration.
quelle
Handler
.Logger.getGlobal().getParent().getHandlers()[0].setLevel(Level.FINER);
Das Warum
java.util.logging verfügt standardmäßig über einen Root-Logger
Level.INFO
und einen ConsoleHandler, der ebenfalls standardmäßig verwendet wirdLevel.INFO
.FINE
ist niedriger alsINFO
, daher werden feine Nachrichten standardmäßig nicht angezeigt.Lösung 1
Erstellen Sie einen Logger für Ihre gesamte Anwendung, z. B.
Logger.getGlobal()
anhand Ihres Paketnamens oder Ihrer Verwendung , und hängen Sie Ihren eigenen ConsoleLogger daran an. Bitten Sie dann entweder den Root-Logger, den Computer herunterzufahren (um die doppelte Ausgabe von Nachrichten höherer Ebene zu vermeiden), oder bitten Sie Ihren Logger, die Protokolle nicht an den Root weiterzuleiten .Lösung 2
Alternativ können Sie die Leiste des Root-Loggers senken.
Sie können sie per Code einstellen:
Oder mit der Protokollierungskonfigurationsdatei, wenn Sie diese verwenden :
Wenn Sie die globale Ebene senken, werden möglicherweise Nachrichten aus Kernbibliotheken angezeigt, z. B. von einigen Swing- oder JavaFX-Komponenten. In diesem Fall können Sie im Root-Logger einen Filter festlegen , um Nachrichten herauszufiltern, die nicht aus Ihrem Programm stammen.
quelle
Warum funktioniert meine Java-Protokollierung nicht?
Bietet eine JAR-Datei, mit der Sie herausfinden können, warum Ihre Anmeldung nicht wie erwartet funktioniert. Sie erhalten einen vollständigen Überblick darüber, welche Logger und Handler installiert wurden und welche Ebenen festgelegt wurden und auf welcher Ebene in der Protokollierungshierarchie.
quelle
WARUM
Wie von @Sheepy erwähnt, funktioniert es nicht,
java.util.logging.Logger
weil standardmäßig ein Root-Logger verwendetLevel.INFO
wird und derConsoleHandler
an diesen Root-Logger angehängte standardmäßig ebenfallsLevel.INFO
. Deshalb, um die zu sehenFINE
(,FINER
oderFINEST
) ausgegeben, müssen Sie den Standardwert der Root - Logger setzen und seineConsoleHandler
aufLevel.FINE
wie folgt:Das Problem Ihres Updates (Lösung)
Wie von @mins erwähnt, werden die Nachrichten für
INFO
und über zweimal auf der Konsole gedruckt : zuerst vom anonymen Logger, dann vom übergeordneten Logger, dem Root-LoggerConsoleHandler
, aufINFO
den standardmäßig ebenfalls festgelegt ist. Um den Root-Logger zu deaktivieren, müssen Sie folgende Codezeile hinzufügen:logger.setUseParentHandlers(false);
Es gibt andere Möglichkeiten, um zu verhindern, dass Protokolle vom Standard-Konsolenhandler des von @Sheepy erwähnten Root-Loggers verarbeitet werden, z.
Funktioniert
Logger.getLogger("").setLevel( Level.OFF );
jedoch nicht, da nur die direkt an den Root-Logger übergebene Nachricht blockiert wird und nicht die Nachricht von einem untergeordneten Logger stammt. Um zu veranschaulichen, wie dasLogger Hierarchy
funktioniert, zeichne ich das folgende Diagramm:public void setLevel(Level newLevel)
Legen Sie die Protokollebene fest und geben Sie an, welche Nachrichtenebenen von diesem Protokollierer protokolliert werden. Nachrichtenpegel, die unter diesem Wert liegen, werden verworfen. Mit dem Pegelwert Level.OFF können Sie die Protokollierung deaktivieren. Wenn die neue Ebene null ist, bedeutet dies, dass dieser Knoten seine Ebene von seinem nächsten Vorfahren mit einem bestimmten Wert (nicht null) erben sollte.quelle
Ich habe mein eigentliches Problem gefunden und es wurde in keiner Antwort erwähnt: Einige meiner Komponententests führten dazu, dass der Protokollierungsinitialisierungscode innerhalb derselben Testsuite mehrmals ausgeführt wurde, was die Protokollierung bei den späteren Tests durcheinander brachte.
quelle
Versucht andere Varianten, kann dies richtig sein
quelle
Diese Lösung erscheint mir in Bezug auf Wartbarkeit und Design für Änderungen besser:
Erstellen Sie die Protokollierungseigenschaftendatei, in die sie im Ressourcenprojektordner eingebettet ist, um sie in die JAR-Datei aufzunehmen:
Laden Sie die Eigenschaftendatei aus dem Code:
quelle