この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
どうも、クラ本部の黒田です。
大変お久しぶりですね。
あっという間で、今年は残り僅かとなりました。
涼しくなってきましたところ、そろそろ来年に向けて、オフラインで会社説明会を開こうかと考えております。
協栄情報にご興味のある方、是非、ご連絡いただければ幸いです。
さて、今回は、システム監視スクリプトを作成してAWS SNSで通知を受け取る実装手順を解説します。
スクリプトは以下の機能を提供します。
- メモリ使用状況の監視
- CPU使用率の監視
- ディスク使用率の監視
- 条件を満たした際の通知の送信
- システム情報のログ記録
はじめに
AWS CloudWatch アラーム通知 と シェルスクリプトによるシステム監視の区別について
< AWS CloudWatch アラーム通知 >
AWS CloudWatchアラームは、Cloudwatchのメトリクスやログを収集して、メールなどで通知を行うことができる機能です。
主な特徴は以下の通りです。
■ AWSリソースへの統合:EC2インスタンス、RDSデータベースなどのAWSリソースを監視できる。
■ メトリクスに基づく警告: ユーザー定義の閾値を超えた場合に通知を送信できる。
■ 自動的なリカバリー: 通知を受け取った場合に、自動的なリカバリーアクションを実行できる。
< シェルスクリプトによるシステム監視 >
シェルスクリプトを使用したシステム監視は、AWS CloudWatchアラームとは異なり、以下の特徴があります。
■ カスタマイズ性: ユーザーは特定のメトリクスや条件を自由に定義できる。
■ 独自の通知方法: AWS SNS以外にも、メール、Slack、APIコールなどさまざまな通知方法が利用可能。
■ 非AWSリソースの監視: AWS以外のサーバーやシステムも監視可能。
システムの安定稼働は非常に重要です。特にサーバーやクラウドインフラの場合、リソースの適切な管理が必要です。
AWS CloudWatchアラーム通知は良く使われているかと思いますが、サーバーが数多く存在する場合、それぞれのサーバーごとにアラームを作成するのにも、人件費がかかっております。
そこで、この記事では、システム監視スクリプトを作成し、AWS SNS(Simple Notification Service)を使用して異常時に通知を受け取る手順をご紹介します。
シェルスクリプトによるシステム監視の実装手順
以下に、Linux環境でシステム監視スクリプトを作成し、AWS SNSを使った通知を設定する手順を説明します。
事前準備
実装する前に、以下の事前準備が必要です。
- EC2 インスタンスが起動している状態
- rootユーザーでログイン出来ている状態
A newer release of "Amazon Linux" is available. Version 2023.1.20230906: Version 2023.1.20230912: Version 2023.2.20230920: Run "/usr/bin/dnf check-release-update" for full release and version update info , #_ ~\_ ####_ Amazon Linux 2023 ~~ \_#####\ ~~ \###| ~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023 ~~ V~' '-> ~~~ / ~~._. _/ _/ _/ _/m/' Last login: Sun Sep 24 01:10:46 2023 from 111.111.122.212 [root@kuroda ~]#
■ 手順1: AWS SNSトピックの作成
まず最初に、AWSコンソールにログインし、SNSのダッシュボードに移動し、そこで新しいトピックを作成します。
- SNSダッシュボードで「トピックの作成」をクリックします。
- トピックの名前を入力し、適切な設定を選びます。
- トピックが作成されたら、ARN(Amazon Resource Name)を控えておきます。
■ 手順2: システム監視スクリプトの作成
-
新規ファイルの作成
vi system_monitor.sh 下記スクリプト内容を貼り付けてください。
-
スクリプトの実行権限を付与
chmod +x system_monitor.sh
-
スクリプト内容にある AWS SNS メールを送信部分をご自身の設定内容に入れ替えてください。
#!/bin/bash
# 6秒ごとに3回の使用状況表示
vmstat 6 3
# 現在のメモリ情報を取得
mem_total=$(free -m | grep "Mem" | awk '{print $2}')
mem_used=$(free -m | grep "Mem" | awk '{print $3}')
# メモリの合計値と使用中の値を表示
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
echo "現在のメモリ合計容量は $mem_total MB "
echo "$mem_used MB が使用されています."
# 使用率を計算して表示
mem_usage=$(awk "BEGIN {printf \"%.2f\", ($mem_used / $mem_total) * 100}")
echo "現在のメモリ使用率は $mem_usage% "
# CPU使用率を取得
cpu_usage=$(mpstat | awk '$12 ~ /[0-9.]+/ {print 100 - $12}')
# コアごと負荷情報
mpstat -P ALL
# CPU使用率を表示
echo "現在のCPU使用率は $cpu_usage% "
# ディスク使用率を取得
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | cut -d'%' -f1)
# ディスク使用率を表示
echo "現在のディスク使用率は $disk_usage% "
# メールを送信する関数
send_email() {
local subject=$1
local body=$2
# AWS SNS メールを送信
aws sns publish --topic-arn arn:aws:sns:ap-northeast-1:AWSアカウントID:SNSトピック名 --message "$body" --subject "$subject"
}
# 条件をチェックして、それぞれの場合にメールを送信
if (( $(echo "$cpu_usage >= 60" | bc -l) )); then
send_email "CPU使用率が60%以上になりました。" "現在のCPU使用率は $cpu_usage% です。"
fi
if (( $(echo "$mem_usage >= 60" | bc -l) )); then
send_email "メモリ使用率が60%以上になりました。" "現在のメモリ使用率は $mem_usage% です。"
fi
if (( $(echo "$disk_usage >= 80" | bc -l) )); then
send_email "ディスク使用率が80%以上になりました。" "現在のディスク使用率は $disk_usage% です。"
fi
# コマンドの実行を変数に格納
CpuRec=$(uptime)
MemRec=$(free -m)
DiskRec=$(df -hT)
LastUserLoginRec=$(last -20)
RecTime=$(date +"%Y-%m-%d %H:%M:%S")
# ログファイルのディレクトリを作成
mkdir -p /var/log/runrec
RecFile="/var/log/runrec/running-$(date +%Y%m%d%H%M)"
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
# ログの記録
{
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
echo "Record Time: $RecTime"
echo "Cpu Load information:"
echo "$CpuRec"
echo "Memory information:"
echo "$MemRec"
echo "Disk use information:"
echo "$DiskRec"
echo "Last login 20 users record:"
echo "$LastUserLoginRec"
} > "$RecFile"
# 出力通知
echo "詳細は$RecFileより確認してください。"
このスクリプトは、システムの使用状況をモニタリングし、特定の条件が満たされた場合にメールで通知するものです。また、定期的にシステムの状態を記録し、ログファイルに保存します。
-
mem_total=$(free -m | grep "Mem" | awk ‘{print $2}’): free -m コマンドを使って現在のメモリ情報を取得し、その結果からメモリの合計容量を抽出し、mem_total に代入します。
-
mem_used=$(free -m | grep "Mem" | awk ‘{print $3}’): 同様に、メモリの使用量を取得し、mem_used に代入します。
-
echo"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++": メッセージをコンソールに出力します。
-
echo "現在のメモリ合計容量は $mem_total MB ": メモリの合計容量をコンソールに出力します。
-
echo "$mem_used MB が使用されています.": 使用中のメモリ量をコンソールに出力します。
-
mem_usage=$(awk "BEGIN {printf \"%.2f\", ($mem_used / $mem_total) * 100}"): メモリの使用率を計算し、mem_usage に代入します。
-
echo "現在のメモリ使用率は $mem_usage% ": メモリの使用率をコンソールに出力します。
-
cpu_usage=$(mpstat | awk ‘$12 ~ /[0-9.]+/ {print 100 – $12}’): mpstat コマンドを使ってCPUの使用率を取得し、cpu_usage に代入します。
-
sudo mpstat: CPUの使用率の詳細情報を表示します。
-
echo "現在のCPU使用率は $cpu_usage% ": CPUの使用率をコンソールに出力します。
-
disk_usage=$(df -h / | awk ‘NR==2 {print $5}’ | cut -d’%’ -f1): ルートディレクトリのディスク使用率を取得し、disk_usage に代入します。
-
echo "現在のディスク使用率は $disk_usage% ": ディスク使用率をコンソールに出力します。
-
send_email() {…}: メールを送信するための関数 send_email を定義します。
-
if (( $(echo "$cpu_usage >= 60" | bc -l) )); then … fi: CPU使用率が60%以上の場合にメールを送信する条件文を設定します。
-
if (( $(echo "$mem_usage >= 60" | bc -l) )); then … fi: メモリ使用率が60%以上の場合にメールを送信する条件文を設定します。
-
if (( $(echo "$disk_usage >= 80" | bc -l) )); then … fi: ディスク使用率が80%以上の場合にメールを送信する条件文を設定します。
-
CpuRec=$(uptime): uptime コマンドを使ってCPUの負荷情報を取得し、CpuRec に代入します。
-
MemRec=$(free -m): メモリ情報を取得し、MemRec に代入します。
-
DiskRec=$(df -hT): ディスク情報を取得し、DiskRec に代入します。
-
LastUserLoginRec=$(last -20): 最後の20人のユーザーのログイン情報を取得し、LastUserLoginRec に代入します。
-
RecTime=$(date +"%Y-%m-%d %H:%M:%S"): 現在の日時を取得し、RecTime に代入します。
-
mkdir -p /var/log/runrec: ログファイルのディレクトリを作成します。
-
RecFile="/var/log/runrec/running-$(date +%Y%m%d%H%M)": ログファイルのパスを指定します。
-
> "$RecFile": ログファイルを作成します。
-
{…}: 波括弧内のコマンドをログファイルに追記します。
-
echo "詳細は$RecFileより確認してください。": ログファイルの場所をコンソールに出力します。
■ 手順3: クーロンジョブの設定
- 定期的な実行を行うために、cronジョブを設定します。
crontab -e
- 例えば、毎時実行する場合は以下のように設定します。
0 * * * * /infra/script/system_monitor.sh
以上で、システムの監視とAWS SNSを使用した通知の設定手順が完了しました。
■ 動作確認の準備
-
CPU使用率を一時的に高めて行きます。
システムのリソースを使用するプロセスを起動する必要があります。以下はその例です:yes > /dev/null &
このコマンドは、
yes
コマンドを実行し、その出力を/dev/null
にリダイレクトします。これにより、CPUに対して常に計算が必要なタスクが生成され、使用率が上昇します。
検証完了後、このプロセスを停止するには、次のコマンドを使用します:pkill yes
-
ディスク使用率を一時的に高めて行きます。
システムのリソースを使用するプロセスを起動する必要があります。以下はその例です:dd if=/dev/zero of=6G.dummy bs=1MD count=6000
このコマンドは、/dev/zero デバイスから読み取りを行い、それを 6G.dummy という名前のファイルに 1MB のブロックサイズで合計 6000 回書き込むものです。この結果、サイズが約 6GB のダミーファイルが作成されます。
検証完了後、削除するのをおわすれずに! -
メモリー使用率を一時的に高めて行きます。
システムのリソースを使用するプロセスを起動する必要があります。以下はその例です:stress --vm 1 --vm-bytes 100M --vm-hang 0
stress
コマンドが利用できない場合:
stress
コマンドは一般的にLinuxシステムで利用できるツールですが、特定の環境やOSによっては事前にインストールする必要がある場合があります。
Amazon LinuxやAmazon Linux 2の場合、stress
パッケージはデフォルトで提供されていないため、手動でインストールする必要があります。
以下はAmazon Linux 2でstress
をインストールする手順です。
-
パッケージリストを更新します。
sudo yum update -y
-
stress
パッケージをインストールします。sudo yum install stress -y
以上の手順で
stress
コマンドが利用可能になるはずです。それ以外の環境やOSの場合は、環境に応じた手順でstress
をインストールしてください。
■ アラーム通知の受け取り
作成したスクリプトをサーバーに配置し、定期的に実行します。スクリプトはシステムの使用状況を監視し、一定の条件が満たされるとAWS SNSを介して通知を送信します。
- 以下は今回設定した条件の通知メールとなります。
最後に
この手順を実行することで、シェルスクリプトを使用してシステムの監視を行い、AWS SNSを介して通知を受け取ることができます。
これにより、システムの異常な状態が検出された場合に、適切な人物がすばやく通知を受け取ることができます。
以上、システムの監視とAWS SNSを使用した通知の設定が完了しました。
システムの安定性を保つために、定期的な監視と通知の設定を行ってください。
この記事では、システム監視スクリプトを作成し、AWS SNSを使用して通知を受け取る手順を紹介しました。これにより、システムの異常が発生した際に迅速に対応できるようになります。是非、お試しください!
では、皆さん、また次回お会いしましょう。
【AWS初心者向け】CloudWatch AgentでEC2インスタンスを監視・メトリクスの閾値を超えたらSNSで通知を送付
↑↑↑クラ本部メンバーが書いた記事のご紹介 ↑↑↑、合わせてやってみるのもいいかと