Jak wysłać java.util.logging do log4j?


84

Mam istniejącą aplikację, która wykonuje wszystkie swoje logowanie względem log4j. Korzystamy z wielu innych bibliotek, które albo używają log4j, albo logują się do Commons Logging, co kończy się użyciem log4j pod osłonami w naszym środowisku. Jedna z naszych zależności loguje nawet do slf4j, która również działa dobrze, ponieważ ostatecznie deleguje również do log4j.

Teraz chciałbym dodać ehcache do tej aplikacji na potrzeby buforowania. Poprzednie wersje ehcache wykorzystywały wspólne logowanie, które działałoby doskonale w tym scenariuszu, ale od wersji 1.6-beta1 usunęły one zależność od commons-logging i zamiast tego zastąpiły je java.util.logging.

Nie jestem zaznajomiony z wbudowanym rejestrowaniem JDK dostępnym w java.util.logging, czy istnieje łatwy sposób, aby jakiekolwiek komunikaty dziennika wysyłane do JUL były rejestrowane w log4j, więc mogę użyć mojej istniejącej konfiguracji i ustawić dla każdego nadchodzącego logowania z ehcache?

Patrząc na javadoc dla JUL, wygląda na to, że mógłbym ustawić kilka zmiennych środowiskowych, aby zmienić LogManagerużywaną implementację, i być może użyć tego do zawijania log4j Loggerw Loggerklasie JUL . Czy to jest właściwe podejście?

To trochę ironiczne, że korzystanie przez bibliotekę z wbudowanego rejestrowania JDK powodowałoby taki ból głowy, gdy (większość) reszta świata zamiast tego korzysta z bibliotek innych firm.

Odpowiedzi:


37

Jedną z metod, które z powodzeniem zastosowałem, jest użycie slf4j jako mojego podstawowego interfejsu API logowania. Następnie mam powiązanie slf4j z log4j. Zależności innych firm korzystające z innych frameworków (takich jak JUL) można mostkować do slf4j.


2
Dobry link, ale myślę, że miałeś na myśli # jul-to-slf4j
araqnid

Brzmi to jak dobre podejście, ale nie wydaje mi się, żebym działał :(
matt b

2
Nie mogę też uwierzyć, że biblioteka tak popularna jak ehcache mogłaby przejść na coś takiego jak java.util.logging - wydaje się bardzo ostra
mat b

1
@matt b, JUL jest zawsze obecny w środowisku wykonawczym Java, więc wymaga jak najmniej zewnętrznych zależności. Jest to jednak w moich oczach prawdziwy przykład kodu napisanego przez ludzi, którzy nie mają doświadczenia z jego używaniem. System konfiguracji jest raczej niewygodny.
Thorbjørn Ravn Andersen

1
Problem polega na tym, że jeśli łączysz SLF4J z JUL, wydajność logowania jest przerażająca. W szczególności każdy utworzony wiersz dziennika powoduje zgłoszenie wyjątku w celu określenia, którego kontekstu programu rejestrującego należy użyć. To generuje dużo narzutów i spowalnia procesy
Egwor,

19

Używamy SLF4J w naszym obecnym projekcie i działa to bardzo dobrze dla nas. SLF4J został napisany przez Ceki Gülcü, twórcę Log4J, i wykonał naprawdę świetną robotę. W naszym kodzie używamy bezpośrednio interfejsów API logowania SLF4J i konfigurujemy SLF4J tak, aby wywołania z Jakarta Commons Logging (JCL), java.util.logging (JUL) i Log4J API były połączone mostem z interfejsami API SLF4J. Musimy to zrobić, ponieważ podobnie jak Ty korzystamy z bibliotek innych firm (open source), które wybrały różne interfejsy API do logowania.

W dolnej części SLF4J konfigurujesz go tak, aby używał określonej implementacji rejestratora. Jest wyposażony w wewnętrzny lub „prosty” rejestrator, który można zastąpić za pomocą Log4J, JUL lub Logback . Konfiguracja odbywa się po prostu przez umieszczenie różnych plików jar w ścieżce klas.

Pierwotnie korzystaliśmy z implementacji Logback, również napisanej przez Ceki Gülcü. To jest bardzo potężne. Jednak zdecydowaliśmy się następnie wdrożyć naszą aplikację na serwerze aplikacji Glassfish Java EE, którego przeglądarka dziennika oczekuje komunikatów w formacie JUL. Więc dzisiaj przestawiłem się z Logback na JUL iw zaledwie kilka minut wymieniłem dwa słoiki Logback na słoik SLF4J, który łączy go z implementacją JUL.

Tak jak @overthink, serdecznie polecam użycie SLF4J w twojej konfiguracji.


8
Ile razy Ceki musi wymyślać na nowo ramy / fasady logowania?
mP.

@mP: Rejestrowanie może nie być efektowne, ale jest kluczową potrzebą w przypadku oprogramowania komercyjnego na dużą skalę. Z kolei SLF4J rozwiązuje problem integracji kodu, który korzysta z odmiennych struktur rejestrowania (co stało się pilniejsze, gdy firma Sun zdecydowała się opracować java.utils.logging zamiast przyjąć Log4J).
Jim Ferrans

3
@mP, slf4j było konieczne, ponieważ Sun wykonał złą robotę z JUL. Logback to rozwidlenie log4j, a nie nowy projekt.
Thorbjørn Ravn Andersen

3
Zauważyłem, że logowanie jest konieczne, jeśli nie ma innego powodu, nie jest to Apache i jest faktycznie udokumentowane.
Spencer Kormos

13

Istnieje prostsza alternatywa dla połączenia JUL z log4j niż SLF4J, patrz http://people.apache.org/~psmith/logging.apache.org/sandbox/jul-log4j-bridge/examples.html

Wystarczy umieścić most jul-log4j-bridge w ścieżce klas i dodać właściwość systemową:

-Djava.util.logging.manager=org.apache.logging.julbridge.JULBridgeLogManager

jul-log4j-bridge nie znajduje się w Maven Central i można go pobrać z tego repozytorium:

<repository>
  <id>psmith</id>
  <url>http://people.apache.org/~psmith/logging.apache.org/repo</url>
  <releases>
    <enabled>false</enabled>
  </releases>
</repository>

a następnie używany z:

<dependency>
  <groupId>org.apache.logging</groupId>
  <artifactId>apache-jul-log4j-bridge</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>log4j</groupId>
      <artifactId>apache-log4j-component</artifactId>
    </exclusion>
  </exclusions>
</dependency>

Możliwe jest również odbudowanie go ze źródeł, wykonując następujące kroki:

  1. svn co http://svn.apache.org/repos/asf/logging/sandbox/jul-to-log4j-bridge/
  2. edytuj pom.xml, zamień zależność od log4j: log4j: 1.2.15 na log4j: apache-log4j-extras: 1.2.17 i usuń zależność od apache-log4j-component
  3. pakiet mvn

4
Myślę, że jest to prostsze, ponieważ można to zrobić bez zmiany kodu, wystarczy dodać właściwość systemową. SLF4J nie proponuje jeszcze podobnego mechanizmu, albo zmieniasz kod, albo logging.propertiesplik.
Emmanuel Bourg,

1
To nie istnieje w log4j2, niestety :(
BeepDog

JulLog4jBridge.assimilate();o_0
Bastian Voigt

2
OSTRZEŻENIE! jul-log4j-bridgeużywa nigdy nie wydanego apache-log4j-companionspakietu (backport z porzuconego log4j 1.3). Będzie ci ciężko go zbudować. Oczywiście sam most został również porzucony przed wydaniem.
ivan_pozdeev

@ivan_pozdeev Słuszna uwaga, dziękuję. Dodałem instrukcje, jak to zbudować.
Emmanuel Bourg

9

PAŹDZIERNIK 2014

Od wersji 2.1 log4j istnieje komponent log4j-jul, który dokładnie na to pozwala. Mimo to, jeśli używasz log4j 1, musi być możliwe uaktualnienie do log4j2, aby użyć tego podejścia.

Adapter rejestrowania JDK

Class LogManager

Migracja z log4j 1.x do log4j 2


2
Od teraz (połowa 2018 r.) Powinna to być akceptowana odpowiedź
rmuller

Dla przyszłych czytelników: Potwierdzam, że to działa. W zasadzie (1) dodaj to do swojego pom mvnrepository.com/artifact/org.apache.logging.log4j/log4j-jul i (2) dodaj właściwość systemową w pierwszym linku (np. W parametrach JVM dodaj -Djava. util.logging.manager = org.apache.logging.log4j.jul.LogManager)
Hossam El-Deen

3

Uważam, że witryna slf4j ma pomost do przekazywania zdarzeń java.util.logging przez slf4j (a tym samym do log4j).

Tak, plik do pobrania SLF4J zawiera jul-to-slf4j, co moim zdaniem robi właśnie to. Zawiera moduł obsługi JUL do przekazywania rekordów do SLF4J.


2

@Yishai - Dziękuję za umieszczenie linku do mojej wiki. Przykład tam przekierowuje JUL do Log4J i mam go uruchomionego w systemie produkcyjnym przez kilka lat. JBoss 5.x już przekierowuje JUL do Log4J, więc usunąłem go podczas aktualizacji. Mam nowszy, który przekierowuje do SLF4J, którego używam teraz w kilku rzeczach. Opublikuję to, kiedy będę miał okazję.

Jednak SLF4J już to ma:

http://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.