log4j가 자체 구성에 사용한 파일을 표시하도록 할 수 있습니까?


79

질문

Log4J가 구성에 사용한 파일의 전체 경로를 표시하도록 할 수 있습니까?


배경

나는 log4j와 애증 관계가 있습니다. 좋은시기에는 훌륭하지만 작동하지 않을 때는 디버깅하기 가장 어려운 일 중 하나가 될 수 있습니다. 애플리케이션의 모든 로깅을 관리합니다. 따라서 저는 매뉴얼에 정의 된 로깅과 기본 초기화 절차에 매우 익숙 합니다. 그래도 몇 주마다 로그 기록이 중단되고 문제를 해결 하는 데 많은 시간을 소비 하는 것 같습니다 .

이번에는 심하게 깨졌습니다. 모든 곳의 모든 로그 문이 콘솔에 덤프되고 이유를 알 수 없습니다. 지난주에 내 log4j.xml 파일을 사용한 것과 동일한 코드 기반이 갑자기 다른 구성을 사용하고 있습니다. 명백한 것은 변경되지 않았습니다. 내 유일한 추측은 몇 가지 종속성이 변경되었으며 Maven이 모든 것을 파괴하는 사악한 JAR을 다운로드했다고 의심합니다.

Log4J가 시작할 때 사용하기로 결정한 구성 파일을 알아낼 수만 있다면 이 문제와 대부분의 다른 문제를 쉽게 해결할 수 있습니다.


요약

Log4J에 구성에 사용 된 파일을 인쇄하도록 지시하는 방법이 있습니까? 또는 실행중인 응용 프로그램을 중단하고 디버거를 사용하여이 질문에 답할 수있는 방법이 있습니까 (식을 사용하거나 변수를 검사하여)?


1
배경이 다중 바인딩 문제처럼 들립니다. From slf4j.org/codes.html#multiple_bindings : SLF4J에서 내 보낸 경고는 바로 경고입니다. 여러 바인딩이있는 경우에도 SLF4J는 하나의 로깅 프레임 워크 / 구현을 선택하고 바인딩합니다. SLF4J가 바인딩을 선택하는 방식은 JVM에 의해 결정되며 모든 실제 목적을 위해 무작위로 간주되어야합니다.
— newur

답변:


82

예, log4j.debugJVM 시스템 변수에 추가 하기 만하면 됩니다. 예를 들면 :

java -Dlog4j.debug -cp ... some.class.name

Log4j는 다음과 같은 결과를 출력합니다.

log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@1f7182c1.  
log4j: Using URL [file:/C:/Users/matt/workspace/projectname/target/test-classes/log4j.xml] for automatic log4j configuration.  
log4j: Preferred configurator class: org.apache.log4j.xml.DOMConfigurator  
log4j: System property is :null  
log4j: Standard DocumentBuilderFactory search succeded.  
log4j: DocumentBuilderFactory is: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl  
log4j: debug attribute= "null".  
log4j: Ignoring debug attribute.  
log4j: reset attribute= "false".  
log4j: Threshold ="null".  
...

참고로 매뉴얼 과 FAQ 를 참조하십시오 .


6
어떤 이유로이 플래그를 설정해도 SLF4J를 사용하기 때문에 내 프로젝트에 영향을 미치지 않습니다. 이유를 알아 보려고했지만 마침내 수동으로 21 개의 구성 파일을 확인했습니다.)
— Line

2
log4j2에서 속성이 log4j2.debug로 변경되었으며 구성 파일을 찾는 데 문제를 디버깅하려는 경우 -Dorg.apache.logging.log4j.simplelog.StatusLogger.level = TRACE를 설정해야 할 수도 있습니다.
— user2163960

7

저는 Log4J2를 사용하고 있으며 Java 프로그램 내부에서 파일을 얻으려면 이것이 저에게 효과적이었습니다.

LoggerContext lContect = LogManager.getContext();
Field f = lContect.getClass().getDeclaredField("configuration");
f.setAccessible(true);
XmlConfiguration iWantThis = (XmlConfiguration) f.get(lContect);
System.out.println("Config File: " + iWantThis.getName());

1
한편으로는 이것은 정확히 내가 찾고 있던 것이었고 다른 한편으로는 출력에서 ​​구성 파일을 변경해도 효과가 없었습니다. 따라서 Log4J2가 실제로 사용되는지 정말 확실해야합니다. 여기 slf4j.org/codes.html#multiple_bindings에 설명 된대로 다중 바인딩 문제가 발생 했기 때문에 실제 로거는 slf4j-simple이었습니다.
— newur

또한 디버거를 사용하고 org.apache.logging.log4j.util.PropertiesUtil의 생성자에 중단 점을 설정했습니다. 여기에 log4j2.component.properties라는 파일이 있고로드됩니다. 첫 번째는 target / test-classes에서, 두 번째는 target / classes에서 두 번째 파일이로드되었고 후자의 속성은 첫 번째 파일에서 속성을 덮어 쓴다는 것을 발견했습니다.
— rychu

2

이에 상응하는 log4j 2 <Configuration status="trace">는 구성 파일에 설정됩니다. 그러면 log4j2 구성 파일이로드 된 위치와 log4j2 구성 프로세스의 기타 내부 세부 정보가 표시됩니다. 기본적으로 상태 로거 수준은 WARN이므로 문제가있는 경우에만 알림이 표시됩니다.

구성 파일을 올바르게 찾을 수없는 경우에도 시스템 속성 org.apache.logging.log4j.simplelog.StatusLogger.level을 로 설정하여 log4j2 내부 상태 로깅을 활성화 할 수 있습니다 TRACE.


5
그러나 사용중인 구성 값을 찾으려고하는 경우 활성 상태가 아닐 수있는 구성 값에 추가해도 아무 소용이 없습니다!
— Omaha
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.