皆さま、明けましておめでとうございます!y.takanashiです。
今年もよろしくお願いします。
今回はOracle Cloud(以下OCI)のオブジェクト・ストレージを使用して、ログを長期的に保管する方法について説明します。
目次
ログローテーションについて
今回の検証環境として、Oracle Linux8を使用しました。
Oracle Linux8では、デフォルトで「logrotate」がインストールされています。
「logrotate」はログファイルを削除や圧縮するためのものです。
今回の検証ではこの機能を使用してログローテーションを実現していきます。
ログローテーションとは、システムが残す時系列の記録データ(ログ)が際限なく増えることを防ぐために、一定の容量や期間ごとに古いログを削除したり新しいログで上書きすること。また、そのような機能。
e-words「ログローテーション」より引用
今回やりたいこと
デフォルトではローテーションされたログは複製されたのち、1ヶ月後に自動的に削除されます。
デフォルトの設定では対象ログの中にOS内のエラーを記録するログやセキュリティ関連のログが含まれており、万が一のことを考えて1ヶ月以上経過したログも残しておくべきだと個人的に考えます。
後述する設定ファイルのlogrotate.confの中身を書き加える手もありますが、ログの保管期間を長期間に設定すると、ログの容量が増えてしまい、ディスク領域を圧迫してしまう可能性があります。
そこでローテーションされたログをオブジェクト・ストレージに格納することで、ディスク領域を圧迫せずにログを長期間保管することができます。
今回はログローテーション〜オブジェクト・ストレージに格納するまでの一連の流れについて説明します。
この検証の主な要件は以下の表となっております。
ちなみにオブジェクト・ストレージはAWSのS3互換のストレージで、料金は1GBあたり約3.5円(2023年1月現在)と、ブロック・ボリューム(1GBあたり約6円)と比べて手頃な料金で利用できます。
オブジェクト・ストレージの詳細は下記のドキュメントをご覧ください。
各種ファイルの設定
ここではログローテーションを構成する各種ファイルについて説明し、その後に今回の要件に沿うように各ファイルの編集を行います。
設定前後の内容をわかりやすくするため、設定前(デフォルト)の内容は黒背景で、設定後は白背景の図を使用します。
/etc/logrotate.conf
/etc/logrotate.conf(以下logrotate.conf)はOS内全体でのログローテーションの設定を定義します。
以下の図がデフォルトの定義内容です。
logrotate.conf に記載されているコマンドは以下となります。
- weekly...1週間単位でローテーションする(daily, weekly, monthlyから選択)
- rotate 4...何世代分OS内にローテーションしたログを残すか(この場合は4世代分)
- dateext...ローテーションログの後ろに日付を記載
- (例:「messages-20230105)
- compress...ローテーションしたログを.gz形式で圧縮
- (デフォルトでは無効化されている点に留意)
- include /etc/logrotate.d...各ログファイルの設定が置かれるパスを指定
- (デフォルトでは/etc/logrotate.d{後述}が記載)
logrotate.conf に記載されている上記のコマンド以外にも、使用頻度の高いコマンドを以下の図に示します。
そのほかlogrotate.confで使用するコマンドの詳細は下記の記事をご覧ください。
Qiita - 任意のログをlogrotateを使って管理する
以下の図が設定後の定義内容で、赤枠部分を今回の要件に沿うように変更しています。
/etc/logrotate.d
/etc/logrotate.d(以下logrotate.d)はログローテーションの対象となる各ファイルの詳細について定義します。
以下の図のように、logrotate.d配下には様々なファイルがあります。
その中で、syslogの定義内容を以下の図に示します。
{}内のコマンドを使用して、ローテーションを実行したい複数のファイルパスがsyslogファイルの上部に定義されています。
{}のコマンドにの実行内容については上記の表に記載しましたので、ここでの説明は割愛します。
logrotate.confとlogrotate.d配下のファイルの関係についてですが、
logrotate.confはローテーションするファイル全般に共通する内容を定義、
logrotate.d配下のファイルには各ファイルの詳細をそれぞれ定義しています。
権限の強さは、logrotate.conf > logrotate.dとなっておりますので、logrotate.confの定義内容を変更した場合、ログローテーションを行う全てのファイルに反映されますのでご注意ください。
/etc/anacrontab
/etc/anacrontab(以下anacron)はジョブをスケジュールするための設定ファイルです。
anacronはcronと親戚関係にありますが、
- anacronは遅延実行が行われて、分単位では行えない、一日1回しか実行できない
- cronは分単位での実行が行えるが、継続的に実行されていることを前提としている
といった違いがあります。
少し情報は古いですが、詳細は下記の公式ドキュメントをご覧ください。
Linux6設定ガイド - cron および anacron
以下の図がデフォルトの定義内容です。
本記事の主旨と外れますので、anacronの詳細は下記の記事をご覧ください。
【Linux】anacronの制御について検証しながら理解した際の話
anacronは時間の指定が曖昧で、今回の要件では指定した時間でログローテーションを行いたいので、
実行時間の赤枠部分を全てコメントアウトしました。
/etc/cron.daily/logrotate
/etc/cron.daily/logrotate(以下logrotateファイル)はlogrotateコマンドの実行内容を定義します。
定義内容はシンプルで、logrotateコマンドを行いエラーが発生した場合に、loggerコマンドを用いて/var/log/messagesに出力するといったものです。
OSの仕様により時々ローテートされない場合を考慮して、logrotateコマンドの後ろに強制的にローテーションを実行させる「-f」オプションを追加しました。
/var/spool/cron/root
最後に/var/spool/cron/root(以下cron)は、指定した時間に特定の処理を記述するファイルで、「crontab -e」コマンドで編集できます。
こちらは参考記事が多いので、一例として下記の記事をご覧ください。
またcronの設定する際は、事前に下記のサイトで検証することをお勧めします。
cronはデフォルトでは何も記述されておらず、新規で定義する必要があります。
以下が上記のcronの定義内容となります。
- ①毎日0時00分にrun-partsコマンド(引数に指定したディレクトリを実行する)で、logrotateファイルを実行
- ②毎日0時10分にlogrotation.sh(後述)を実行
ログをオブジェクト・ストレージに格納
シェルスクリプトを使用して格納
ここではローテーションされたログをオブジェクト・ストレージに格納する流れを説明します。
上記の作業を行う前に、事前にオブジェクト・ストレージをファイルシステムとして連携させる必要があります。
連携していない方は、以下の記事を参考に行ってください。
Cloudiiブログ - オブジェクト・ストレージをファイルシステムとしてマウントさせる
OS内でファイルシステムとして連携させたオブジェクト・ストレージの構成図は以下となっています。
スクリプトで自動で作成するディレクトリ以外は事前に作成しておきましょう。
ローテーションされたログをオブジェクト・ストレージに格納する際は、シェルスクリプト(ここでは「logrotation.sh」)を使用します。
以下の図が、今回の要件に沿って定義したシェルスクリプトです。
logrotation.shの定義内容は以下となっております。
- ①実行前に各変数を定義
- ②OCIコンソール上に該当月分のディレクトリがない場合に新規で作成
- ③ローテートしたログをオブジェクト・ストレージにコピー
- ④366日前に作成したディレクトリを削除
OCIコンソール上でログを確認
最後にシェルスクリプトを実行後、オブジェクト・ストレージにローテーションされたログが格納されてるかの確認を行います。
OCIコンソールでファイルシステムとして連携させたオブジェクト・ストレージのページに行き、ストレージ内を確認してみると、
無事にログが格納されたことが確認できました!
また参照したいログ(ここでは「secure-20230104.gz」)の三点リーダーアイコン →「ダウンロード」でダウンロード後、任意のテキストエディタ(ここでは「VS Code」)でファイルを開いてみると、
文字化けせずに、ちゃんと読める状態で保存されているのがわかります。
オブジェクト・ストレージに保存されたログを自動的に削除したい場合は、オブジェクト・ストレージ内サービスのライフサイクル・ポリシーを使用して設定します。
以下が今回の要件に沿った使用例です。
ライフサイクル・ポリシーの詳細は下記の公式ドキュメントをご覧ください。
以上です!
これでログローテーション〜ログをオブジェクト・ストレージに格納されるまでの一連の作業は完了です。
まとめ
改めてここまでの一連の流れについて整理します。
- 各種ファイルの定義内容の変更
- /etc/logrotate.conf...ログローテーション対象ファイル全般を定義。ここではローテーションの頻度をweekly→dailyに、OS内に保持するファイルを4世代→7世代に、ローテーションされたログを圧縮する設定に変更
- /etc/logrotate.d...個別のファイルの詳細について定義。ここでは特に変更なし
- /etc/anacrontab...ジョブをスケジュールするための設定ファイル。ここではスケジュール箇所を全てコメントアウト
- /etc/cron.daily/logrotate...logrotateコマンドの実行内容を定義。ここではlogrotateコマンドの後ろに「-f」を追加
- /var/spool/cron/root..指定した時間に特定の処理を実行させるための設定ファイル。今回の要件に沿うように設定
- シェルスクリプトを使用してログをオブジェクト・ストレージに格納
- 実行前に各変数を定義
- OCIコンソール上に該当月分のディレクトリがない場合に新規で作成
- ローテートしたログをオブジェクト・ストレージにコピー
- 366日前に作成したディレクトリを削除
- オブジェクト・ストレージに格納されたログの確認
- ライフサイクル・ポリシーを使用して格納されてから365日後にログを削除
ここでの注意点は、作業環境毎に仕様が違うので、必要に応じて定義内容等を変更する必要があることです。
例えば、Oracle Linux8ではデフォルトでwtmpファイル(ログイン成功を記録)とbtmpファイル(ログイン失敗を記録)が/etc/logrotate.d配下に存在しますが、BaseDB内には存在しないので該当ファイルを新規作成する必要があります。
以上となります。
この記事を通じて読者の皆様の問題解決の一助となれば幸いです。
最後まで読んで頂き、ありがとうございましたm(_ _)m