![logrotate 執行的腳本給出的結果與手動執行的結果不同](https://rvso.com/image/168788/logrotate%20%E5%9F%B7%E8%A1%8C%E7%9A%84%E8%85%B3%E6%9C%AC%E7%B5%A6%E5%87%BA%E7%9A%84%E7%B5%90%E6%9E%9C%E8%88%87%E6%89%8B%E5%8B%95%E5%9F%B7%E8%A1%8C%E7%9A%84%E7%B5%90%E6%9E%9C%E4%B8%8D%E5%90%8C.png)
我想使用 輪換我們的應用程式日誌logrotate
。每次輪換後,它都會執行一個腳本,將所有輪換日誌移動到另一個目錄。例如/home/dev/logs/frontend
,我有這些日誌檔案:
webapp1-access.log
webapp2-access.log
anotherapp3-access.log
codename-access.log
...
我的 logrotate 設定檔:
$ cat app.daily
/home/dev/logs/frontend/*access.log {
rotate 1
daily
copytruncate
compress
notifempty
missingok
lastaction
bash /path/to/script.sh
endscript
}
script.sh 的作用是根據日誌檔案名稱建立目錄然後將旋轉的日誌檔案移到那裡。會webapp1-access.log
被旋轉到webapp1-access.log.1.gz
然後腳本會將其移動到/x/y/webbapp1/renamed.log.gz
。對於其他旋轉日誌,依此類推。
當我使用測試 logrotate 時logrotate -fv /path/to/config
,它會按照我的預期完美運行。然後我將 logrotate 設定檔放入/etc/logrotate.d
(作為符號連結)。
第二天我檢查了/x/y
目錄,我得到:
webbapp1/ <---- created from initial logrotate -fv
webbapp1-access.log/ <---- Unexpected
anotherapp3/ <---- created from initial logrotate -fv
anotherapp3-access.log/ <---- Unexpected
codename/ <---- created from initial logrotate -fv
codename-access.log/ <---- Unexpected
目錄*-access.log/
是由 logrotate 建立的。但logrotate -vf config
多次運行不會產生意想不到的結果。當我讓 logrotate 進行每日輪換時就會發生這種情況。
為什麼會發生這種情況?我怎樣才能解決這個問題?
script.sh
#! /usr/bin/bash
exec 3>> /var/log/archived-log.log
[ "${1:-}" = "-d" ] && debug=1
environment="frontend"
rotateddir="/home/dev/logs/$environment"
destdir="/x/y"
[ "${debug:-}" ] && echo "DEST DIR: $destdir"
log() {
timestamp=$(date +"%Y-%m-%d %H:%M:%S")
echo "$timestamp: $1" >&3
}
for archive in $rotateddir/*.gz; do
[ "${debug:-}" ] && echo "ARCHIVE: $archive"
[ "${archive##*/}" = "*.gz" ] && continue
base_name=$(basename "$archive")
[ "${debug:-}" ] && echo "BASENAME: $base_name"
extension="${base_name##*.}"
[ "${debug:-}" ] && echo "EXT: $extension"
newdir_name="${base_name%-*}"
[ "${debug:-}" ] && echo "NEWDIR_NAME: $newdir_name"
tanggal=$(stat -c %y "$archive" | cut -d" " -f1 | { read dat; date -d $dat +%Y%m%d; })
#jam=$(stat -c %y "$archive" | cut -d" " -f2 | { read dat; date -d $dat +%H%M; })
newdir_path="$destdir/$newdir_name"
[ "${debug:-}" ] && echo "NEWDIR_PATH: $newdir_path"
#dest_archive="$newdir_path/$tanggal-$jam.log.$extension"
dest_archive="$newdir_path/$tanggal.log.$extension"
[ "${debug:-}" ] && echo "DEST_ARCHIVE: $dest_archive"
[ ! -d "$newdir_path" ] && {
if [ "${debug:-}" ]; then
echo "Would create $newdir_path"
else
mkdir -p "$newdir_path"
log "Created directory: $newdir_path"
fi
}
[ ! -f "$dest_archive" ] && {
if [ "${debug:-}" ]; then
echo "Would move $archive to $dest_archive"
else
rsync -a --no-owner --no-group --remove-source-files "$archive" "$dest_archive"
#cp -u --no-preserve=mode,ownership "$archive" "$dest_archive" && rm -f "$archive"
log "Relocated $archive to $dest_archive"
fi
}
rotates=$(ls -1 "$newdir_path" | wc -l )
[ "$rotates" -ge 7 ] && {
oldest=$(ls -t "$newdir_path" | tail -1)
if [ "${debug:-}" ]; then
echo "Would delete the oldest archive: $oldest"
else
rm -f "$newdir_path/$oldest"
log "Deleted oldest archive of $base_name : $oldest"
fi
}
done
exit 0
更新
我仍然不知道為什麼會發生這種情況,但最後我決定在輪換後幾分鐘透過 cron 運行腳本。
我懷疑我的“script.sh”的這一部分newdir_name="${base_name%-*}"
沒有得到很好的評估logrotate
。但同樣,如果我使用強制運行它,它會按預期工作logrotate -fv config
答案1
結果 logrotate 使用 bashishms 執行腳本sh
,而我的腳本包含 bashishms。
從手冊頁:
最後行動/結束語
之間的線最後行動和尾稿(兩者都必須單獨出現在行上)被執行(使用/bin/sh) ...
最後,我在crontab
logrotate 後幾分鐘執行我的腳本。