일부 이벤트를 로깅하고 추적 할 수 있도록 Java 프로젝트에 LoggingHandler 클래스를 추가했습니다. 이 클래스에서는 두 개의 서로 다른 log4j 로거 인스턴스를 사용합니다. 하나는 이벤트를 로깅하고 다른 하나는 이벤트를 다른 파일로 추적하는 인스턴스입니다. 클래스의 초기화 블록은 다음과 같습니다Log4j : 이벤트가 잘못된 로그 파일에 나타납니다.
public void initialize()
{
System.out.print("starting logging server ...");
// create logger instances
logLogger = Logger.getLogger("log");
traceLogger = Logger.getLogger("trace");
// create pattern layout
String conversionPattern = "%c{2} %d{ABSOLUTE} %r %p %m%n";
try
{
patternLayout = new PatternLayout();
patternLayout.setConversionPattern(conversionPattern);
}
catch (Exception e)
{
System.out.println("error: could not create logger layout pattern");
System.out.println(e);
System.exit(1);
}
// add pattern to file appender
try
{
logFileAppender = new FileAppender(patternLayout, logFilename, false);
traceFileAppender = new FileAppender(patternLayout, traceFilename, false);
}
catch (IOException e)
{
System.out.println("error: could not add logger layout pattern to corresponding appender");
System.out.println(e);
System.exit(1);
}
// add appenders to loggers
logLogger.addAppender(logFileAppender);
traceLogger.addAppender(traceFileAppender);
// set logger level
logLogger.setLevel(Level.INFO);
traceLogger.setLevel(Level.INFO);
// start logging server
loggingServer = new LoggingServer(logLogger, traceLogger, serverPort, this);
loggingServer.start();
System.out.println(" done");
}
은 단지 스레드가 동시에 각각의 기록에 로거 인스턴스의 기능을 사용하고 있는지 확인하려면/방법을 추적하는 것은 내부) (.INFO 로깅 메소드를 호출 동기 블록. 한 예는 다음과 같습니다.
public void logMessage(String message)
{
synchronized (logLogger)
{
if (logLogger.isInfoEnabled() && logFileAppender != null)
{
logLogger.info(instanceName + ": " + message);
}
}
}
로그 파일을 보면 잘못된 파일에 이벤트가 나타나는 경우가 있습니다. 한 가지 예 :
trace 10:41:30,773 11080 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1267093 to vehicle 1055293 (slaveControl 1)
trace 10:41:30,784 11091 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1156513 to vehicle 1105792 (slaveControl 1)
trace 10:41:30,796 11103 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1104306 to vehicle 1055293 (slaveControl 1)
trace 10:41:30,808 11115 INFO masterControl(192.168.2.21): vehicle 1327879 was pushed to slave control 1
10:41:30,808 11115 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1101572 to vehicle 106741 (slaveControl 1)
trace 10:41:30,820 11127 INFO masterControl(192.168.2.21): string broadcast message was pushed from 1055293 to vehicle 1104306 (slaveControl 1)
나는 문제가 매번 두 개의 이벤트가 동시에 발생 occures 생각 (현재 : 10 : 41 : 30,808). 아무도 내 문제를 해결하는 방법을 알고 있습니까?
logtrace 11:16:07,75511:16:07,755 1129711297 INFOINFO masterControl(192.168.2.21): string broadcast message was pushed from 1291400 to vehicle 1138272 (slaveControl 1)masterControl(192.168.2.21): vehicle 1333770 was added to slave control 1
또는
: ...BR,
마르쿠스
편집을 이미 메서드 호출 후 잠을()를 추가하려하지만 도움이되지 않습니다
log 11:16:08,562 12104 INFO 11:16:08,562 masterControl(192.168.2.21): string broadcast message was pushed from 117772 to vehicle 1217744 (slaveControl 1)
12104 정보 masterControl (192.168.2.21) : 차량 1169775가 슬레이브 컨트롤 1에 푸시되었습니다.
편집 2 : 로깅 방법은 RMI 스레드 내부에서 호출하는 경우 문제는 (내 클라이언트/서버 정보를 교환은 RMI 연결을 사용하여) 발생과 같은
보인다. ...
편집 3 :
은 나 자신에 의해 문제를 해결 : 그것은 완전히 스레드 저장 아닙니다의 log4j처럼 보인다. 별도의 객체를 사용하여 모든 로그/추적 메소드를 동기화 한 후에 모든 것이 잘 작동합니다. 어쩌면 lib 디렉토리에 파일을 쓰기 전에 스레드가 안전하지 않은 버퍼에 메시지를 쓰고 있습니까?
출력 스트림에서 appender를 의미하는 경우 appender는 threadsafe입니다. 'doAppend' 메소드는'동기화 됨 '입니다. –
fileAppeners에서 동기화 한 후에도 문제가 계속 발생합니다 (예제 위쪽 참조). 어쩌면 로거 인스턴스를 다른 스레드에 넣어야합니까? – Markus
아니요, 초기화 메소드에서 볼 수 있듯이 두 애 퍼더가 서로 다른 파일 (logFilename 및 traceFilename)에 바인딩되지만 동일한 patternLayout을 사용하고 있습니다. 일부 분 agao 나는 로깅/추적을 다른 스레드로 옮기려고했지만이 역시 도움이되지 못했습니다. – Markus