2017-09-18 3 views
0

시스템 로그와 사용자 로그를 분리하려고합니다. 시스템 로그는 개발자와 관리자가 볼 수 있습니다. 모든 기술적 세부 사항없이 시스템 정보를 사용자에게 제공하는 사용자 로그 다른 로그 메시지를 다른 파일에 저장하려고합니다. 하나는 기술자 용이고 다른 하나는 사용자 용입니다.다중 log4j2 로거 구성

나는 맞춤 레벨과 필터를 비롯한 다양한 옵션을 살펴 보았습니다. 필터가 사용자 메시지를 식별하는 데 사용할 수있는 메시지의 시작 부분에 키워드를 추가 할 수 있습니다. 표준 오류 수준을 사용하는 사용자 메시지 용으로 별도의 로거를 추가하는 방법을 실험하고 있습니다.

나는 테스트를 위해 간단한 데모 프로그램을 작성했습니다. 2 개의 로거를 작성한 다음 몇 가지 오류 메시지를 생성합니다. config 파일에서

package demo; 
import java.io.IOException; 
import org.apache.logging.log4j.Level; 
import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 

public class Logdemo { 
private final static Logger logger = LogManager.getLogger(); 
private final static Logger userLog = LogManager.getLogger("demo.userMsg"); 

public static void main(String[] args) throws IOException { 
    try { 
     ((Object) null).toString(); 
    } catch (Exception e) { 
     logger.error("error message", e); 
    } 
    try { 
     ((Object) null).toString(); 
    } catch (Exception e) { 
     logger.fatal("User level Red message" ,e); 
    } 
    try { 
     ((Object) null).toString(); 
    } catch (Exception e) { 
     userLog.error("User level Amber message" ,e); 
    } 
    logger.info("Errors Logged"); 
    userLog.info("Lunch is served."); 
    } 
} 

내가 가진이에서

<Loggers> 
     <Root level="all"> 
      <AppenderRef ref="RollingFile" level="ALL"/> 
      <AppenderRef ref="Console" level="ALL"/> 
     </Root> 
     <userMsg name="demo.userMsg" level = "all"> 
      <AppenderRef ref="UserMsgFile" level="ALL"/> 
     </userMsg> 
    </Loggers> 
</Configuration> 

I 얻을 넷빈즈에서 다음과 같은 오류 메시지 :

run: 
2017-09-18 22:20:13,933 main ERROR Error processing element UserMsgFile [Appenders: null]): CLASS_NOT_FOUND 
2017-09-18 22:20:13,936 main ERROR Error processing element userMsg ([Loggers: null]): CLASS_NOT_FOUND 
22:20:14.038 [main] INFO demo.Logdemo - logger starting... 
22:20:14.040 [main] ERROR demo.Logdemo - error message 

예외 메시지의 모든가 콘솔에 기록됩니다, userLog에 대한 메시지가 포함됩니다. 그래서 두 로거가 작동하고 있다는 것을 알고 있습니다. 로거 appender는 파일에 OK를 씁니다. 거의 동일한 appender를 사용하는 userLog 로거에 의해 생성 된 파일이 없습니다.

log4j2가 로거를 찾을 수 있도록 올바르게 이름을 지정하지 않은 것처럼 보입니다. 나는 그것을 얻기 위해 다양한 조합을 시도했지만 문제가 무엇인지 알 수 없다.

내가 아직 얻지 못한 또 다른 사항은 다른 클래스에서 userLog 로거를 사용하는 것입니다. 사용자 로그 메시지가 생성 된 클래스를 알 필요가 없으므로 모든 클래스에서 클래스 식별자없이 동일한 로거 이름을 사용하고 싶습니다. 나는 그것을 할 수 없다고 생각한다.

제 질문은 : 구성 파일에 어떤 오류가 있습니까?
편집 : 다음 구성 항목이 작동합니다. 이것은 두 개의 로거를 제공합니다. 두 가지 문제가있었습니다. 하나는 로거의 이름이 패키지 이름이라는 것입니다. 다른 하나는 Logger라는 단어를 올바르게 사용하지 않았다는 것입니다.

<Loggers> 
    <Logger name="demo" level="all"> <!-- name = package name --> 
     <AppenderRef ref="UserLogFile" level="ALL" /> 
    </Logger> 
    <Root level="all"> 
     <AppenderRef ref="Console" level="ALL"/> 
     <AppenderRef ref="SystemLogFile" level="ALL"/> 
    </Root> 
</Loggers> 

나는 각 클래스에서 로거 개시의 클래스 이름을 포함해야합니까?
편집 : 패키지 이름을 입력해야했습니다. 알아내는 데 시간이 좀 걸렸습니다.

다른 문제는 log4j2에 대한 디버그 메시지를 켜는 것이 었습니다. 이는 다음과 같이 구현됩니다.

<Configuration status="WARN"> <!-- to debug, set status="TRACE" --> 

답변

0

필자의 접근 방식을 변경했습니다. 추가 된 로거와 함께 마커 기능을 사용했습니다. 로그 메시지에 마커를 추가하면 다른 appender를 사용하여 사용자 메시지를 처리 ​​할 수 ​​있습니다. 샘플 코드는 다음과 같습니다

import java.io.IOException; 
import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 
import org.apache.logging.log4j.MarkerManager; 
import org.apache.logging.log4j.Marker; 

    public class Logdemo { 

    private final static Logger logger = LogManager.getLogger(); 
    static final Marker usrMkr = MarkerManager.getMarker("USR"); 

    public static void main(String[] args) throws IOException { 
     logger.info("logger starting..."); 

     try { 
      ((Object) null).toString(); 
     } catch (Exception e) { 
      logger.fatal(usrMkr,"User message"); 
     } 
     try { 
      ((Object) null).toString(); 
     } catch (Exception e) { 
      logger.debug("Debug error message" ,e); 
     } 
     logger.info("Errors Logged"); 
     } 
    } 

설정 파일의 관련 부분을 같이 다음 MarkerFilter 명령이 추가 된 내가 펜더를 만들어

 <RollingFile 
     name="UserLogFile" 
     fileName="${basePath}/UserMsg.log" 
     immediateFlush="false" 
     filePattern="logs/$${date:yyyy-MM}/user-%d{MM-dd-yyyy}-%i.log"> 
     <MarkerFilter marker="USR" onMatch="ACCEPT" onMismatch="DENY"/> 
    </RollingFile> 
</Appenders> 

<Loggers> 
    <Logger name="demo" level="all"> 
     <AppenderRef ref="UserLogFile" level="ALL"/> 
    </Logger> 
    <Root level="all"> 
     <AppenderRef ref="Console" level="ALL"/> 
     <AppenderRef ref="RollingFile" level="ALL"/> 

    </Root> 

</Loggers> 

. 로거가 appender에게 지적한 메시지를 별도의 파일로 돌리라고했습니다. 간결함을 위해 xml 파일의 큰 덩어리를 해킹했습니다.

+0

안녕하세요, 당신의 접근 방식 중 하나가 작동해야합니다. "로그 메시지에 마커를 추가하면 사용자 메시지를 처리하기 위해 다른 애펜더를 사용할 수 있습니다."하지만 마커없이이 작업을 수행 할 수 있습니다. 마커를 사용하지 않으면 여러 로거를 만들어야하기 때문에 마커로 올바른 길을 가고 있다고 생각합니다. –

+0

다른 한 가지 - "데모"로거가있는 유일한 이유는 "UserLogFile"할당자를 할당하는 것이고이 로거가 실제로 필요하지 않은 경우입니다. appender에 MarkerFilter가 있기 때문에 루트 로거에 할당 할 수 있으며 같은 방식으로 작동합니다. –

+0

안녕하세요. # D.B 로거 학습 곡선을 따라 가파른 오르막길을 올리신 후에도 (필자는 아직 먼 길을 가고 있습니다.) 필자가 작성한 코드는 그 일을합니다. 데모 로거가 필요하지 않다는 것을 알 수 있습니다.하지만 내가 가지고있는 것을 잊어 버렸을 때 2 년 후에 코드를 읽는 것이 더 쉬울 것입니다. – dazz