システム状態(負荷とメモリ)を定期的にログに記録

  • 投稿日:
  • 更新日:2015/02/26
  • by
  • カテゴリ:

システム状態を定期的に記録したい

サーバを運用していると、ときどきシステムが不安定になることがあるので、定期的に状態を記録したくなります。

Tiny Core Linuxではvmstatなどの高級な(?)コマンドが最初からインストールされていないので、busyboxだけで実現できるようにします。

ログに記録する内容ですが、

  • ロードアベレージ(uptimeで見られるもの)
  • フリーメモリ(freeで見られるもの)

これらを1行に整形して一定時間ごとに以下のような形式でファイルに書き出すようにしたいと思います。

2015-02-03 12:00:00 load 0.03, 0.10, 0.05 free 400

クイックな説明

そのためのプログラムは以下の通りです。ここでは仮に /root/uptime.sh という名前にします。

#/bin/sh
echo `date +"%Y-%m-%d %H:%M:%S"` load `uptime | awk -F"average:" '{print $2}'` free `free -m | awk '/\-\/\+/ {print $4}'`

もちろん/root/uptimeには

$ sudo chmod a+x /root/uptime.sh

で実行権限を与えておきます。

これを定期的に実行するため、crontabに以下を追加します。 この例では、5分ごとに実行しています(下記は2行以上に見える場合もあると思いますが、実際は1行です)。

*/5 * * * * /root/uptime.sh  >> /usr/local/var/log/uptime.log

10分毎が良ければ最初の"*/5"を"*/10"にすればokです。 cronのフォーマットについて詳しくは別に書いていますので、必要に応じて参照してください。

以上で、 /usr/local/var/log/uptime.log というディレクトリに5分ごとにロードアベレージとその時のフリーメモリが出力されます。

詳しい説明

上記で書いたuptime.shスクリプトについて説明します。 実質2行目のechoだけが実行される1行スクリプトなのですが、長いので、分割して一つづつ説明します。

1. 日時の出力

date +"%Y-%m-%d %H:%M:%S"

これは実行時間をを"2015-02-23 12:00:00"のような形式で出力します。

2. ロードアベレージの出力

uptime | awk -F"average:" '{print $2}'

uptimeの出力は起動からの時間で変わることがあります。 例えばこんな風に。

12:00:00 up 5 days,  6:28,  1 user,  load average: 0.01, 0.03, 0.05
12:00:00 up  1:15,  3 users,  load average: 0.03, 0.10, 0.05

そのため、"average:"以降の文字列を出力するようにしています。

ちなみに、次のように正規表現を使っても同じことができます。

uptime | awk '{sub(/.*average:/,"",$0);print $0}'

3. フリーメモリの出力

free -m | awk '/\-\/\+/ {print $4}'

フリーメモリを出力するコマンド"free -m"のフォーマットは以下のようになっています(一例なので値は適当です)。

             total    used    free  shared buffers  cached
Mem:          1600    1200     330       1      20      40
-/+ buffers:          1200     400
Swap:         1600       0   16000

このうち、取得したいのは"-/+"がある行の"free"の部分、上で言うと400という数値なので、それをawkで取得しています。

これで、出力は以下のようになります。

2015-02-03 12:00:00 load 0.03, 0.10, 0.05 free 400

これをcronで定期実行させれば、ログファイルに履歴が残るというわけです。

しばらく動かして見てみましたが、freeの部分が徐々に減っていくんですよね。なんか怖い。というわけで、この調査をベースによく調べると不安定の原因はメモリ不足にありそうなので、Swapに関する対策を施しました

(13 Feb 2015 Updated)

私のサーバでは、/root/uptime.sh を以下のようにしました。

#/bin/sh
echo `date +"%Y-%m-%d %H:%M:%S"` load `uptime | awk -F"average:" '{print $2}'` free `free -m | awk '/\-\/\+/ {print $4}'`+` free -m | awk '/Swap/ {print $4;}'`

赤字の部分を追加しました。スワップスペースの残りを表示するためです。これで、出力は次のようになります。

2015-02-13 12:00:00 load 0.03, 0.10, 0.05 free 400+1200

+1200の部分がswapの空き領域を表すわけです。

こちらもよく読まれています