질문이 너무 길어서 죄송합니다. 이것은 설명하기 어렵습니다. 제가 영어에 능통하더라도 그렇지 않습니다. ;)
이 질문에는 Java, log4j 라이브러리 및 Linux가 있으므로 어디에 게시해야 할지 잘 모르겠습니다.
상상하다:
log4j를 사용하여 생성된 로그 파일이 여러 개 있습니다 RollingFileAppender
. 이름파일.로그그리고파일.로그.1도착하다파일.로그.10
모든 파일은 하루에 여러 번 덮어쓰여집니다. 즉, 이벤트를 수신하면 덮어쓰게 되므로 무슨 일이 일어났는지 확인할 수 있는 로그가 거의 없을 것입니다.
목적:
내 의도는 특정 조건에서 주기적으로 이러한 파일을 백업하는 것입니다.
- 첫째, 데이터를 놓치지 마세요(작업을 충분히 자주 실행하는 문제 해결)
- 정보를 반복하지 마십시오. (정보를 정리하면 해결 가능)
- 데이터를 정렬해야 합니다. (질문!!)
지침:
- 각 개별 파일은 정렬되지만 데이터를 쓰는 두 개의 서버 인스턴스가 있기 때문에 파일 전체가 정렬되는 것은 아닙니다.
내 말은 한 인스턴스가 *.log.1에 쓸 수 있고 다른 인스턴스가 *.log.2에 동시에 쓸 수 있다는 것입니다. 그래서 나는 그것들을 모두 병합하고 정렬할 것으로 기대할 수 없습니다. - 파일 시스템의 여유 공간을 늘릴 수 없습니다.
로그 레지스터 레이아웃:
각 줄은 다음과 같습니다.
2014-11-28 14:33:10,015 메인 ca.cpy.net.txc.batch.SendEER INFO - 정보
노력하다:
에서 어펜더 유형으로 이동되었습니다
RollingFileAppender
.DailyRollingFileAppender
불행히도 Apache 문서에는 다음과 같이 나와 있습니다."DailyRollingFileAppender에서 동기화 문제 및 데이터 손실이 발생하는 것으로 관찰되었습니다."
그래서 나는 그것을 사용할 수 없습니다.
- Apache log4j extras 라이브러리를 사용하고 있지만 이 작업을 수행할 수 없습니다. 그것은 나에게 달려 있지 않습니다.
모든 것을 스스로 하십시오. 여기에는 다음이 포함됩니다:
- 모든 파일 병합
- 정렬하세요
- 이전 백업에 저장된 모든 데이터를 폐기합니다.
- 압축
문제는 정렬 단계에 있습니다. 내가 시도한 것은 다음과 같습니다.
for ((i=10; i >= 1; i--)); do cat file.log.$i >> $FILE_OUT; ## put all files in one (as much sorted as possible) done; cat file.log >> $FILE_OUT; ## append last sort -s -t ' ' -k 1.1,1.4n -k 1.6,1.7n -k 1.9,1.10n -k 2.1,2.2n -k 2.4,2.5n -k 2.7,2.8n -k 2.10,2.12n -3k $FILE_OUT -o $FILE_SORTED # Sort by date/time
글쎄요, 로그에 레지스터당 한 줄만 추가된 경우(즉, 줄 끝 문자 \n이 없는 경우)에는 작동합니다. 예를 들어, 위의 sort 명령은 다음 레지스터를 삭제합니다.2014-11-28 14:33:10,015 main ca.cpy.net.txc.batch.SendEER INFO - ***** RESULTATS ENVIAMENT EXPEDIENT ***** Total documents a tractar en DB: 86 *****************************************
첫 번째 줄만 정렬되고 나머지 세 줄은 출력 파일의 시작 부분에 배치됩니다.
여러 줄이 포함된 모든 레지스터를 삭제하지 않고 병합된 파일을 정렬하는 방법이 있습니까? 다른 아이디어도 매우 환영받을 것입니다.
답변1
한 가지 방법은 다음과 같습니다.
로그 파일을 NUL
-로 구분하여 만듭니다. 즉, 각 레코드는 NUL
( \0
) 문자로 끝나도록 합니다. 그런 다음 NUL
다양한 도구( sed
, sort
, xargs
등 ) find
에서 구분된 텍스트에 대한 지원을 활용할 수 있습니다 . 한 가지 방법은 다음과 같습니다.
perl -pe 's/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/\0$1/' file.log.2 > file.log.2.NULL
- 각 타임스탬프 앞에 1을 추가합니다.
\0
(이것은 반대 방법입니다. 레코드가 로 시작NUL
하지만 실제로는...)
그러면 다음과 같이 할 수 있습니다:
sort -szt ' ' -k1,2 file.log{.{10..1},}.NULL -o $FILE_SORTED
-s
안정적인 정렬을 위해(바인딩 항목이 나타나는 순서대로 정렬되도록)-z
NUL
구분된 텍스트 지원 켜기- 주석에서 지적했듯이 양식의 타임스탬프를
YYYY-MM-DD HH:MM:SS,UUU
사전순으로 정렬할 수 있기 때문에 키를 변경했습니다. 숫자로 정렬할 필요는 없습니다.
또는 이러한 임시 파일을 모두 완전히 피할 수 있습니다.
perl -pe 's/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/\0$1/' file.log{.{10..1},} | \
sort -szt ' ' -k1,2 -o $FILE_SORTED