>>를 사용하여 로그 파일 크기를 제한하는 방법


24

>>200MB로 작성된 로그 파일의 크기를 어떻게 제한 할 수 있습니까?

$ run_program >> myprogram.log

1
200MB 후에 프로그램을 종료 하시겠습니까? 아니면 비트 버킷에서 오래된 모든 것을 가진 마지막 200MB를 원하십니까?
— Aaron D. Marasco

아니, 프로세스는 수동으로 죽일 때까지 멈출 수 없다
— david

귀중한 의견을 주신 모든 분들께 감사를 표합니다
— david

답변:


9

응용 프로그램 (예 :) run_program이 로그 파일 크기 제한을 지원하지 않는 경우 외부 응용 프로그램이나 스크립트를 사용하여 루프에서 파일 크기를 주기적으로 확인할 수 있습니다.

당신은 또한 logrotate(8)당신의 로그를 회전 하는 데 사용할 수 있으며 , size당신의 목적에 사용할 수있는 매개 변수가 있습니다

이를 통해 지정된 크기에 도달하면 로그 파일이 회전합니다. 크기는 바이트 (기본값), 킬로바이트 (sizek) 또는 메가 바이트 (sizem)로 지정할 수 있습니다.


1
+1 반복되는 정보가 포함 된 로그 파일은 종종 큰 순서로 압축 될 수 있습니다.
— 사용자가 알 수 없음

logrotate가 파일을 자르거나 단순히 복사 또는 이동합니까? fd와 관련된 파일이 잘린 경우에만 작동하기 때문입니다. mv'd이면 파일이 계속 커지고, 연결이 끊어지면 계속 열려 있고 프로세스가 종료 될 때까지 계속 커집니다 ... IIRC는 복사를 끊고 연결을 끊고 새 파일을 생성합니다. 그렇기 때문에 통나무가 회전 할 때 SIMONUP을 dæmons에 보내야하는 이유가 여기에 있습니다.
— Michael Trausch

파일이 잘린 경우에도 추가 모드에서 파일을 열지 않은 경우 문제가 있습니다 (로그 파일 은 항상 추가 모드에서 열어야하지만 경험상 종종 그렇지 않습니다)
— Random832

Logrotate는 파일이 매일, 매주 등 특정 크기에 도달하면 회전 할 수 있습니다. 또한 압축 할 수 있으며 postscript옵션을 사용 하여 logrotate 구성 SIGHUP을 프로그램으로 보내도록 할 수 있습니다 .
— laebshade

12

프로그램이이 제한보다 큰 OTHER 파일을 쓸 필요가없는 경우을 사용하여 커널에이 제한을 알릴 수 있습니다 ulimit. 명령을 실행하기 전에 현재 쉘 세션에서 실행되는 모든 프로세스에 대해 200MB 파일 크기 제한을 설정하려면이를 실행하십시오.

ulimit -f $((200*1024))

이것은 시스템을 보호하지만 파일을 작성하는 프로그램을 방해 할 수 있습니다. eyazici가 제안 했듯이 logrotate로그 파일이 특정 크기 또는 연령에 도달하면 정리 ( prune)하도록 설정하는 것이 좋습니다 . 오래된 데이터를 삭제하거나 일정 기간 동안 일련의 압축 파일로 보관할 수 있습니다.


이 크기 제한 어떤 프로그램에 의해 작성된 파일
— 김

참된. 프로그램에 다른 큰 파일을 작성해야하는 합법적 인 요구가있는 경우 다른 솔루션이 필요합니다.
— Caleb

6

새 파일 시스템 이미지를 생성하고 루프 장치를 사용하여 마운트 한 다음 해당 파일 시스템에 로그 파일을 넣을 수 있습니다.

dd if=/dev/zero of=./200mb.img bs=1024 count=200000 # create new empty 200MB file
mkfs.ext2 200mb.img # or ext3, or whatever fits your needs
mkdir logs
sudo mount -t ext2 -o loop 200mb.img logs # only root can do '-o loop' by default
run_program >>logs/myprogram.log

tmpfs메모리가 충분한 경우 파일 대신 사용할 수도 있습니다 .


창의적인 아이디어 ... 프로그램이 다 떨어지면 어떻게해야하는지 프로그램에 맡깁니다.
— Aaron D. Marasco

6

다음을 사용하여 출력을자를 수 있습니다 head.

size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log

아주 창의적인. 이것은 파일에 기록되는 새로운 데이터를 제한하기 위해서만 작동한다는 점에 유의하십시오. 파일이 이미 크거나 작은 것을 고려하지는 않습니다.
— Caleb

2
SIGPIPE데이터를 삭제하지 않고 크기 제한에 도달하면 (와 함께 ) 프로그램을 종료 시킬 수 있습니다.
— Random832

1
좀 비슷한 생각 dd마술하지만 그래 @ Random832 잘, 당신은 얻을 것이다 SIGPIPE으로 head/ dd/이 whatever그것을 삭제합니다.
— Aaron D. Marasco

로 무시하는 것은 trap '' SIGPIPE어떻습니까?
— tuxce

또는 대신 파이프하십시오 { head -c "$size" >> log; cat > /dev/null; }.
— Stéphane Chazelas

5

package apache2-utilsis라는 유틸리티 rotatelogs가 있으면 도움이 될 수 있습니다.

개요:

ROTATELOGS [-l] [-L LINKNAME ] [-p 프로그램 ] [-f] [-t] [-v] [-e] [-c] [-n 수-의-파일 ] 로그 파일 rotationtime | 파일 크기 (B | K | M | G) [ 오프셋 ]

예:

your_program | rotatelogs -n 5 /var/log/logfile 1M

이 링크 에서 전체 매뉴얼을 읽을 수 있습니다 .


링크가 존재하지 않습니다.
— Alexander Gonchiy

1

원래 포스터가 해결책을 찾았습니다. 이 글타래를 읽을 수있는 다른 사람들을위한 또 다른 것이 있습니다 ...

Curtail은 프로그램 출력의 크기를 제한하고 다음 명령을 사용하여 마지막 200MB의 출력을 유지합니다.

$ run_program | curtail -s 200M myprogram.log

참고 문헌

참고 : 나는 위의 repo의 관리자입니다. 솔루션을 공유하는 중 ...


나는 축소의 아이디어를 좋아한다. 나는 C에 익숙하지 않으므로 바이너리를 제공 할 기회가 있습니까? 또는 설치 방법에 대한 최소한의 자세한 지침은 무엇입니까?
— 펠리페

0

텍스트이므로 선호하는 언어로 스크립트를 작성하고 그 언어로 파이프합니다. 파일 I / O를 처리하도록하십시오 (또는 메모리에 모두 보관 한 다음 덤프 SIGHUP하거나 이와 유사한 방식으로 덤프하십시오 ). 이를 위해 200MB 대신 추적 할 수있는 '합리적인'행 수를 생각할 것입니다.


잘라낼 수있는 것 외에 다른 이유없이 200MB의 로그 데이터를 메모리에 유지하는 것은 시스템 리소스를 잘 사용하지 않습니다. 큰 로그 파일에 대한 행 수를 계산하지도 않습니다. 내가 좋아하는이 위해 만들어진 도구를 사용하는 것이 좋습니다 것 syslog등을 logrotate.
— Caleb

0

다음 스크립트가 작업을 수행해야합니다.

LOG_SIZE=500000
NUM_SEGM=2
while getopts "s:n:" opt; do
  case "$opt" in
    s)
      LOG_SIZE=$OPTARG
      ;;
    n)
      NUM_SEGM=$OPTARG
      ;;
  esac
done
shift $((OPTIND-1))
if [ $# == 0 -o -z "$1" ]; then
    echo "missing output file argument"
    exit 1
fi
OUT_FILE=$1
shift
NUM=1
while :; do
    dd bs=10 count=$(($LOG_SIZE/10)) >> $OUT_FILE 2>/dev/null
    SZ=`stat -c%s $OUT_FILE`
    if [ $SZ -eq 0 ]; then
        rm $OUT_FILE
        break
    fi
    echo -e "\nLog portion finished" >> $OUT_FILE
    mv $OUT_FILE $OUT_FILE.n$NUM
    NUM=$(($NUM + 1))
    [ $NUM -gt $NUM_SEGM ] && NUM=1
done

그것은 몇 가지 확실한 지름길을 가지고 있지만 전반적으로 당신이 요청한 것을 수행합니다. 로그를 제한된 크기의 청크로 분할하고 청크의 양도 제한합니다. 명령 줄 인수를 통해 모두 지정할 수 있습니다. 명령 행을 통해 로그 파일도 지정됩니다.

백그라운드로 분기되는 데몬과 함께 사용하면 작은 문제가 발생합니다. 파이프를 사용하면 데몬이 백그라운드로 이동하지 못하게됩니다. 이 경우 문제를 피하기 위해 bash 관련 구문이 있습니다.

my_daemon | ( logger.sh /var/log/my_log.log <&0 & )

를 참고 <&0, 그것은이없이 작동하지 않습니다 겉으로 중복 동안.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.