Chcesz spojrzeć na strukturę rejestrowania, a może na strukturę fasady rejestrowania.
Istnieje wiele ram rejestrowania, często z nakładającymi się funkcjami, do tego stopnia, że z czasem wielu ewoluowało, aby polegać na wspólnym interfejsie API, lub zaczęło być używanych przez strukturę elewacji, aby wyodrębnić ich użycie i umożliwić ich zamianę na miejscu Jeśli potrzebne.
Ramy
Niektóre ramy rejestrowania
Niektóre fasady z logowaniem
Stosowanie
Podstawowy przykład
Większość z tych frameworków pozwoli ci napisać coś w formie (tutaj używając slf4j-api
i logback-core
):
package chapters.introduction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// copied from: http://www.slf4j.org/manual.html
public class HelloWorld {
public static void main(String[] args) {
final Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.debug("Hello world, I'm a DEBUG level message");
logger.info("Hello world, I'm an INFO level message");
logger.warn("Hello world, I'm a WARNING level message");
logger.error("Hello world, I'm an ERROR level message");
}
}
Zwróć uwagę na użycie bieżącej klasy do stworzenia dedykowanego programu rejestrującego, który pozwoliłby SLF4J / LogBack sformatować dane wyjściowe i wskazać, skąd pochodzi komunikat rejestrowania.
Jak zauważono w podręczniku SLF4J , typowy wzorzec użycia w klasie to zwykle:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyClass {
final Logger logger = LoggerFactory.getLogger(MyCLASS.class);
public void doSomething() {
// some code here
logger.debug("this is useful");
if (isSomeConditionTrue()) {
logger.info("I entered by conditional block!");
}
}
}
Ale w rzeczywistości jeszcze bardziej powszechne jest deklarowanie programu rejestrującego za pomocą formularza:
private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class);
Pozwala to na użycie rejestratora również z metod statycznych i jest dzielony między wszystkie instancje klasy. Jest to prawdopodobnie preferowana forma. Jednak, jak zauważył Brendan Long w komentarzach, musisz mieć pewność, że rozumiesz implikacje i odpowiednio decydujesz (dotyczy to wszystkich ram rejestrowania następujących po tych idiomach).
Istnieją inne sposoby tworzenia instancji rejestratorów, na przykład za pomocą parametru ciągu w celu utworzenia nazwanego rejestratora:
Logger logger = LoggerFactory.getLogger("MyModuleName");
Poziomy debugowania
Poziomy debugowania różnią się w zależności od frameworka, ale typowe są (w kolejności krytyczności, od łagodnych do złych gówno-nietoperzy i od prawdopodobnie bardzo powszechnych do, miejmy nadzieję, bardzo rzadkich):
TRACE
Bardzo szczegółowe informacje. Powinny być zapisywane tylko w dziennikach. Służy tylko do śledzenia przepływu programu w punktach kontrolnych.
DEBUG
Dokładna informacja. Powinny być zapisywane tylko w dziennikach.
INFO
Znaczące zdarzenia w czasie wykonywania. Powinny być natychmiast widoczne na konsoli, więc używaj oszczędnie.
WARNING
Nieprawidłowości w działaniu i błędy, które można naprawić.
ERROR
Inne błędy w czasie wykonywania lub nieoczekiwane warunki.
FATAL
Poważne błędy powodujące przedwczesne zakończenie.
Bloki i Strażnicy
Załóżmy, że masz sekcję kodu, w której masz zamiar napisać kilka instrukcji debugowania. Może to szybko wpłynąć na wydajność, zarówno ze względu na wpływ samego rejestrowania, jak i generowania wszelkich parametrów przekazywanych do metody rejestrowania.
Aby uniknąć tego rodzaju problemów, często chcesz napisać coś w formie:
if (LOGGER.isDebugEnabled()) {
// lots of debug logging here, or even code that
// is only used in a debugging context.
LOGGER.debug(" result: " + heavyComputation());
}
Jeśli nie używałeś tego zabezpieczenia przed blokiem instrukcji debugowania, mimo że komunikaty mogą nie być wyprowadzane (jeśli na przykład twój program rejestrujący jest obecnie skonfigurowany do drukowania tylko rzeczy powyżej INFO
poziomu), heavyComputation()
metoda nadal byłaby wykonana .
Konfiguracja
Konfiguracja jest dość zależna od struktury rejestrowania, ale oferują one w większości te same techniki:
- konfiguracja programowa (w czasie wykonywania, poprzez API - pozwala na zmiany w czasie wykonywania ),
- statyczna konfiguracja deklaratywna (na początku, zwykle za pomocą pliku XML lub pliku właściwości - prawdopodobnie będzie to, czego potrzebujesz na początku ).
Oferują również w większości te same możliwości:
- konfiguracja formatu komunikatu wyjściowego (znaczniki czasu, znaczniki itp.),
- konfiguracja poziomów wyjściowych,
- konfiguracja filtrów drobnoziarnistych (na przykład w celu włączenia / wyłączenia pakietów lub klas),
- konfiguracja programów dołączających w celu określenia, gdzie należy się zalogować (do konsoli, do pliku, do usługi internetowej ...) i ewentualnie co zrobić ze starszymi dziennikami (na przykład z automatycznymi zwijaniem plików).
Oto typowy przykład konfiguracji deklaratywnej przy użyciu logback.xml
pliku.
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Jak wspomniano, zależy to od twojego frameworka i mogą istnieć inne alternatywy (na przykład LogBack pozwala również na użycie skryptu Groovy). Format konfiguracji XML może również różnić się w zależności od implementacji.
Więcej przykładów konfiguracji można znaleźć (między innymi) w:
Trochę historycznej zabawy
Należy pamiętać, że Log4J widzi znaczącą aktualizację w tej chwili, przejście z wersji 1.x do 2.x . Możesz rzucić okiem na więcej historycznej zabawy lub zamieszania, a jeśli wybierzesz Log4J, prawdopodobnie wolisz korzystać z wersji 2.x.
Warto zauważyć, jak wspomniał Mike Partridge w komentarzach, że LogBack został stworzony przez byłego członka zespołu Log4J. Który został stworzony w celu wyeliminowania niedociągnięć platformy Java Logging. I że nadchodząca główna wersja Log4J 2.x sama teraz integruje kilka funkcji zaczerpniętych z LogBack.
Zalecenie
Podsumowując, pozostań oddzielony jak najwięcej, baw się z kilkoma i zobacz, co będzie dla Ciebie najlepsze. Ostatecznie jest to po prostu struktura rejestrowania . Z wyjątkiem przypadku, gdy masz bardzo konkretny powód, oprócz łatwości użycia i osobistych preferencji, każdy z nich byłby raczej w porządku, więc nie ma sensu się nad nim wisieć. Większość z nich można również rozszerzyć na Twoje potrzeby.
Mimo to, gdybym dzisiaj musiał wybrać kombinację, wybrałbym LogBack + SLF4J. Ale jeśli zapytałeś mnie kilka lat później, poleciłbym Log4J z logowaniem Apache Commons, więc miej oko na swoje zależności i rozwijaj się wraz z nimi.