やりたいこと
各サーバーのログファイルを定期的に取得し保存する。保存元のサーバーでシェルスクリプトを書いてみました。
- 保存したログファイルは保持期間が過ぎていれば削除する
- webとapiのログファイルは当日日付、batchは前日日付
- bashのバージョンはGNU bash, version 4.2.46
#!/bin/bash -eu
# sshログイン
SSH_LOGIN="-i ~/.ssh/id_rsa [username]@"
# ファイル保持期間
PERIOD=5
# 前日日付
PRE_Y="$(date '-d 1 day ago' +%Y)"
PRE_M="$(date '-d 1 day ago' +%m)"
PRE_D="$(date '-d 1 day ago' +%d)"
PRE_YMD=${PRE_Y}${PRE_M}${PRE_D}
# 当日日付
TO_YMD="$(date +%Y%m%d)"
# エラーメッセージ
error_msg=""
# 各サーバーのコピー元ファイルとコピー先ディレクトリのハッシュ
declare -A WEB
WEB["/var/log/nginx/www.hoge.jp/*.log-${TO_YMD}.gz"]="/server_logs_backup/web@/var/log/nginx/"
declare -A API
API["/var/log/nginx/api.hoge.jp/*.log-${TO_YMD}.gz"]="/server_logs_backup/api@/nginx/"
declare -A BATCH
BATCH["/home/hoge/app/logs/${PRE_YMD}.php.gz"]="/server_logs_backup/batch@/app/logs/"
# 各ホストのIPとサーバーのハッシュ
declare -A HOST
HOST["IP address"]="WEB"
HOST["IP address"]="API"
HOST["IP address"]="BATCH"
# サーバーとコピー元ファイルのハッシュ
declare -A SERVER
SERVER["WEB"]=${!WEB[@]}
SERVER["API"]=${!API[@]}
SERVER["BATCH"]=${!BATCH[@]}
# コピー先を取得する
function get_dest {
eval echo '$'{$1[$2]/@/$3}
}
# エラー時のメール送信
function send_alert {
echo "Subject: [ERROR] log backup fails
To: [宛先のアドレス]
From: [送信者のアドレス]
${1}" | /usr/sbin/sendmail -t
}
# HOSTのキーからipを取得
for ip in ${!HOST[@]}; do
# ipからサーバーを取得
for server in ${HOST[$ip][@]}; do
# サーバーからコピー元ファイルを取得
for src in ${SERVER[$server][@]}; do
# コピー先を取得
dest=`get_dest ${server} ${src} ${ip##*.}`
# 保持期間がすぎているファイルを削除
find ${dest} -mtime +${PERIOD} -type f | xargs rm -rf
# コピー元ファイルが存在するか確認
if [ $(ssh ${SSH_LOGIN}${ip} "ls $src >& /dev/null;" echo \$?) -eq 0 ]; then
# 存在すればコピー先にscpする
/usr/bin/scp ${SSH_LOGIN}${ip}:${src} ${dest}
# scpコマンドでエラーが出た場合はerror_msgを貯める
if [ $? -ne 0 ]; then
BODY="[ERROR] ${ip} ${server} ${src} ${dest}"
echo ${BODY} >> "${log_file}"
error_msg+="${BODY}
"
fi
fi
done
done
done
# error_msgが空でなければメール送信
if [ -n "${error_msg}" ]; then
send_alert "${error_msg}"
fi
exit 0