java.util.logging을 사용하지 않는 이유는 무엇입니까?


351

내 인생에서 처음으로 오픈 소스가 될 Java API를 작성하는 위치에 있습니다. 많은 다른 프로젝트에 포함되기를 바랍니다.

로깅을 위해 (그리고 실제로 작업하는 사람들) 항상 JUL (java.util.logging)을 사용했으며 아무런 문제가 없었습니다. 그러나 이제 API 개발을 위해해야 ​​할 일을 더 자세하게 이해해야합니다. 나는 이것에 대해 약간의 연구를 해 왔으며 내가 얻은 정보로 더 혼란스러워합니다. 따라서이 게시물.

내가 JUL에서 왔기 때문에 나는 그것에 편견이 있습니다. 나머지에 대한 나의 지식은 그렇게 크지 않습니다.

내가 한 연구에서 사람들이 JUL을 좋아하지 않는 이유를 생각해 냈습니다.

  1. "Sun이 JUL을 출시하기 훨씬 전에 Java로 개발을 시작했으며 새로운 것을 배우기보다는 logging-framework-X를 계속 사용하는 것이 더 쉬웠습니다 . " 흠. 농담이 아니에요. 사람들이 실제로하는 말입니다. 이 논쟁으로 우리 모두는 COBOL을 할 수 있습니다. (그러나 나는 이것이 게으른 친구임을 분명히 말할 수있다)

  2. "JUL의 로깅 수준 이름이 마음에 들지 않습니다 . " 진지하게, 이것은 새로운 의존성을 도입할만한 이유가 충분하지 않습니다.

  3. "JUL의 표준 출력 형식이 마음에 들지 않습니다 . " 흠. 이것은 단지 구성입니다. 코드 단위로 아무것도 할 필요조차 없습니다. (사실 옛날에는 포맷터 클래스를 직접 만들어야했습니다.)

  4. "저는 logging-framework-X를 사용하는 다른 라이브러리를 사용하기 때문에 그 라이브러리를 사용하는 것이 더 쉽다고 생각했습니다 . " 이것은 원형의 주장이지 않습니까? 왜 '모두'가 JUL이 아닌 logging-framework-X를 사용합니까?

  5. "다른 사람이 logging-framework-X를 사용하고 있습니다" . 나에게 이것은 위의 특별한 경우입니다. 대다수가 항상 옳은 것은 아닙니다.

그래서 진짜 큰 질문은 왜 JUL이 아닌가? . 내가 놓친 것이 무엇입니까? 외관 로깅 (SLF4J, JCL)에 대한 단점은 역사적으로 여러 로깅 구현이 존재했으며 그 이유는 내가 볼 때 JUL 이전으로 거슬러 올라갑니다. 만약 JUL이 완벽했다면, 정면의 로깅은 존재하지 않습니까? 문제를 더 혼란스럽게 만드는 JUL은 어느 정도 파사드 자체이므로 처리기, 포맷터 및 심지어 LogManager를 바꿀 수 있습니다.

똑같은 일을하는 여러 가지 방법 (로깅)을 포용하는 대신, 왜 그들이 왜 필요한지 의심해서는 안 되는가? (그리고 그 이유가 여전히 존재하는지 확인하십시오)

좋아, 지금까지의 연구는 JUL과 관련 하여 실제로 문제 가 될 수있는 몇 가지 사실을 발견했다 .

  1. 성능 . 어떤 사람들은 SLF4J의 성능이 다른 것보다 우수하다고 말합니다. 이것은 나에게 조기 최적화의 경우 인 것 같습니다. 초당 수백 메가 바이트를 기록 해야하는 경우 어쨌든 올바른 경로에 있는지 잘 모르겠습니다. JUL도 발전했으며 Java 1.4에서 수행 한 테스트가 더 이상 사실이 아닐 수도 있습니다. 여기에서 읽을 수 있으며이 수정으로 Java 7로 변경되었습니다. 많은 사람들이 로깅 메소드에서 문자열 연결의 오버 헤드에 대해서도 이야기합니다. 그러나 템플리트 기반 로깅은이 비용을 피하며 JUL에도 존재합니다. 개인적으로는 템플릿 기반 로깅을 작성하지 않습니다. 너무 게으르다. 예를 들어 JUL로 이것을하면 :

    log.finest("Lookup request from username=" + username 
       + ", valueX=" + valueX
       + ", valueY=" + valueY));

    내 IDE가 경고하고 다음과 같이 변경해야한다는 권한을 요청합니다.

    log.log(Level.FINEST, "Lookup request from username={0}, valueX={1}, valueY={2}", 
       new Object[]{username, valueX, valueY});

    .. 물론 받아 들일 것입니다. 권한 부여! 도와 주셔서 감사합니다.

    따라서 실제로 그러한 진술을 직접 작성하지는 않습니다. IDE에서 수행합니다.

    성능 문제에 대한 결론에서 나는 JUL의 성능이 경쟁사에 비해 좋지 않다는 것을 암시하는 것을 찾지 못했습니다.

  2. 클래스 경로에서 구성 . 기본 JUL은 클래스 경로에서 구성 파일을로드 할 수 없습니다. 그렇게 하는 것은 몇 줄의 코드 입니다. 왜 이것이 귀찮은 지 알 수 있지만 해결책은 짧고 간단합니다.

  3. 출력 핸들러의 가용성 . JUL에는 콘솔, 파일 스트림, 소켓 및 메모리 등 5 가지 출력 핸들러가 기본 제공됩니다. 이것들은 확장되거나 새로운 것을 쓸 수 있습니다. 예를 들어, UNIX / Linux Syslog 및 Windows 이벤트 로그에 쓰는 중일 수 있습니다. 나는 개인적 으로이 요구 사항을 갖지 못했거나 사용 된 것을 보지 못했지만 그것이 왜 유용한 기능 일 수 있는지 분명히 알 수 있습니다. 로그 백에는 Syslog의 어 펜더가 포함되어 있습니다. 여전히 나는 그것을 주장 할 것이다

    1. 출력 대상에 대한 요구의 99.5 %는 기본적으로 JUL에 포함되어 있습니다.
    2. 특별한 요구 사항은 다른 것보다는 JUL 위의 사용자 지정 처리기에 의해 제공 될 수 있습니다. JUL 용 Syslog 출력 핸들러를 다른 로깅 프레임 워크보다 작성하는 데 시간이 더 걸린다는 제안은 없습니다.

내가 간과 한 것이 있다는 것이 정말 걱정입니다. JUL 이외의 로깅 파사드와 로깅 구현의 사용은 너무나 널리 퍼져 있으므로 이해하지 못하는 사람이 나라는 결론에 도달해야합니다. 처음이 아니에요, 두렵습니다. :-)

API로 무엇을해야합니까? 나는 그것이 성공하기를 원합니다. 물론 "흐름을 따라가"고 SLF4J (요즘 가장 인기있는 것)를 구현할 수는 있지만, 내 자신을 위해 오늘의 JUL에 무엇이 잘못되었는지 정확히 이해해야합니까? 내 라이브러리에 JUL을 선택하여 스스로 방해 할 수 있습니까?

테스트 성능

(2012 년 7 월 7 일에 nolan600에 의해 추가 된 섹션)

Ceki에서 SLF4J의 매개 변수화가 JUL보다 10 배 이상 빠르다는 내용이 아래에 나와 있습니다. 그래서 간단한 테스트를 시작했습니다. 언뜻보기에 주장은 정확합니다. 예비 결과는 다음과 같습니다 (그러나 계속 읽어보십시오!).

  • 실행 시간 SLF4J, 백엔드 로그 백 : 1515
  • 실행 시간 SLF4J, 백엔드 JUL : 12938
  • 실행 시간 JUL : 16911

위의 숫자는 msec이므로 적을수록 좋습니다. 따라서 성능 차이의 10 배는 실제로는 실제로 거의 비슷합니다. 내 초기 반응 : 그것은 많이입니다!

테스트의 핵심은 다음과 같습니다. 알 수 있듯이 정수와 문자열은 루프로 해석되어 로그 문에 사용됩니다.

    for (int i = 0; i < noOfExecutions; i++) {
        for (char x=32; x<88; x++) {
            String someString = Character.toString(x);
            // here we log 
        }
    }

(로그 진술에 기본 데이터 유형 (이 경우 int)과 더 복잡한 데이터 유형 (이 경우 String)이 필요했습니다. 확실하지 않지만 거기에 있습니다.)

SLF4J에 대한 로그 설명 :

logger.info("Logging {} and {} ", i, someString);

JUL에 대한 로그 설명 :

logger.log(Level.INFO, "Logging {0} and {1}", new Object[]{i, someString});

실제 측정을 수행하기 전에 동일한 테스트를 한 번 실행하여 JVM이 '워밍업'되었습니다. Java 1.7.03은 Windows 7에서 사용되었습니다. 최신 버전의 SLF4J (v1.6.6) 및 Logback (v1.0.6)이 사용되었습니다. Stdout 및 stderr이 널 장치로 경로 재 지정되었습니다.

그러나 JUL은 getSourceClassName()기본적으로 소스 클래스 이름을 출력에 출력하지만 Logback은 출력하지 않기 때문에 JUL이 대부분의 시간을 소비하고 있음을 조심 하십시오. 우리는 사과와 오렌지를 비교하고 있습니다. 테스트를 다시 수행하고 로깅 구현을 비슷한 방식으로 구성하여 실제로 동일한 내용을 출력해야합니다. 그러나 SLF4J + Logback은 여전히 ​​위에 나와 있지만 초기 숫자와는 거리가 멀다고 생각합니다. 계속 지켜봐 주시기 바랍니다.

Btw : 테스트는 실제로 SLF4J 또는 Logback으로 작업 한 것이 처음입니다. 즐거운 경험. JUL은 시작할 때 훨씬 덜 환영합니다.

테스트 성능 (2 부)

(2012 년 7 월 8 일에 nolan600에 의해 추가 된 섹션)

JUL에서 패턴을 구성하는 방법, 즉 소스 이름 포함 여부에 관계없이 성능에는 문제가되지 않습니다. 나는 매우 간단한 패턴으로 시도했다.

java.util.logging.SimpleFormatter.format="%4$s: %5$s [%1$tc]%n"

그리고 그것은 위의 타이밍을 전혀 바꾸지 않았습니다. 내 프로파일 러는 로거 getSourceClassName()가 내 패턴의 일부가 아니더라도 호출에 많은 시간을 보냈다고 밝혔다 . 패턴은 중요하지 않습니다.

따라서 테스트 된 템플릿 기반 로그 문에 대해 JUL (느린)과 SLF4J + 로그 백 (빠른)의 실제 성능 차이에 대략 10의 요인이있는 것으로 보이는 성능 문제에 대해 결론을 내 렸습니다. Ceki가 말한 것처럼.

또한 SLF4J의 getLogger()통화가 JUL의 통화보다 훨씬 비싸다는 또 다른 것을 볼 수 있습니다 . (내 프로파일 러가 정확하면 95ms 대 0.3ms). 이것은 말이됩니다. SLF4J는 기본 로깅 구현의 바인딩에 약간의 시간을 할애해야합니다. 이것은 나를 두려워하지 않습니다. 이러한 호출은 응용 프로그램 수명 동안 다소 드 물어야합니다. 견뢰도는 실제 로그 호출에 있어야합니다.

최종 결론

(2012 년 7 월 8 일에 nolan600에 의해 추가 된 섹션)

모든 답변에 감사드립니다. 처음에 생각했던 것과는 달리 API에 SLF4J를 사용하기로 결정했습니다. 이것은 많은 것들과 당신의 입력을 기반으로합니다 :

  1. 배포시 로그 구현을 유연하게 선택할 수 있습니다.

  2. 응용 프로그램 서버 내에서 실행될 때 JUL 구성의 유연성이 부족한 문제

  3. SLF4J는 Logback과 결합하면 특히 위에서 설명한 것처럼 훨씬 빠릅니다. 이것이 거친 테스트 일지라도 JUL보다 SLF4J + Logback에서 훨씬 많은 노력이 최적화되었다고 생각할 이유가 있습니다.

  4. 선적 서류 비치. SLF4J에 대한 문서는 훨씬 포괄적이고 정확합니다.

  5. 패턴 유연성. 테스트를 수행하면서 JUL이 Logback의 기본 패턴을 모방하도록 설정했습니다. 이 패턴에는 스레드 이름이 포함됩니다. JUL 은이 작업을 즉시 수행 할 수 없습니다. 좋아, 나는 지금까지 그것을 놓치지 않았다. 그러나 나는 그것이 로그 프레임 워크에서 없어야한다고 생각하지 않는다. 기간!

  6. 오늘날 대부분의 (또는 많은) Java 프로젝트는 Maven을 사용하므로 종속성을 추가하는 것이 특히 그 종속성이 다소 안정적인 경우, 즉 API를 지속적으로 변경하지 않는 경우 큰 문제는 아닙니다. 이것은 SLF4J에 해당되는 것 같습니다. 또한 SLF4J 항아리와 친구는 크기가 작습니다.

그래서 이상한 일이 실제로 SLF4J와 조금 일한 후 JUL에 대해 화가 났었습니다. JUL과 함께 해야하는 것이 여전히 유감입니다. JUL은 완벽하지는 않지만 그 일을합니다. 충분하지 않습니다. Properties예를 들어 똑같이 말할 수는 있지만 사람들이 자신의 구성 라이브러리에 플러그인 할 수 있다고 추상화하지는 않습니다. 나는 그 이유가 Properties바로 막대 바로 위에 오는 반면 오늘 JUL의 반대는 사실 이라고 생각합니다 ... 그리고 과거에는 존재하지 않았기 때문에 0에 도달했습니다.


8
이 잘 제시된 질문이 흥미로워 서 닫히지 않을 것입니다. 그러나 FAQ를 읽으면 경계가됩니다.
거부 거부 Séguret

당신이 놓친 것은 많은 프레임 워크 작성자가 JUL 사용을 포기했기 때문에 바닐라 자바를 만들지 않으면 사용하기가 종종 어렵다는 것입니다.
Denys Séguret

3
jul 이전의 일반적인 로깅 프레임 워크를 언급 할 때 "logging-framework-X"라는 일반적인 용어를 사용하는 것은 잘못된 것입니다. 이 경우 "log4j"를 사용해야합니다. SLF4J 및 로그 백과 같은 다른 인기있는 프레임 워크는 jul이 출시 된 후 잘 나왔습니다.
Ceki

1
아쿠아 리안 Netty 프로젝트는 Reflection을 사용하여 클래스 경로에서 사용할 수있는 로깅 프레임 워크를 테스트합니다. 출처는 여기 를 참조 하십시오 . 참조하십시오 InternalLoggerFactory.java.
peterh

1
@xenoterracide 더 중요한은 소개로, 자바 (9)에 대한 업데이트 될 java.lang.System.Logger인터페이스를 그 프레임 워크가 잡은 그 인터페이스의 구현을 제공 한, 당신이 원하는 실제 어떤 로깅 프레임 워크로 리디렉션 할 수 있습니다. 모듈화와 결합 java.util.logging하여 다른 프레임 워크를 선호하는 경우 번들 JRE를 포함하지 않는 번들로 애플리케이션을 배포 할 수도 있습니다.
Holger

답변:


207

면책 조항 : 저는 log4j, SLF4J 및 logback 프로젝트의 창립자입니다.

SLF4J를 선호하는 객관적인 이유가 있습니다. 우선 SLF4J를 사용하면 최종 사용자가 기본 로깅 프레임 워크를 선택할 수 있습니다 . 또한 숙련 된 사용자는 jul이 뒤쳐져 log4j 이외의 기능을 제공 하는 로그 백 을 선호하는 경향이 있습니다. 기능별 jul은 일부 사용자에게는 충분할 수 있지만 다른 사용자에게는 충분하지 않습니다. 간단히 말해서, 로깅이 중요한 경우 SLF4J를 기본 구현으로 로그 백과 함께 사용하려고합니다. 로깅이 중요하지 않으면 jul이 좋습니다.

그러나 OS 개발자는 자신 만이 아니라 사용자의 선호도를 고려해야합니다. 이 때문에하지 SLF4J을 채택해야 다음 당신은 SLF4J 더 7월 이상하지만 것을 확신 현재 대부분의 자바 개발자 (2012 년 7 월) 자신의 로깅 API로 SLF4J를 선호하기 때문이다. 궁극적으로 대중 의견에 신경 쓰지 않기로 결정한 경우 다음 사실을 고려하십시오.

  1. jul을 선호하는 사람들은 jul이 JDK와 번들로 제공되므로 편리하지 않습니다. 내 지식으로는 줄을 찬성하는 다른 객관적인 주장은 없다
  2. jul에 대한 당신의 선호는 바로 그 선호 입니다.

따라서, 용감한 것 같지만 여론보다 "고단 사실"을 유지하는 것은이 경우 논리적 오류입니다.

여전히 확신이 없다면 JB Nizet 는 추가적이고 강력한 논쟁을합니다.

최종 사용자는 자신의 코드 또는 log4j 또는 logback을 사용하는 다른 라이브러리에 대해이 사용자 정의를 이미 수행했을 수 있습니다. jul은 확장 가능하지만 로그 백, jul, log4j를 확장해야하며 하나님은 다른 로깅 프레임 워크를 사용하는 것은 4 개의 서로 다른 로깅 프레임 워크를 사용하는 4 개의 라이브러리를 사용하기 때문에 번거 롭습니다. SLF4J를 사용하면 선택한 프레임 워크가 아닌 원하는 로깅 프레임 워크를 구성 할 수 있습니다. 전형적인 프로젝트는 당신뿐만 아니라 수많은 라이브러리를 사용한다는 것을 기억하십시오 .

어떤 이유로 든 SLF4J API를 싫어하고 그것을 사용하여 작업에서 재미를 빼앗는다면 반드시 jul을 찾으십시오. 결국 jul을 SLF4J리디렉션 하는 수단이 있습니다 .

그런데 jul 매개 변수화는 SLF4J보다 적어도 10 배 느리므로 눈에 띄는 차이가 있습니다.


2
@Ceki 당신은 면책 조항을 조금 자세히 설명하여 log4j, slf4j 및 logback 프로젝트에서의 현재 역할을 언급 할 수 있습니다. 그 이유는 자연스럽게 편견을 설명하는 것입니다.
Thorbjørn Ravn Andersen

2
대부분의 Java 개발자가 SLF4J를 로깅 API로 선호한다는 주장에 대한 지원이 있습니까?
Olivier Cailloux

3
내 게시물의 핵심은 다른 개발자가 다른 환경 설정을 가지고 있으며 이는 논쟁의 여지가없는 것 같습니다. 예?
Ceki

1
솔직히 Java 11 (또는 결과적으로 무엇이든지)과 비동기 모드의 log4j2에 대한 2018 벤치 마크를보고 싶습니다.
xenoterracide 2016 년

5
여기에 내가 SLF4J를 사용하여, 나는, 나는 여전히 다른 라이브러리를 사용하는 모든 다른 로깅 프레임 워크를 처리해야합니다. SLF4J를 사용한다고해서 이기종 로거의 문제점을 해결할 수는 없으며 악화시킬뿐입니다. xkcd.com/927
Charlie

34
  1. java.util.loggingJava 1.4에 도입되었습니다. 그 전에 로깅에 대한 사용이 있었기 때문에 다른 많은 로깅 API가 존재합니다. Java 1.4 이전에 많이 사용 된 API는 1.4가 출시되었을 때 0으로 떨어지지 않은 시장 점유율을 보였습니다.

  2. JUL은 1.4에서 훨씬 더 나쁘고 1.5에서만 나아진 곳에서 언급 한 많은 것을 시작하지 않았습니다 (6도 추측하지만 너무 확실하지는 않습니다).

  3. JUL은 동일한 JVM에서 서로 다른 구성을 가진 여러 응용 프로그램에 적합하지 않습니다 (상호 작용하지 않아야하는 여러 웹 응용 프로그램 생각). Tomcat은 그 일을하기 위해 몇 가지 농구를 뛰어 넘어야합니다 (정확하게 이해하면 효과적으로 JUL을 다시 구현).

  4. 라이브러리가 사용하는 로깅 프레임 워크에 항상 영향을 줄 수는 없습니다. 따라서 SLF4J (실제로 다른 라이브러리보다 매우 얇은 API 레이어)를 사용하면 전체 로깅 세계에 대해 다소 일관된 그림을 유지할 수 있습니다 (따라서 동일한 시스템에서 라이브러리 로깅을 유지하면서 기본 로깅 프레임 워크를 결정할 수 있음).

  5. 라이브러리는 쉽게 변경할 수 없습니다. logging-library-X를 사용하는 데 사용 된 이전 버전의 라이브러리 인 경우 logging-library-Y (예 : JUL)로 쉽게 전환 할 수 없습니다. 새로운 로깅 프레임 워크와 (적어도) 로깅을 재구성합니다. 그것은 대부분의 사람들에게 명백한 이익을 가져 오지 않을 때 특히 그렇습니다.

나는 7 월이 생각하는 모든 것을 미루어 보아 적어도 다른 로깅 프레임 워크 이러한 일에 대한 유효한 대안.


1
감사합니다 Joachim, 귀하의 게시물에 감사드립니다. 당신의 (1)과 (2)는 저에게 단지 역사입니다. 옛날에. 귀하의 (4)는 그 결과이며 주기적 순환 주장이라고 부릅니다. 그러나 귀하의 (3)은 정말 흥미 롭습니다. 어쩌면 당신은 뭔가에 있습니까? 그러나 이것은 하루가 거의 끝나지 않는 응용 프로그램 컨테이너를 만드는 사람들에게만 영향을 미칩니다. 또는 무엇을?
peterh

3
글쎄, 역사를 무시하는 사람은 그것을 반복 할 운명이다 ;-) 역사는 소프트웨어 개발과 매우 관련이있다. 사람들은 너무 빨리 움직이지 않으며 기존의 타사 라이브러리를 표준 API로 교체 하면 표준 API 가 적어도 타사 라이브러리만큼 잘 작동하는 경우 에만 잘 작동합니다 . 그리고 그들은 처음에는 없었습니다 (그리고 어떤 경우에는 여전히 그렇지 않습니다).
Joachim Sauer

Joachim, 나는 당신이 언급 한 "어쩌면 여전히 어떤 경우에는 그렇지 않다"는 것에 관심이 있습니다. 그 고기가 있어야했습니다. 기존 코드에서 로거 라이브러리를 교체하는 것은 쉽지 않으며 요즘 자동화 할 수 있습니다. SLF4J는 내 요지를 입증하는 도구를 가지고 있습니다. 그래서 2002 년 log4j로 작성된 대규모 라이브러리는 자동화 도구를 사용하여 몇 분 만에 JUL로 변환 될 수 있다고 생각합니다. (하지만 존재하는지 모르겠습니다). 왜 그렇게되지 않습니까?
peterh

3
@ nolan6000 : 나는 그 문구에 대한 세부 사항으로 들어갈 구체적인 내용에 대해 충분히 알지 못하며 실제로 내가하고있는 요점이 아닙니다. JUL이 이제 타사 프레임 워크와 동등하더라도 관성과 기존 인프라는 여전히 전환하지 않는 강력한 이유입니다. 예를 들어, 라이브러리 X가 버전 1.1에서 slf4j를 사용하는 경우 1.2 (또는 2.0)에서 JUL로 전환하는 것은 많은 사용자 (이전 시스템을 올바르게 구성했으며 명백한 이득없이이를 다시 수행해야 함)의 주요 문제점이됩니다. .
Joachim Sauer

경우에도 @ nolan6000 당신이 역사에 대해 걱정하지 마십시오 라이브러리 는 응용 프로그램에서 사용하는 가장 확실 할. 단순히 다른 로깅 프레임 워크를 사용했기 때문에 라이브러리를 버릴 필요가 없습니다.
Thorbjørn Ravn Andersen

29

slf4j와 같은 로깅 파사드를 사용할 때의 주요 이점은 라이브러리의 최종 사용자가 최종 사용자에게 선택을 강요하기보다는 원하는 구체적인 로깅 구현을 선택할 수 있다는 것입니다.

어쩌면 그는 Log4j 또는 LogBack (특수 포맷터, 어 펜더 등)에 시간과 돈을 투자했으며 jul을 구성하는 대신 Log4j 또는 LogBack을 계속 사용하는 것을 선호합니다. 문제 없습니다 : slf4j가 허용합니다. Jul보다 Log4j를 사용하는 것이 현명한 선택입니까? 그럴 수도 있고 아닐 수도 있고. 그러나 당신은 상관하지 않습니다. 최종 사용자가 원하는 것을 선택하게하십시오.


감사합니다 JB. 내 질문은 내가 JUL을 강제로 강요하여 내 라이브러리의 사용자 / 구현 자에게 그 정도를 실제로 부과하는 것입니까? 예를 들어 JUL의 표준 출력 핸들러에 만족하지 않으면 배치 시간에 내가 볼 수 있듯이 자체 출력 핸들러를 교체 할 수 있습니다. 나는 JUL을 해협으로 보지 않습니다. 다른 사람들처럼 유연하고 확장 가능한 것 같습니다.
peterh

12
최종 사용자는 자신의 코드 또는 log4j 또는 LogBack을 사용하는 다른 라이브러리에 대해이 사용자 정의를 이미 수행했을 수 있습니다. jul은 확장 가능하지만 LogBack, jul, log4j를 확장해야하며 하나님은 4 개의 서로 다른 로깅 프레임 워크를 사용하는 4 개의 라이브러리를 사용하기 때문에 다른 로깅 프레임 워크 만 알고 있습니다. slf4j를 사용하면 원하는 로깅 프레임 워크를 구성 할 수 있습니다. 당신이 선택한 것이 아닙니다. 전형적인 프로젝트는 당신 만이 아니라 수많은 라이브러리를 사용한다는 것을 기억하십시오.
JB 니 제트

6

JUL을 사용하는 것이 가장 쉬운 방법 이었기 때문에 JUL을 사용하기 시작했습니다. 그러나 지난 몇 년 동안, 나는 조금 더 많은 시간을 보냈 으면 좋겠다.

내 주요 문제는 이제 많은 응용 프로그램에서 사용되는 상당한 양의 '라이브러리'코드가 있으며 모두 JUL을 사용한다는 것입니다. 웹 서비스 유형 앱에서 이러한 도구를 사용할 때마다 로깅이 사라지거나 예측할 수 없거나 이상한 곳으로갑니다.

우리의 해결책은 라이브러리 로그 호출이 변경되지 않았지만 사용 가능한 로깅 메커니즘으로 동적으로 리디렉션되는 라이브러리 코드에 외관을 추가하는 것이 었습니다. POJO 도구에 포함되면 JUL로 연결되지만 웹 응용 프로그램으로 배포되면 LogBack으로 리디렉션됩니다.

우리의 후회는 물론 라이브러리 코드가 매개 변수화 된 로깅을 사용하지 않지만 이제 필요할 때마다 개장 할 수 있다는 것입니다.

우리는 slf4j를 사용하여 정면을 만들었습니다.


1
slf4j 배포에서 "redirect java.util.logging to slf4j"패키지를 사용하지 않은 이유는 무엇입니까?
Thorbjørn Ravn Andersen

2
slf4j로 전환 할 때의 주요 이점은 효율적인 매개 변수화 된 로깅이기 때문에 가치가 거의 없습니다. 처음부터 사용했다면 지금해야 할 일이 없었을 것입니다.
OldCurmudgeon

1
나는 이것이 slf4j의 낮은 교수형 과일이라는 것에 동의합니다.
Thorbjørn Ravn Andersen

3

logback-1.1.7을 통해 slf4j-1.7.21에 대해 jul을 실행하고 SSD, Java 1.8, Win64로 출력

jul은 1M 루프에 대해 48449ms, 로그 백 27185ms를 실행했습니다.

여전히 조금 더 빠른 속도와 조금 더 멋진 API는 3 개의 라이브러리와 800K의 가치가 없습니다.

package log;

import java.util.logging.Level;
import java.util.logging.Logger;

public class LogJUL
{
    final static Logger logger = Logger.getLogger(LogJUL.class.getSimpleName());

    public static void main(String[] args) 
    {
        int N = 1024*1024;

        long l = System.currentTimeMillis();

        for (int i = 0; i < N; i++)
        {
            Long lc = System.currentTimeMillis();

            Object[] o = { lc };

            logger.log(Level.INFO,"Epoch time {0}", o);
        }

        l = System.currentTimeMillis() - l;

        System.out.printf("time (ms) %d%n", l);
    }
}

package log;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogSLF
{
    static Logger logger = LoggerFactory.getLogger(LogSLF.class);


    public static void main(String[] args) 
    {
        int N = 1024*1024;

        long l = System.currentTimeMillis();

        for (int i = 0; i < N; i++)
        {
            Long lc = System.currentTimeMillis();

            logger.info("Epoch time {}", lc);
        }

        l = System.currentTimeMillis() - l;

        System.out.printf("time (ms) %d%n", l);
    }

}

2
당신은 같은 것을 비교하지 않습니다. 왜 jul에 대한 배열을 명시 적으로 작성합니까? slf4j에 인수가 하나 인 인수가 부족하기 때문입니다 logger.info(). 따라서 slf4j 인터페이스의 단점을 보완하기 위해 의도적으로 jul 성능을 저하시킵니다. 대신 두 가지 방법 모두 관용적으로 코딩되는 방식으로 코딩해야합니다.
Klitos Kyriacou

2
당신은 그것을 오해했다. 추가 800K를 사용할 필요가 없습니다. 합의는 매우 얇은 SLF4J API를 사용할 가치 가 있다는 것입니다. 따라서 당신 (또는 언젠가 코드를 재사용하는 다른 사람들)이 JUL, Logback, Log4j 등을 자유롭게 전환 할 수 있기 때문입니다. SLF4J는 ~ 28K에 불과합니다. SLF4J-JUL 브릿지 (slf4j-jdk ... jar)는 ~ 9K입니다.
riskop
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.