AWS上でAutoScaleを利用していると、ヘルスチェックでミスったりの予期せぬEC2停止でEC2ごと削除されることがままあります。
いざ原因をログから解析しようと思っても、EC2ごとログが消えているため、どうにもならないことがありました。
そんなときのためにEC2停止時に指定したログをS3上に逃がすスクリプトを作成しました。
注:この方法は、EC2がshutdownコマンドなどで正常停止する場合に取得可能です。(AutoScaleなどから切り離された時など)
EC2自体がカーネルパニックやハードウェア障害で正常に停止していない場合はこの方法では救えません(経験上ほぼないですが)
###[必要なもの(※Amazon Linuxに設定する前提)]
-EC2停止時にS3にログを退避するスクリプト
-退避する対象のログリスト
-ログ退避スクリプトをEC2停止時に実行するサービス起動・停止(init.d)スクリプト
[EC2停止時にS3にログを退避するスクリプト]
日付とインスタンスIDをログに付与してS3にアップロード
※1 以下はawsの情報取得にcredentialsにアクセスキーを記載して利用しているが、IamRoleを利用できるならばそのほうがよい
※2 パスも/usr/local/bin/と/usr/local/etc/を利用しているが任意
#!/bin/sh
DATESTR=`date +%Y%m%d_%H%M%S`
# コンフィグ情報読み込み
INSTANCEID=`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id`
AWSSETTING=/root/.aws/credentials
SRCFILELIST=/usr/local/etc/shutdown_targetfile.txt
TMPCPPATH=/tmp/logtmp
BUCKET=hogehoge-log
FOLDER=hoge/shutdown
export AWS_CONFIG_FILE=$AWSSETTING
# ログ取得の対象を作業フォルダにコピー
mkdir -p $TMPCPPATH 2>/dev/null
cat ${SRCFILELIST} | while read FILEPATH
do
cp -f ${FILEPATH} $TMPCPPATH/
done
# 指定パス対象にgzip化
for i in `find $TMPCPPATH -maxdepth 1 -type f | egrep -v gz`
do
gzip -c $i > $i"_shutdown_"$INSTANCEID"_"${DATESTR}.gz
rm -f $i
done
# S3のフォルダへ.gzファイルをアップロード 合わせて、取得したログ一覧も
aws s3 cp $TMPCPPATH s3://$BUCKET/$FOLDER/$DATESTR/ --exclude "*" --include "*.gz" --recursive
aws s3 cp $SRCFILELIST s3://$BUCKET/$FOLDER/$DATESTR/
# 作業フォルダを削除する
rm -rf $TMPCPPATH
[EC2停止時にS3にログを退避するスクリプト]
ファイル単位で指定
ここではシステム関連の/var/log/のみ退避させている。tomcatやnginxなどのアプリケーションログも指定可能
各システムに必要なものを指定する
/var/log/messages
/var/log/cron
/var/log/secure
[ログ退避スクリプトをEC2停止時に実行するサービス起動・停止(init.d)スクリプト]
サービス起動時に2重起動防止をしておき、サービス停止時(マシン停止時)にスクリプトを実行
chkconfig: runlevel 起動順番 終了順番 のため、起動を一番遅く、停止時は一番早く実行する
#!/bin/bash
#
# Version: 0.1
#
# chkconfig: 345 99 01
# description: logmvs3_shutdown shell
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
# Source function library.
. /etc/init.d/functions
start() {
touch /var/lock/subsys/logmvs3_shutdown
}
stop() {
rm -f /var/lock/subsys/logmvs3_shutdown
/usr/local/bin/logmvs3_shutdown.sh
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
[サービス登録と確認]
あとは以下のコマンドを実行し、サービスに登録および開始しておく
chkconfig --add logmvs3_shutdown
service logmvs3_shutdown start
再起動してみて、指定のS3バケットのフォルダにログがアップロードされていればOK