Co słychać w logowaniu w Javie? [Zamknięte]

117

Dlaczego jeden z poniższych pakietów miałby używać zamiast drugiego?

  • Rejestrowanie Java
  • Commons Logging
  • Log4j
  • SLF4j
  • Logback
Loki
źródło
4
Możesz użyć stackoverflow.com/questions/873051 , który porównuje SLF4j z Commons Logging.
James McMahon
24
Dlaczego, do diabła, Ceki stworzył 3 ramy logowania !!! to szaleństwo ...
mP.
6
@poseł. - log4j był pierwszy, potem powstał spór i napisano slf4j + logback. slf4j to API i logback implementacją API. Niezależnie od wszystkiego innego, slf4j jest niezwykle przydatny.
Thorbjørn Ravn Andersen
3
Szczegółowe informacje na temat dlaczego nie stworzyć Ceki Gülcü SLF4J + Logback patrz poniższy Devoxx Dyskusja: parleys.com/#st=5&id=1701
Bitek
Najlepszą rzeczą, jaka z tego wyniknie, jest slf4j API, które, miejmy nadzieję, ujednolici świat logowania. Myślę, że logback nie osiągnął jeszcze masy krytycznej u programistów.
Thorbjørn Ravn Andersen

Odpowiedzi:

86

W porządku chronologicznym wyglądu api (o ile wiem):

  • Log4j, ponieważ prawie wszyscy go używają (z mojego doświadczenia)
  • Commons Logging, ponieważ używają go projekty open source (dzięki czemu mogą integrować się z dowolną strukturą rejestrowania używaną w zintegrowanym rozwiązaniu); szczególnie ważne, jeśli jesteś API / Framework / OSS i polegasz na innych pakietach, które używają Commons Logging.
  • Commons Logging, ponieważ nie chcesz "blokować" określonego frameworku rejestrowania (więc zamiast tego ograniczasz się do tego, co daje ci Commons Logging) - nie sądzę, aby rozsądne było decydowanie o tym punkcie jako przyczynie.
  • Rejestrowanie Java, ponieważ nie chcesz dodawać dodatkowego pliku jar.
  • SLF4j, ponieważ jest nowszy niż Commons Logging i zapewnia sparametryzowane rejestrowanie:

logger.debug("The entry is {}.", entry);
//which expands effectively to
if (logger.isDebugEnabled()){
    // Note that it's actually *more* efficient than this - see Huxi's comment below...
    logger.debug("The entry is " + entry + "."); 
}
  • Logback, ponieważ jest nowszy niż log4j i ponownie obsługuje sparametryzowane rejestrowanie, ponieważ bezpośrednio implementuje SLF4j
  • SLF4j / Logback, ponieważ został napisany przez tego samego gościa, który zrobił log4j, więc ulepszył go (według Kena G - dzięki. Wydaje się, że pasuje do ich wcześniejszych postów )
  • SLF4j, ponieważ publikują również adapter log4j, więc nie musisz "wyłączać" log4j w starszym kodzie - wystarczy, że log4j.properties używa SLF4j i jego konfiguracji
Stephen
źródło
3
O ile wiem, idea wspólnego rejestrowania jest taka, że ​​powinno być używane w bibliotekach. W ten sposób biblioteka może zawsze korzystać z tej samej struktury rejestrowania (poprzez rejestrowanie wspólne), z której korzysta aplikacja hostingowa.
Joachim Sauer
Wielkie dzięki dla Lokiego za pytanie. Teraz wiem, że nie będę już używać log4j jako domyślnej platformy. SLF4j FTW! Dziękuję również Kenowi G za wskazanie, że SLF4j jest napisane przez tego samego gościa co log4j
Stephen
3
Komentarz w przykładowym kodzie nie jest w 100% poprawny. Rzeczywiste formatowanie wiadomości jest wykonywane leniwie przez Logback, więc będzie to miało miejsce tylko wtedy, gdy zdarzenie jest naprawdę obsługiwane przez appender, a appender wymaga sformatowanej wiadomości - co nie zdarzyłoby się np. W przypadku SocketAppender, ponieważ zdarzenie jest serializowane przy użyciu niezmieniony wzorzec wiadomości + argumenty jako Strings. Myślę, że zależy to tylko od tego, jak zdefiniujesz „skutecznie”. Z pewnością wyemituje ten sam komunikat (przynajmniej jeśli wpis i obiekt są takie same;)), więc proszę wybaczyć moje czepianie się.
Huxi
6
SLF4J jest w rzeczywistości tylko interfejsem API, który znajduje się na szczycie innych platform rejestrowania. Podobny do celu Commons Logging, ale z mojego doświadczenia wynika, że ​​jest bardziej intuicyjny.
James McMahon
37

Uważam, że logowanie w Javie jest mylące, niespójne, słabo udokumentowane i szczególnie przypadkowe. Co więcej, istnieje ogromne podobieństwo między tymi strukturami rejestrowania, co powoduje powielanie pracy i niejasności co do środowiska logowania, w którym się aktualnie znajdujesz. W szczególności, jeśli pracujesz w poważnym stosie aplikacji internetowych Java, często jesteś w wielokrotnośćśrodowiska logowania w jednym czasie; (np. hibernacja może używać log4j i tomcat java.util.logging). Apache commons ma na celu łączenie różnych platform logowania, ale tak naprawdę tylko zwiększa złożoność. Jeśli nie wiesz tego z wyprzedzeniem, jest to całkowicie oszałamiające. Dlaczego moje komunikaty dziennika nie są drukowane na konsoli itp.? Och, ponieważ patrzę na logi Tomcata, a nie log4j. Dodając kolejną warstwę złożoności, serwer aplikacji może mieć globalne konfiguracje rejestrowania, które mogą nie rozpoznawać lokalnych konfiguracji dla określonej aplikacji internetowej. Wreszcie, wszystkie te ramy rejestrowania są ZBYT SKOMPLIKOWANE. Logowanie w Javie było chaotycznym bałaganem, przez co deweloperzy tacy jak ja byli sfrustrowani i zdezorientowani.

Wczesne wersje Java nie miały wbudowanej struktury rejestrowania, co prowadziło do tego scenariusza.

Julien Chastang
źródło
19
Czy to jest odpowiedź? Wygląda bardziej jak rant.
Michael Myers
15
Przepraszam. To jest trochę rant. Ale jest to również przekonująca odpowiedź na pytanie „Co słychać w logowaniu w Javie?”. Krótko mówiąc, jest głęboko złamana.
Julien Chastang
1
cóż, to nie jest warte głosu -1; P Ale coś do przemyślenia.
guyumu
21
Problemy zaczęły się, gdy firma Sun faktycznie dodała java.util.logging do języka Java 1.4. Wcześniej LOG4J miał ugruntowaną pozycję i był szeroko stosowany. Potem pojawiła się konieczność stosowania opakowań do obsługi zarówno LOG4J, jak i java.util.logging. Ponadto, ponieważ jul jest zawarty w pakiecie java. *, Nie można go zastąpić przez zamianę JAR - w ten sposób SLF4J łączy inne frameworki. To był prawdopodobnie najgorszy pomysł firmy Sun w historii… i ostatecznie doprowadził do błędnego założenia, że ​​„dobry obywatel Jawy” powinien używać języka jul.
Huxi
4
@Huxi, uważam, że API Kalendarza było gorsze. W obronie Sun to nie był ich kod, ale pochodził od Taglient.
Thorbjørn Ravn Andersen
22

Jest jeden ważny punkt, o którym wcześniej nie wspomniano:

SLF4J (i zarówno Logback, jak i LOG4J jako zaplecze logowania) obsługują tak zwany Mapped Diagnostic Context (MDC, patrz javadoc i dokumentacja ).

Jest to zasadniczo mapa <String, String> lokalna dla wątku, której można użyć do dodania dodatkowych informacji kontekstowych do zdarzenia rejestrowania. Aktualny stan MDC jest dołączony do każdego wydarzenia.

Może to być niezwykle przydatne, jeśli umieścisz w nim takie rzeczy, jak nazwa użytkownika i adres URL żądania (w przypadku aplikacji internetowej). Można to zrobić na przykład automatycznie za pomocą filtra.

Huxi
źródło
2
Z technicznego punktu widzenia jest to lokalna mapa wątku <String, String>.
pdxleif
17

Zobacz także odpowiedzi na pytanie Jakie są sprawdzone metody rejestrowania błędów? , szczególnie:

  • Istnieją pewne potencjalne problemy z ładowaniem klas z Commons Logging.

  • Log4J i SLF4J zostały opracowane przez tę samą osobę, ucząc się na podstawie problemów znalezionych w praktyce z Log4J.

Ken Gentle
źródło
4

W projekcie naszej firmy używamy LOG4j i jest on bardzo łatwy w użyciu, jak pokazał Stephen na swoim przykładzie. Napisaliśmy również własne klasy wzorców dla LOG4j, dzięki czemu możesz tworzyć własne schematy plików wyjściowych. Możesz opisać, jak powinien wyglądać Twój plik dziennika. Możliwe jest rozszerzenie oryginalnych klas log4j.

Wszystkie właściwości LOG4j można zmienić w pliku log4j.properties, dzięki czemu można używać różnych plików dla różnych projektów.

Rejestrowanie w Javie nie jest moją ulubioną, ale może to być spowodowane tym, że używam log4j od samego początku.

Markus Lausberg
źródło
4

Commons Logging przegląd daje powód jego istnienia: Rejestrowanie kodu z biblioteki, gdy nie masz kontroli nad spodem ramy rejestrowania. Bardzo ważne dla różnych projektów Apache, które będą połączone z zewnętrznymi aplikacjami. Być może nie jest to tak ważne dla wewnętrznych projektów IT, w których masz pełną kontrolę.

To powiedziawszy, piszę do Commons Logging, podobnie jak wielu innych programistów, których znam. Powodem jest zminimalizowanie bagażu mentalnego: możesz zmieniać projekty lub prace i nie musisz uczyć się nowych ram (pod warunkiem, że nowa praca / projekt również korzysta z CL i / lub możesz przekonać ich do przejścia do niego).

Istnieje również pewna wartość w tworzeniu własnych opakowań wokół używanego frameworka. Jak opisano tutaj , lubię używać obiektu LogWrapper, aby zapewnić niestandardowe ciągi znaków (ważne) i zminimalizować wizualny bałagan w instrukcjach logowania (mniej ważne).

kdgregory
źródło
1
Istnieje również most commons.logging => SLF4J, który może być używany do kierowania wszystkich rejestrów CL przez SLF4J. SLF4J obsługuje mostkowanie commons.logging, LOG4J i (trochę uciążliwe, ale tak dobre, jak to tylko możliwe) java.util.logging, więc wszystkie logi trafią do dowolnego backendu SLF4J, którego będziesz używać. Zobacz slf4j.org/legacy.html Przy okazji użyłbym Logback, ale możesz argumentować, że jestem stronniczy.
Huxi
2

Generalnie używałbym Log4J.

Użyłbym rejestrowania Java, gdybym nie miał nic przeciwko zależności od Java 1.4, ale nadal preferowałbym Log4J.

Użyłbym Commons Logging, gdybym ulepszał coś, co już go używało.

Michael Rutherfurd
źródło
Nie przeszkadzała nam zależność od 1.4 ?? Nawet 1.4 osiągnął koniec żywotności.
Tom Hawtin - tackline
2
@Tom Ma na myśli jdk1.4 + nie bądź głupi.
mP.
Właściwie ostatnio wykonałem trochę pracy w systemie, który wciąż działał pod jdk 1.3 :-( i to było mniej niż dwa lata temu ostatnio utrzymywałem system jdk 1.2 . Zbyt wiele miejsc nie aktualizuje się, chyba że absolutnie mają po prostu odmawiają instalacji uaktualnień.
Michael Rutherfurd
0

Sugerowałbym stworzenie cienkiej fasady rejestrowania, która może zapisywać w dowolnej platformie rejestrowania, w którym to momencie wybór silnika wspierającego staje się kwestią sporną.

tsimon
źródło
2
To właśnie robi wspólne logowanie, więc po co wymyślać koło na nowo? Istnieją również pewne problemy, z którymi Twoja fasada musiałaby sobie poradzić, co już ma miejsce w przypadku zwykłego drewna.
James AN Stauffer
+1 Aby przeciwdziałać argumentowi rejestrowania powszechnego, niektóre aplikacje korporacyjne używają niestandardowego rejestratora. Zawsze dobrze jest ukryć podstawową implementację. „Cienkie” opakowanie eliminuje potrzebę pakowania kolejnego słoika i nie jest aż tak wymyślane na nowo.
questzen
1
To uratowało mnie ostatnio, kiedy przenieśliśmy nasz framework do Compact Framework (w .Net). Gdybyśmy mieli zakodowane na stałe zależności od nLog, zostalibyśmy załatwieni. Ponieważ zastosowaliśmy to podejście, mogliśmy dodać zerowy rejestrator i być szczęśliwym. Ktoś głosuje na mnie z powrotem do 0 Proszę :-)
tsimon
3
Jeden już istnieje - spójrz na slf4j. Jest to akceptowane cienkie opakowanie, które umożliwia przełączanie struktur rejestrowania podczas uruchamiania aplikacji przez przełączanie plików JAR w ścieżce klas środowiska wykonawczego.
przerwa
1
clogging ma swój własny sposób na odkrycie, jakiego frameworka będzie używał - nie jest ładny i raczej zawiły. Ile frameworków logowania stworzył Ceki. Należy zawsze dążyć do umieszczenia poziomu wzajemnych powiązań i ukrycia implementacji, nawet jeśli zapycha się ona własnym logowaniem. Za kulisami możesz następnie podłączyć dowolne oprogramowanie, o czym wspomniał Travis.
mP.