ロードアベレージを監視するシェルスクリプトを作成してみた

公開日: : プログラム ,

このブログを運用している Linux サーバの負荷が高い状態になってました。
何か被害にあったとかではなく原因はボクにあったのでひと安心でしたが、反省の意味も含めて今後こういうことがあった場合に警告してくれるスクリプトを作成してみました。

icatch-9214710040_822a4c3456_z

photo credit: Some rights reserved by Nomadic Lass

目次

1. 監視スクリプト作成の背景

先日このブログを運用している Linux サーバでちょっとした作業を行いました。
作業中、処理が重たく感じたので top コマンドで CPU などのリソース類の状態を確認すると、CPU のユーザプロセスがほぼ100%の状態になっていました。

100%になっていた原因はウィルスとかではなくボクにあったので、とりあえずひと安心なのですが監視ツールの必要性を実感しました。

Nagios などの監視ツールをインストールしてさらりと済ませようかと考えましたが、監視スクリプトを自作することにしました。
ツールをインストールして良からぬ副作用が発生したら面倒だなぁってのがあったのと、リッチなものではなくシンプルな監視スクリプトで充分だったってのが理由です。

2. 監視処理の内容

シンプルにロードアベレージだけを監視する内容にしました。
なぜロードアベレージなのかというと、その理由を引用しておきます。

語弊を恐れず言えば Load Averageが高い ≒ サーバ負荷が高い ≒ 重い ≒ 応答速度が遅い

Load Average(ロードアベレージ)とCPU数 – tweeeetyのぶろぐ的めも

ロードアベレージを取得して、その値が CPU の数を超えていたら通知します。
再び同じ記事からの引用になりますが、CPU の数と比較するのは次の理由からです。

コマンド(uptimeなど)でLoad Averageを表示した場合に Load Averageの値がCPUの数より大きい場合、「Load Averageが高い」( 負荷が高い、重い )

Load Average(ロードアベレージ)とCPU数 – tweeeetyのぶろぐ的めも

通知手段はボクだけに知らせればいいのでメールにしました。

3. 監視スクリプト

作成したスクリプトは次の通りです。

#!/bin/sh

LOAD_AVERAGE=`uptime | sed -e 's/.*average: //g' -e 's/,//g' | awk '{print $2}'`

LOG_FILE=/path/to/directory/`basename $0 | sed -e 's/.sh//g'`.log
echo `date +"%Y/%m/%d %H:%M:%S"`,${LOAD_AVERAGE} >> ${LOG_FILE}

THRESHOLD=`grep 'processor' /proc/cpuinfo | wc -l`
    # カーネルが認識する CPU 数。閾値として使用
    # 参考 http://d.hatena.ne.jp/kakurasan/20110117/p1

COMPARE=`echo "${THRESHOLD} < ${LOAD_AVERAGE}" | bc` 
if [ ${COMPARE} = 1 ]; then
    # 閾値を超えたのでメールで通知
    MAIL_ADDRESS=mail@add.ress
    SUBJECT="${HOSTNAME} サーバ: CPU のロードアベレージ(${LOAD_AVERAGE})がしきい値(${THRESHOLD})を超えました"
    BODY=""
    echo ${BODY} | mail -s ${SUBJECT} ${MAIL_ADDRESS}
fi

uptime | sed -e 's/.*average: //g' -e 's/,//g' | awk '{print $2}' の部分でロードアベレージを取得しています。
直近5分のロードアベレージを取得しています。
5分のものにしている理由は、この後に書きますが、このスクリプトを5分間隔で実行するからです。

取得したロードアベレージは動作確認の意味も含めてログに出力します。
cron で運用するため吐かれたログを見て、スクリプトが正常に動作しているかを確認します。ログはとても大事。

ログファイルは "/path/to/directory" と書いているディレクトリに作成されます(実際には適切なパスに変更しています)。
ファイル名はこのスクリプトファイル名の拡張子を log に変換したものとなるようにしました。
このログファイルに次のような内容でログが出力されていきます。

2014/07/01 10:00:01,0.00
2014/07/01 10:05:01,0.01
2014/07/01 10:10:01,0.04

CPU の数は grep 'processor' /proc/cpuinfo | wc -l のようにして取得できます。
CPU の数は環境が変わらない限り固定値なので、毎回取得しなくてもいいんじゃないかって感じがしますが、環境が変わるたびにスクリプトを修正するのも面倒なのでこのようにしています。
大した負荷になるとは思えないのでこれでいいかなと。

取得したロードアベレージと CPU の数を比較するには bc コマンドを使用します。
test コマンドは小数点以下の値に対応していないようで、小数点以下の値が含まれる場合は bc コマンドを使うようです。
bc コマンドは、渡される式が正しい場合は 1 が返り、偽の場合は 0 が返る仕様になっています。

メール送信には mail コマンドを使います。
本文なし・件名のみのメールを送信するので、s オプションを付けて実行します。
上記のように echo などで本文を渡さないと、本文が入力されるまで待機してしまうので、空白文字を渡してやります。

4. cron 設定

最後にこのスクリプトの cron 設定です。
このスクリプトを5分間隔で実行したいので設定は次のようになります。

*/5 * * * * /path/to/script

"path/to/script" の部分をこのスクリプトの絶対パスで置き換えます。
あとは、このスクリプトのパーミッションを適切なものに設定すれば5分間隔で動きます。

5. まとめ

以上、シンプルなロードアベレージ監視シェルスクリプトの作成についてでした。

Linux の知識に乏しいこともあって、この程度のシェルスクリプトを作成するだけでもいろいろと調べることがたくさんありました。

  • サーバの負荷状態を知る手がかりとしてロードアベレージを参照する
  • その際、CPU の数を考慮して状態を判定する

6. その他 Linux に関する記事

その他の Linux に関する記事は次の通りです。
気になる記事があったらぜひチェックしてみてください!

Googleアドセンス用(PC)

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

関連記事

icatch_5428744075-resized

scp を使ってファイルのコピーを実行したら “command not found” と表示されたときの対処法

CentOS が起動しているサーバに scp を使ってファイルをコピーしようとコマンドを実行したら

記事を読む

no image

VPS に Redmine を設置したときに対処したトラブル

Redmine のインストール自体は Redmine 2.3をCentOS 6.4にインストールする

記事を読む

icatch-jersey_multi_pathparams

Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format} のような URL も以下のよう

記事を読む

icatch-markdown_14bd207bd7_mini-thumbnail

Markdown記法のテキストに書いたソースコードをシンタックスハイライトするプラグイン

SublimeText3 で拡張子が md のファイルを開いたときに、文章中に書かれたプログラムのソ

記事を読む

icatch-8587724648_24926df337_z-resized

yum のリポジトリ ATrpms を参照できるように設定する

あるツールの動作検証をしようと調べたところ、そのツールは ATrpms リポジトリが提供しているとの

記事を読む

icatch-back-scratcher_3553512020_mini-thumbnail

Sublime Text3 で JavaScript を書くために設定したプラグインとキーバインド

プロフィール にもあるように、ボクは Java をメインとしたプログラマです。 IDE には Ecl

記事を読む

icatch-vacuum_9060011568_mini-thumbnail

GitHub にアップされているブランチをローカルに取り込む

GitHub に限らず、会社や自分で Git のサーバを使った場合にも当てはまりますが、毎回同じこと

記事を読む

icatch-medium_4301351732-resized

mp3splt を実行して “undefined symbol: mp3splt_u_check_if_directory” と出力されたときの対処法

mp3 ファイルを分割してくれる mp3splt というライブラリがあります。 mp3 ファイルを

記事を読む

icatch_442682895-resized

scp コマンドを yum を使って CentOS にインストールする

小ネタです。 yum install scp ではなかったのでメモしておきます。 photo

記事を読む

icatch-pray_c916c87577_mini-thumbnail

Eclipse がエラーメッセージを出力して起動しなくなった場合の対処法

Eclipse の exe ファイルをクリックすると(または、実行すると)、 Eclipse のスプ

記事を読む

Googleアドセンス用(PC)

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


九 × = 54

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Googleアドセンス用(PC)

icatch-jersey_multi_pathparams
Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format}

icatch-vagrant_box_customize
VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を

icatch-2015-006-1
バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増え

icatch-2015-005-1
ユニットテストの偏りを防ぐ命名規則の付け方

ユニットテスト名に以下の命名規則を付けるようにして二ヶ月ぐらい経った。

icatch-2015-004-1
Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に

→もっと見る

PAGE TOP ↑