Làm cách nào tôi có thể giới hạn kích thước của tệp nhật ký được ghi với >>
200MB?
$ run_program >> myprogram.log
Làm cách nào tôi có thể giới hạn kích thước của tệp nhật ký được ghi với >>
200MB?
$ run_program >> myprogram.log
Câu trả lời:
Nếu ứng dụng của bạn (ví dụ. run_program
) Không hỗ trợ giới hạn kích thước của tệp nhật ký, thì bạn có thể kiểm tra kích thước tệp định kỳ trong một vòng lặp với một ứng dụng hoặc tập lệnh bên ngoài.
Bạn cũng có thể sử dụng logrotate(8)
để xoay các bản ghi của mình, nó có size
tham số mà bạn có thể sử dụng cho mục đích của mình:
Với điều này, tệp nhật ký được xoay khi đạt đến kích thước được chỉ định. Kích thước có thể được chỉ định bằng byte (mặc định), kilobyte (sizek) hoặc megabyte (sizem).
postscript
tùy chọn để gửi cấu hình logrotate sau đó SIGHUP
đến chương trình.
Nếu chương trình của bạn không cần ghi bất kỳ tệp KHÁC nào lớn hơn giới hạn này, bạn có thể thông báo cho kernel về giới hạn này bằng cách sử dụng ulimit
. Trước khi bạn chạy lệnh của mình, hãy chạy lệnh này để thiết lập giới hạn kích thước tệp 200 MB cho tất cả quá trình chạy trong phiên shell hiện tại của bạn:
ulimit -f $((200*1024))
Điều này sẽ bảo vệ hệ thống của bạn nhưng nó có thể gây nhiễu cho chương trình ghi tệp. Như Eyazici gợi ý , hãy xem xét việc thiết lập logrotate
để cắt tỉa các tệp nhật ký một khi chúng đạt đến một kích thước hoặc độ tuổi nhất định. Bạn có thể loại bỏ dữ liệu cũ hoặc lưu trữ dữ liệu đó trong một khoảng thời gian trong một loạt các tệp nén.
Bạn có thể tạo một hình ảnh hệ thống tập tin mới, gắn kết nó bằng thiết bị lặp và đặt tệp nhật ký vào hệ thống tập tin đó:
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
Bạn cũng có thể sử dụng tmpfs
thay vì một tập tin, nếu bạn có đủ bộ nhớ.
Bạn có thể cắt đầu ra với head
:
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
SIGPIPE
) một khi nó đã đạt đến giới hạn kích thước, thay vì loại bỏ dữ liệu.
dd
ma thuật nhưng yeah @ Random832 là đúng, bạn sẽ nhận được một SIGPIPE
như head
/ dd
/ whatever
giọt nó.
trap '' SIGPIPE
?
{ head -c "$size" >> log; cat > /dev/null; }
.
Trong gói apache2-utils
là tiện ích hiện tại được gọi rotatelogs
, nó có thể hữu ích cho bạn.
Tóm tắc:
rotatelogs [-l] [-L linkname ] [-p chương trình ] [-f] [-t] [-v] [-e] [-c] [-n number-of-files ] logfile rotationtime | kích thước tệp (B | K | M | G) [ offset ]
Thí dụ:
your_program | rotatelogs -n 5 /var/log/logfile 1M
Hướng dẫn đầy đủ bạn có thể đọc trên liên kết này .
Tôi chắc chắn các poster ban đầu đã tìm thấy một giải pháp. Đây là một cái khác cho những người khác có thể đọc chủ đề này ...
Curtail giới hạn kích thước của đầu ra của chương trình và bảo toàn 200 MB đầu ra cuối cùng bằng lệnh sau:
$ run_program | curtail -s 200M myprogram.log
LƯU Ý: Tôi là người duy trì repo trên. Chỉ cần chia sẻ giải pháp ...
Vì nó là văn bản, tôi sẽ viết một kịch bản bằng ngôn ngữ yêu thích của bạn và chuyển nó sang đó. Yêu cầu nó xử lý tệp I / O (hoặc giữ tất cả trong bộ nhớ và sau đó kết xuất SIGHUP
hoặc tương tự). Vì thế, thay vì 200 MB, tôi sẽ nghĩ đến một số dòng 'hợp lý' để theo dõi.
syslog
và logrotate
.
Các kịch bản sau đây nên làm công việc.
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
Nó có một vài đường tắt rõ ràng, nhưng nhìn chung nó làm những gì bạn yêu cầu. Nó sẽ chia khúc gỗ thành một khối có kích thước hạn chế và số lượng khối cũng bị giới hạn. Tất cả có thể được chỉ định thông qua các đối số dòng lệnh. Tệp nhật ký cũng được chỉ định thông qua dòng lệnh.
Lưu ý một gotcha nhỏ nếu bạn sử dụng nó với daemon chuyển thành nền. Sử dụng một đường ống sẽ ngăn daemon đi đến nền. Trong trường hợp này, có một cú pháp (có thể là bash-cụ thể) để tránh sự cố:
my_daemon | ( logger.sh /var/log/my_log.log <&0 & )
Lưu ý <&0
, trong khi dường như dư thừa, nó sẽ không hoạt động mà không có điều này.