2013-05-24 1 views
2

롤링 파일이 로그에 어떻게 구현되는지 궁금합니다.롤링 파일 구현

파일 크기를 초과하지 않도록 모든 언어로 파일 쓰기 클래스를 만드는 방법부터 시작합니다. 내가 생각할 수있는

가능한 유일한 해결책은 이것이다 :

write method: 
    size = file size + size of string to write 
    if(size > limit) 
     close the file writer 
     open file reader 
     read the file 
     close file reader 
     open file writer (clears the whole file) 
     remove the size from the beginning to accommodate for new string to write 
     write the new truncated string 
    write the string we received 

이 끔찍한 구현 것 같아,하지만 난 더 나은 아무것도까지 생각할 수 없다.

특히 자바에서 해결책을보고 싶습니다.

EDIT : 처음부터 크기를 제거하면 20 바이트 문자열 (한도)이 있고 다른 3 바이트 문자열을 쓰고 싶기 때문에 처음부터 3 바이트를 제거하고 끝 17 바이트, 그리고 새 문자열을 추가하여 20 바이트 있습니다.

+1

로깅 프레임 워크에서 롤오버 수행에 대한 정책이 다르기 때문에 조금 더 복잡합니다. 예를 들어'logback'을위한 소스 코드를 다운로드하고'RollingFileAppender'와'FixedWindowRollingPolicy' 클래스, 특히'rollover()'메소드를보십시오. –

+0

감사합니다. 흥미 롭습니다.하지만 예를 들어 단순히 PrintWriter를 확장하는 무언가를 만들고 싶다면 가능한 한 간단하고 우아하게 만들고 싶습니다. – Quillion

+1

게시 한 내용에는 요점이 있지만 처음부터 크기를 _ 제거하면 무엇을 의미합니까? –

답변

2

질문에 대한 조사를 위해 logback 로깅 프레임 워크의 예가 있습니다. RollingfileAppender#rollover() 방법은 다음과 같습니다

public void rollover() { 
    synchronized (lock) { 
     // Note: This method needs to be synchronized because it needs exclusive 
     // access while it closes and then re-opens the target file. 
     // 
     // make sure to close the hereto active log file! Renaming under windows 
     // does not work for open files 
     this.closeOutputStream(); 

     try { 
      rollingPolicy.rollover(); // this actually does the renaming of files 
     } catch (RolloverFailure rf) { 
      addWarn("RolloverFailure occurred. Deferring roll-over."); 
      // we failed to roll-over, let us not truncate and risk data loss 
      this.append = true; 
     } 

     try { 
      // update the currentlyActiveFile   
      currentlyActiveFile = new File(rollingPolicy.getActiveFileName()); 

      // This will also close the file. This is OK since multiple 
      // close operations are safe. 
      // COMMENT MINE this also sets the new OutputStream for the new file 
      this.openFile(rollingPolicy.getActiveFileName()); 
     } catch (IOException e) { 
      addError("setFile(" + fileName + ", false) call failed.", e); 
     } 
    } 
} 

당신이 볼 수 있듯이, 논리 당신이 무엇을 게시 꽤 유사하다. 현재 OutputStream을 닫고 롤오버를 수행 한 다음 새 것을 엽니 다 (openFile()). 많은 스레드가 로거를 사용하기 때문에 분명히이 작업은 모두 synchronized 블록에서 수행되지만 한 번에 하나의 롤오버 만 ​​발생해야합니다.

RollingPolicy은 롤오버 수행 방법에 대한 정책으로 TriggeringPolicy은 롤오버 수행시기입니다. logback을 사용하면 대개 이러한 정책을 파일 크기 또는 시간에 기초합니다.

+0

그게 끔찍하게 비효율적 인 것 같니? 모든 로깅 사물에서 사용합니까? 하천을 열고 닫는 데는 비용이 많이 들고 천장에 부딪치게되면 너무 자주 들립니다. – Quillion

+1

하나의 스트림을 닫으시겠습니까? 아니 정말. 당연히, 트리거 정책을 설정하지 않아 매 초마다 새 파일을 열 수 있습니다 (가능한 경우에도). 이것이 로깅 프레임 워크가하는 일입니다. 파일에 쓰려면 스트림을 열어야합니다. 따라서 롤링 구현을 수행하는 경우이를 수행 할 필요가 없습니다. –

+2

나는 그것이 종종 산발적 인 작동으로 비효율적이라고 생각하지 않는다. 로그에 대해 구체적으로 말하면 너무 자주 발생하면 로그에 너무 많은 정보를 보내거나 로그 크기가 너무 작아 질 수 있습니다. – jambriz