概要
- EC2上で logorotate を使ってログのローテーションを行っている環境で
- サーバー上には最近のログだけ残すようにしたい。
- logrotateでローテートされた過去ログは 毎日S3にバックアップする状態にしたい。
- という要求を過去にざっくり実現した時のメモです。
この記事でやっている事
- アップロード先のS3バケットを用意する
- AWS CLIでs3にアップロードを行える環境を用意する
- logrotate の設定ファイルを編集する
- dry run、強制実行で動作チェック
1. アップロード先のS3バケットを用意する
- ログファイルのアップロード先となるS3バケットを用意します。
- 基本的に今回試している内容ではアップロードは行うが、消し込み処理は行われないのでデータは蓄積される一方となる。
- s3上の古いファイルの消し込みや異なるストレージタイプへの移動は、S3バケットのライフサイクルポリシーで制御すると簡単に実現できます。
2. AWS CLIでアップロードを行える環境を整備する
- AWS CLIの
aws s3
コマンドを使って実現します。 - アップロード元の logrotateを動作させている環境にAWS CLIのインストールが必要。
- AWS CLIはAmazonLinuxで起動したEC2ならデフォルトで導入済みだとは思います。
- 1.で作成したアップロード先 S3バケットへの書き込み権限をインスタンスロールで設定する。
- EC2やECSコンテナ等であれば インスタンスロールで権限を付与すればOS上での認証情報の用意は不要です。
- 検証時は
AmazonS3FullAccess
ポリシーを追加したインスタンスロールをEC2に適用しました。 - IAMで実装したい場合は適切な権限を持ったIAMのCredentials情報を取得しましょう。
3. logrotate の設定ファイルを編集する。
- ディストリビューションによりますが logrotate の設定ファイルは
/etc/logrotate.d/
などにあることが多いです。 - 例えば AmazonLinux2 でhttpdを導入した場合は、httpd のアクセスログ、エラーログをローテートするための設定がインストール時に
/etc/logrotate.d/httpd
として追加されます。 - logrotate設定で
lastaction
のセクションを追加する事で ローテート処理実行後に任意の処理を追加することができます。 - 今回の例では dateextで日付情報が付与され gzでCompressされてアーカイブされたファイルを、S3へアップロードしたいのでそのような処理を追加します。
- 以下の設定は各種オプションで毎日強制ローテートさせ、dateextでの日付情報付与と、compressでのgz圧縮を行っている設定の例です。
/var/log/httpd/*log {
missingok
sharedscripts
compress
minsize 0
rotate 8
daily
ifempty
dateext
postrotate
/bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
endscript
lastaction
S3Bucket="用意したS3バケット名"
HOSTNAME=`hostname`
read DAY MONTH YEAR <<< `/bin/date "+%d %m %Y"`
DATEEXT="${YEAR}${MONTH}${DAY}"
for fullpath in $1
do
logfile=`/bin/basename ${fullpath}`
if [ -f ${fullpath}-${DATEEXT}.gz ]; then
/usr/bin/aws s3 cp ${fullpath}-${DATEEXT}.gz s3://${S3Bucket}/${YEAR}/${MONTH}/${DAY}/${logfile}-${DATEEXT}-${HOSTNAME}.gz
fi
done
endscript
}
-
lastaction
の処理中は ローテート対象となったファイルのパスを$1
で取得できるので、それを元に ローテートされて gz圧縮されたファイルがあれば s3バケットへcpしています。 - もっと雑にやるなら無条件で gzファイルを s3 sync するとかでいいかもしれない。
4. dry run、強制実行で動作チェック
dry run
- 編集したファイルを
/etc/logrotate.d/httpd
等として設置後に下記のコマンドを実行すると dry run で動作を確認できます。 - -d オプションを付与することで dry run を実行できます。
logrotate -dvf /etc/logrotate.d/httpd
強制実行
- -d オプションを除くと -f オプションにより強制実行できます。
logrotate -vf /etc/logrotate.d/httpd
- S3バケットを確認し、ファイルがアップロードされていれば成功です。
- cronで回す場合はcronでもちゃんと回るかは確認しましょう。 直接実行では問題ないのにcronで環境変数周りが違っていて...といった事はよくある。
ログを取りたい
- ちゃんと動いているのか不安。
- cron で動かす場合は cron のログに出ているとは思います。
- 個別に取りたいなら lastaction の処理中で
aws s3 cp
の処理結果をテキストファイル等にリダイレクトしたりもできます。
/usr/bin/aws s3 cp ${fullpath}-${DATEEXT}.gz s3://${S3Bucket}/${YEAR}/${MONTH}/${DAY}/${logfile}-${DATEEXT}-${HOSTNAME}.gz >> /tmp/log.txt
- もう少しちゃんとやるなら
logger
などで syslogに出力されるようにしても良いかもしれない。
まとめ
- 以上、logrotate のローテートのタイミングで、アーカイブをS3へバックアップする方法のメモでした。