답변:
응용 프로그램 (예 :) run_program
이 로그 파일 크기 제한을 지원하지 않는 경우 외부 응용 프로그램이나 스크립트를 사용하여 루프에서 파일 크기를 주기적으로 확인할 수 있습니다.
당신은 또한 logrotate(8)
당신의 로그를 회전 하는 데 사용할 수 있으며 , size
당신의 목적에 사용할 수있는 매개 변수가 있습니다
이를 통해 지정된 크기에 도달하면 로그 파일이 회전합니다. 크기는 바이트 (기본값), 킬로바이트 (sizek) 또는 메가 바이트 (sizem)로 지정할 수 있습니다.
postscript
옵션을 사용 하여 logrotate 구성 SIGHUP
을 프로그램으로 보내도록 할 수 있습니다 .
프로그램이이 제한보다 큰 OTHER 파일을 쓸 필요가없는 경우을 사용하여 커널에이 제한을 알릴 수 있습니다 ulimit
. 명령을 실행하기 전에 현재 쉘 세션에서 실행되는 모든 프로세스에 대해 200MB 파일 크기 제한을 설정하려면이를 실행하십시오.
ulimit -f $((200*1024))
이것은 시스템을 보호하지만 파일을 작성하는 프로그램을 방해 할 수 있습니다. eyazici가 제안 했듯이 logrotate
로그 파일이 특정 크기 또는 연령에 도달하면 정리 ( prune)하도록 설정하는 것이 좋습니다 . 오래된 데이터를 삭제하거나 일정 기간 동안 일련의 압축 파일로 보관할 수 있습니다.
새 파일 시스템 이미지를 생성하고 루프 장치를 사용하여 마운트 한 다음 해당 파일 시스템에 로그 파일을 넣을 수 있습니다.
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
메모리가 충분한 경우 파일 대신 사용할 수도 있습니다 .
다음을 사용하여 출력을자를 수 있습니다 head
.
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
SIGPIPE
데이터를 삭제하지 않고 크기 제한에 도달하면 (와 함께 ) 프로그램을 종료 시킬 수 있습니다.
dd
마술하지만 그래 @ Random832 잘, 당신은 얻을 것이다 SIGPIPE
으로 head
/ dd
/이 whatever
그것을 삭제합니다.
trap '' SIGPIPE
어떻습니까?
{ head -c "$size" >> log; cat > /dev/null; }
.
package apache2-utils
is라는 유틸리티 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
이 링크 에서 전체 매뉴얼을 읽을 수 있습니다 .
원래 포스터가 해결책을 찾았습니다. 이 글타래를 읽을 수있는 다른 사람들을위한 또 다른 것이 있습니다 ...
Curtail은 프로그램 출력의 크기를 제한하고 다음 명령을 사용하여 마지막 200MB의 출력을 유지합니다.
$ run_program | curtail -s 200M myprogram.log
참고 : 나는 위의 repo의 관리자입니다. 솔루션을 공유하는 중 ...
텍스트이므로 선호하는 언어로 스크립트를 작성하고 그 언어로 파이프합니다. 파일 I / O를 처리하도록하십시오 (또는 메모리에 모두 보관 한 다음 덤프 SIGHUP
하거나 이와 유사한 방식으로 덤프하십시오 ). 이를 위해 200MB 대신 추적 할 수있는 '합리적인'행 수를 생각할 것입니다.
syslog
등을 logrotate
.
다음 스크립트가 작업을 수행해야합니다.
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
, 그것은이없이 작동하지 않습니다 겉으로 중복 동안.