2010-07-22 6 views
1

여기에 거래가 있습니다. 다중 프로세스 시스템 (사전 포크 모델, Apache와 유사)이 있습니다. 모든 프로세스가 동일한 로그 파일에 기록합니다 (실제로 요청 및 응답을 기록하는 바이너리 로그 파일이지만 상관 없습니다).다시 시작하지 않고 순환하는 로그, 다중 프로세스 문제

나는 공유 메모리 잠금을 통해 로그에 대한 동시 액세스로부터 보호하고, 파일이 특정 크기를 처음으로 로그를 롤 통지하는 과정에 도달했을 때 : 파일을 닫는

  1. 합니다.
  2. log.bin -> log.bin.1, log.bin.1 -> log.bin.2 등의 이름을 바꿉니다.
  3. 최대 허용 로그 수를 초과하는 로그를 삭제합니다. (예를 들어, log.bin.10)
  4. 여는 새로운 log.bin 파일

문제는 다른 프로세스의 이름이 변경되었다 (이전 로그 파일에 기록을 계속 인식하고, 사실에 있다는 것입니다 log.bin.1).

나는 몇 가지 솔루션을 생각할 수 : RPC의

  1. 어떤 종류의 로그를 다시 다른 프로세스를 통지하는 (어쩌면 신갈). 나는 특히 그것을 좋아하지 않는다.
  2. 프로세스가 열린 파일 스트림을 통해 파일 길이를 확인하고 파일 이름이 바뀌 었음을 감지하고 log.bin 파일을 다시 엽니 다.

아무도 내 의견으로는 매우 우아합니다.

생각? 추천?

답변

3

해결 방법은 좋지만 공유 메모리에 현재 로깅 파일의 inode가있는 정수를 저장해야합니다 (stat(2)stat.st_ino 구성원 참조).

이렇게하면 모든 프로세스는 열려있는 inode 파일과 함께 로컬 변수를 유지합니다.

공유 var은 한 프로세스 만 순환 게재 할 때 업데이트해야하며 다른 모든 프로세스는 로컬 inode와 공유 inode 간의 차이를 확인하여 인식해야합니다. 재개발을 유도해야합니다.

+0

열린 파일 (ftell/tellg)과 디스크의 현재 로그 파일 크기 사이의 길이 차이를 기반으로 회전 감지를 구현하려고합니다. 100 % 총알이 아니지만이 시나리오에서 작동해야하며 공유 메모리가 필요하지 않습니다. –

+0

공유 뮤텍스가있는 공유 메모리를 이미 사용하고 있습니다.이 값은 100 % 글 머리 기호를 사용하는 정수 이외에 사용할 수있는 정수입니다. IMHO, 테스트 크기 차이는 임의로 작동하며 골치 거리가 날 것입니다. – Doomsday

+0

네,하지만 사소한 boost :: interprocess :: file_lock입니다. 어쨌든, 나는 이것이 가장 효율적인 로깅과 로테이션의 결과이기 때문에 이것이 최선의 해결책이라고 생각합니다. –

1
  1. 로그 항목을 작성하기 전에 매번 이름으로 파일을 여는 것은 어떻습니까?

    1. 메모리 잠금을
    2. 쓰기 로그 항목
    3. 가까운 파일
    4. 당신이 로깅 프로세스를 만들 수
  2. 또는 분리 잠금, 수신 이름으로

  3. 열려있는 파일을 공유하세요 다른 프로세스의 메시지를 로깅하고 모든 회전을 투명하게 처리합니다.

+0

레코드를 작성한 후에 파일을 닫는 것은 꽤 좋은 생각입니다. 단, 로깅 오버 헤드가 증가한다는 것만 다릅니다. 내 경우에는 2-3 회의 로깅 이벤트/초 밖에받지 못하기 때문에 적합 할 수 있습니다. 새로운 로거 프로세스는 시스템 복잡성을 증가시키고 견고성을 저하시킵니다. 나는 간단한 해결책을 찾고있다. –

1

사용중인 언어를 말하지 않지만 프로세스가 모두 로그 프로세스에 로그온하고 로그 프로세스가 파일 쓰기를 추상화해야합니다.

Logging client1 -> | 
Logging client2 -> | 
Logging client3 -> | Logging queue (with process lock) -> logging writer -> file roller 
Logging client4 -> | 
+0

질문에 C++ 태그가 있습니다. – foraidt

+0

로깅 프로세스가 종료되면 다른 프로세스에서 로그를 얻지 못하는 문제가 있습니다. –

1

당신은 사본 log.bin는 log.bin.1 할 수 있고 log.bin 파일을 자릅니다. 그래서 문제는 여전히 비어있는 이전 파일 포인터에 쓸 수 있습니다.

man logrotate 참조 :

copytruncate 
      Truncate the original log file to zero size in place after cre‐ 
      ating a copy, instead of moving the old log file and optionally 
      creating a new one. It can be used when some program cannot be 
      told to close its logfile and thus might continue writing 
      (appending) to the previous log file forever. Note that there 
      is a very small time slice between copying the file and truncat‐ 
      ing it, so some logging data might be lost. When this option is 
      used, the create option will have no effect, as the old log file 
      stays in place. 
+0

그건 내가 고려한 옵션이지만 bin 로그 파일은 현재 100MB로 회전하도록 설정되어 있기 때문에 꽤 비싼 교체가 될 것입니다. 나는 경량의 솔루션을 찾고있다. –

1

하는 공유 메모리를 사용하고 있기 때문에, 당신은 많은 프로세스가 로그 파일을 사용하는 방법을 알고있는 경우. 공유 메모리에 플래그 배열을 작성하여 각 프로세스에 파일이 순환되었음을 알릴 수 있습니다. 각 프로세스는 플래그를 다시 설정하여 파일을 계속 다시 열지 않습니다.

관련 문제