Lambda関数なしでEC2インスタンスのエラーログ監視を実装してみた
はじめに
立神です。
本ブログではLambda関数を使わずに、既存のAWSサービスと機能のみでEC2のエラーログ通知システムを構築してみました。具体的にはCloudWatch Agent、メトリクスフィルター、CloudWatchアラームを組み合わせることで、コードを書くことなくエラーログ監視が実現できます。
やってみた
前提
- 通知用のSNSトピックとサブスクリプション設定が完了済み
- テスト用EC2インスタンスの作成
- ログの監視用にCloudWatch Agentのインストール
※インストール方法や使用するポリシーはこちらを参考ください
CloudWatch Agentの設定ファイル変更
参考記事ではプロセス監視用の設定でしたが、今回はログ監視用に変更します。
- EC2インスタンスに接続
お好みの方法でEC2インスタンスに接続してください。
接続方法は以下から選択できます:- SSHクライアント
- Session Manager接続
- EC2 Instance Connect
など
私はSession Managerを使用して接続しました。
-
設定ファイルの場所に移動
cd /opt/aws/amazon-cloudwatch-agent/etc/
-
設定ファイルを編集
sudo vi amazon-cloudwatch-agent.json
-
設定内容を以下に変更:
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/test-app.log",
"log_group_name": "/aws/ec2/test-app",
"log_stream_name": "{instance_id}",
"timestamp_format": "%Y-%m-%d %H:%M:%S"
}
]
}
}
}
}
- 設定の反映
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-s \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
- 初回テストログの生成
ロググループを作成するためにテストログを生成します。
下記コマンドを実行してください。
# ERRORログを生成
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR [TEST] Manual test error for metrics creation - Test ID: $(date +%s)" >> /var/log/test-app.log
"/var/log/test-app.log"の部分は、先程メモしたファイルパスを指定します。
メトリクスフィルターの作成
CloudWatch Logsから特定のパターンを検出してメトリクス(数値データ)を生成する設定を行います。
-
CloudWatchコンソールでロググループを選択
「CloudWatch」→「ログ」→「ロググループ」から
/aws/ec2/test-app
を選択
-
メトリクスフィルターを作成
「メトリクスフィルター」タブ → メトリクスフィルターを作成をクリック
-
フィルターパターンを入力をクリックすると一覧が出てくるので、ERRORを選択し、Nextをクリック
-
メトリクスの割り当てを設定:
- フィルター名:
ApplicationErrorFilter - メトリクス名前空間:
TestApp - メトリクス名:
ErrorCount - メトリクス値:
1 - デフォルト値:
0
以上を入力して、メトリクスフィルターを作成をクリック
テスト用エラーログの生成
メトリクスフィルターを作成しましたが、実際にERRORログが発生しないとメトリクスは作成されません。メトリクスフィルターは「監視設定」のみのためです。
- CloudWatch Agentでテストログを送信
EC2インスタンスへ接続を行い、下記コマンドを実行します。
# ERRORログを生成
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR [TEST] Manual test error for metrics creation - Test ID: $(date +%s)" >> /var/log/test-app.log
"/var/log/test-app.log"の部分は、先程メモしたファイルパスを指定します。
しばらくするとCloudWatch AgentがCloudWatch Logsに自動送信します。
CloudWatch Logs Insightsで確認
先程生成したログを確認します。
-
「CloudWatch」→「ログ」→「Logs Insights (ログのインサイト)」
-
ロググループを参照 をクリック
-
ロググループ名を選択
今回は設定ファイルで指定した/aws/ec2/test-app
を選択 -
クエリを入力
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 20
5. クエリを実行
下部にログが出てくれば成功です。
CloudWatchアラームの作成
「CloudWatch」→「アラーム」→「アラームの作成」でアラームを作成していきます。
- 「メトリクスの選択」をクリックし、先程作成した「ErrorCount」を選択
- 統計の部分を「合計」に変更
- しきい値の種類を「静的」、条件を「以上」、しきい値を「1」に設定
- アクションの設定で通知の送信先を事前に作成したSNSトピックを選択
- アラーム名に任意の名前をつけ、説明に以下のように記述
エラーが発生しました!
基本情報:
• 監視対象: テストアプリケーション
• 検出条件: 5分間で1回以上のエラー
• 発生リージョン: YOUR REGION
エラーログ確認方法:
最新のエラーログ確認 (CloudWatch Logs Insights):
ログのインサイトでメモしたURL
対応手順:
1. 上記リンクでエラー内容を確認
2. エラーの原因を特定
3. 必要に応じてアプリケーションを再起動
4. 問題が解決しない場合は管理者に連絡
- 設定を確認し、アラームの作成をクリック
動作確認
以上で設定は完了です。もう一度テスト用エラーログを生成して通知が来るか確認してみましょう。
このようにメッセージが出ていれば成功です!
まとめ
今回はLambda関数を使わずにエラー通知システムを作ってみました。
ただ通知するだけではエラーが発生したという事実しかわからず、ログを探しに行く手間があったりして不便だったので、クエリまで組み込んだメールを送信できるように工夫しました。
今後は複数のログソースに対応したり、エラーの重要度に応じて通知先を変更するなど、さらに発展させていきたいと思います。
本ブログが誰かの参考になれば幸いです。
参考資料
- 小ネタCloudWatchAgentでAgent自身のプロセス監視を行なう
- CloudWatch エージェント設定ファイルを手動で作成または編集する - Amazon CloudWatch
- ロググループのメトリクスフィルターの作成 - Amazon CloudWatch Logs
- CloudWatch Logs Insights を使用したログデータの分析 - Amazon CloudWatch Logs
- インスタンスの CloudWatch アラームを作成する - Amazon Elastic Compute Cloud
アノテーション株式会社について
アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。