W Javadocs dlajava.util.logging.Level
państwa:
Poziomy w porządku malejącym to:
SEVERE
(najwyższa wartość)WARNING
INFO
CONFIG
FINE
FINER
FINEST
(najniższa wartość)
Źródło
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));
}
}
}
Wynik
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 . . .
Opis problemu
Mój przykład ustawia wartość Level
na FINER
, więc spodziewałem się zobaczyć 2 komunikaty dla każdej pętli. Zamiast tego widzę pojedynczą wiadomość dla każdej pętli ( Level.FINE
brakuje wiadomości).
Pytanie
Co należy zmienić, aby zobaczyć FINE
( FINER
lub FINEST
) wynik?
Aktualizacja (rozwiązanie)
Dzięki odpowiedzi Vineet Reynolds ta wersja działa zgodnie z moimi oczekiwaniami. Wyświetla 3 x INFO
wiadomości i 3 x FINE
wiadomości.
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
źródło
źródło
Odpowiedzi:
Loggery rejestrują tylko komunikat, tj. Tworzą zapisy dziennika (lub żądania logowania). Nie publikują wiadomości do miejsc docelowych, o co dbają Handlowcy. Ustawienie poziomu programu rejestrującego powoduje jedynie utworzenie rekordów dziennika odpowiadających temu poziomowi lub wyższemu.
Być może używasz
ConsoleHandler
(nie mogłem wywnioskować, gdzie twoje wyjście to System.err lub plik, ale przypuszczam, że jest to pierwszy), który domyślnie publikuje rekordy dziennika poziomuLevel.INFO
. Będziesz musiał skonfigurować tę procedurę obsługi, aby publikować rekordy dziennika poziomuLevel.FINER
i wyższego, aby uzyskać pożądany wynik.Polecam przeczytanie przewodnika Java Logging Overview , aby zrozumieć podstawowy projekt. Przewodnik przedstawia różnicę między koncepcją Logger i Handler.
Edycja poziomu obsługi
1. Korzystanie z pliku konfiguracyjnego
Plik właściwości java.util.logging (domyślnie jest to
logging.properties
plik wJRE_HOME/lib
) można zmodyfikować, aby zmienić domyślny poziom ConsoleHandler:2. Tworzenie programów obsługi w czasie wykonywania
Nie jest to zalecane, ponieważ spowodowałoby zastąpienie konfiguracji globalnej. Użycie tego w całej bazie kodu spowoduje prawdopodobnie niemożliwą do zarządzania konfigurację programu rejestrującego.
źródło
Handler
.Logger.getGlobal().getParent().getHandlers()[0].setLevel(Level.FINER);
Dlaczego
java.util.logging ma główny program rejestrujący, który domyślnie jest ustawiony na
Level.INFO
, i dołączony do niego ConsoleHandler, który również ma wartość domyślnąLevel.INFO
.FINE
jest mniejsza niżINFO
, więc dokładne komunikaty nie są wyświetlane domyślnie.Rozwiązanie 1
Utwórz rejestrator dla całej aplikacji, np. Z nazwy pakietu lub użycia
Logger.getGlobal()
, i podłącz do niego własny ConsoleLogger. Następnie poproś administratora programu rejestrującego o zamknięcie systemu (aby uniknąć zduplikowanych wyników komunikatów wyższego poziomu) lub poproś go, aby nie przekazywał dzienników rootowi.Rozwiązanie 2
Alternatywnie możesz obniżyć pasek głównego programu rejestrującego.
Możesz ustawić je kodem:
Lub z plikiem konfiguracyjnym logowania, jeśli go używasz :
Obniżając poziom globalny, możesz zacząć widzieć komunikaty z podstawowych bibliotek, na przykład z niektórych komponentów Swing lub JavaFX. W takim przypadku możesz ustawić filtr w głównym programie rejestrującym, aby odfiltrowywać wiadomości nie pochodzące z programu.
źródło
dlaczego moje logowanie java nie działa
udostępnia plik jar, który pomoże ci zrozumieć, dlaczego logowanie nie działa zgodnie z oczekiwaniami. Daje pełny zrzut tego, jakie programy rejestrujące i programy obsługi zostały zainstalowane, jakie poziomy są ustawione i na którym poziomie w hierarchii rejestrowania.
źródło
CZEMU
Jak wspomniała @Sheepy, powodem, dla którego nie działa, jest to, że
java.util.logging.Logger
ma główny program rejestrujący, który domyślnie maLevel.INFO
, aConsoleHandler
dołączony do tego głównego rejestratora również domyślnieLevel.INFO
. Dlatego, aby oglądnąćFINE
(,FINER
lubFINEST
) wyjścia, trzeba ustawić wartość domyślną rejestratorze korzeniowego i jegoConsoleHandler
sięLevel.FINE
następująco:Problem z aktualizacją (rozwiązanie)
Jak wspomniano w @mins, komunikaty będą drukowane na konsoli dwukrotnie dla
INFO
i powyżej: najpierw przez anonimowego programu rejestrującego, następnie jego rodzica, głównego programu rejestrującego, który również maConsoleHandler
ustawienieINFO
domyślne. Aby wyłączyć root logger, musisz dodać ten wiersz kodu:logger.setUseParentHandlers(false);
Istnieją inne sposoby zapobiegania przetwarzaniu dzienników przez domyślną procedurę obsługi konsoli głównego programu rejestrującego, o której wspomina @Sheepy, np .:
Ale
Logger.getLogger("").setLevel( Level.OFF );
nie zadziała, ponieważ blokuje tylko wiadomość przekazaną bezpośrednio do głównego programu rejestrującego, a nie wiadomość pochodzi z podrzędnego programu rejestrującego. Aby zilustrować, jak toLogger Hierarchy
działa, rysuję następujący diagram:public void setLevel(Level newLevel)
ustaw poziom dziennika określający, które poziomy komunikatów będą rejestrowane przez ten program rejestrujący. Poziomy wiadomości niższe niż ta wartość zostaną odrzucone. Wartość poziomu Level.OFF może służyć do wyłączania rejestrowania. Jeśli nowy poziom ma wartość null, oznacza to, że ten węzeł powinien dziedziczyć swój poziom po swoim najbliższym przodku z określoną (inną niż zerowa) wartością poziomu.źródło
Znalazłem mój rzeczywisty problem i nie został on wymieniony w żadnej odpowiedzi: niektóre z moich testów jednostkowych powodowały, że kod inicjujący rejestrowanie był uruchamiany wiele razy w ramach tego samego zestawu testów, zakłócając rejestrowanie w późniejszych testach.
źródło
Wypróbowałem inne warianty, to może być właściwe
źródło
To rozwiązanie wydaje mi się lepsze, jeśli chodzi o łatwość konserwacji i projektowanie pod kątem zmian:
Utwórz plik właściwości rejestrowania, osadzając go w folderze projektu zasobów, który zostanie dołączony do pliku jar:
Załaduj plik właściwości z kodu:
źródło