2011-03-28 4 views
1

최근 로깅 수준에 따라 로그 파일을 추가하기 위해 JUL (java.util.Logging)에서 Log4J로 전환했습니다.프로그램 실행 중 Log4J 로그 파일의 이름 바꾸기

우리는 선택적으로 값과 날짜/시간 스탬프를 로그 파일 이름에 (모든 의도와 목적으로) 프로그램 실행의 끝에 추가 할 수있는 옵션을 가지고 있습니다.

JUL은 파일을 쓸 때 필요에 따라 파일을 열었다가 닫은 것처럼 보였으므로 잠금되지 않았으므로 간단히 .renameTo()를 사용하여 파일 이름을 변경할 수 있습니다.

이제 Log4J를 사용하면 해당 파일이 열리고 잠겨있어서 파일 이름을 바꿀 수 없습니다.

로깅을 구성하기 전에 파일 이름을 결정할 수 없습니다. 로깅을 필요로 한 후에 이름 바꾸기 옵션이 포함 된 속성 파일이 잠시 동안 남아 있기 때문에 (프로그램 끝 부분에서 파일 이름이 변경된 이유입니다) .

달성 방법에 대한 의견이 있으십니까?

Logback 및/또는 SLF4J가 도움이 되나요?


나는 종류의 속성 파일을 다시로드 한 후, 프로퍼티 파일의 log4j의 시스템 매개 변수를 사용하여 속성을 설정하고하여 문제를 해결 일했다.

이렇게하면 실행이 끝난 후 로그 파일의 이름을 다른 것으로 변경 한 다음 이전 파일의 이름을 바꿀 수 있습니다.

멋지고 대단히 고약한 것이므로 실행 후 임시 파일을 남기면서이를 피하고 싶습니다.

답변

2

한 가지 확실한 방법은 아마도 자신의 log4j를 구현하는이 appender 것 FileAppender (http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/FileAppender.html)를 기반으로합니다. 고유 한 특수 API를 추가하여 파일 이름을 변경하도록 요청하십시오.

나는 아직 시도하지 않은,하지만 난 것이다 걸릴 것 택트는 기본 API의 setFile (...)를 사용하는 예를 들면 다음과 같습니다 http://www.jdocs.com/log4j/1.2.13/org/apache/log4j/FileAppender.html#M-setFile%28String,boolean,boolean,int%29

: 포인터에 대한

public class RenamingFileAppender extends FileAppender { 

... 

/** fix concurrency issue in stock implementation **/ 
public synchronized void setFile(String file) { 
    super.setFile(file); 
} 

public synchronized void renameFile(String newName) { 
    // whole method is synchronized to avoid losing log messages 
    // implementation can be smarter in having a short term queue 
    // for any messages that arrive while file is being renamed 
    File currentFile = new File(this.fileName); 
    File newFile = new File(newName); 
    // do checks to ensure current file exists, can be renamed etc. 
    ... 
    // create a temp file to use while current log gets renamed 
    File tempFile = File.createTempFile("renaming-appender", ".log"); 
    tempFile.deleteOnExit(); 
    // tell underlying impl to use temporary file, so current file is flushed and closed 
    super.setFile(tempFile.getAbsolutePath(), false, this.bufferedIO, this.bufferSize); 
    // rename the recently closed file 
    currentFile.renameTo(newFile); 
    // now go back to the original log contents under the new name. Note append=true 
    super.setFile(newFile.getAbsolutePath(), true, this.bufferedIO, this.bufferSize); 
} 
+0

고마워, 나는 이것을 살펴볼 것이다. 그러나 내가 위에서 말했듯이, 파일의 이름을 바꾸지 않으면 문제를 실제로 도울 수 없다. – Omertron

+0

@Omertron, 나는 내가 상상하고있는 것을 보여주기 위해 편집했다 ... –

+0

고맙다. 내가 원했던 것, 그리고 나의 열등한 노력보다 훨씬 더 우아하다. :) – Omertron