12/08/2018, 00:02

Monitが生きていることをCloudWatchで監視する(Ruby版)

Monit サーバーの運用監視を行うために色々なソフトウェアがあります。 その中でもMonitは設定が簡単で、サービスの再起動も自動で行えるなど、非常に使いやすいです。 なので、基本的には全サーバーにMonitを入れて自分自身の監視を行わせています。 ただ、Monit自体が異常停止してしまうと気付かない、という問題があります。 これまで突然死に遭遇したことは無いですが、仮に死んでしまった時には気付きたいです。 複数台サーバーがあればお互いに監視させても良いですが、SPOFを作らないように5台のサーバーに相互監視させる、となると結構面倒です。 ...

Monit

サーバーの運用監視を行うために色々なソフトウェアがあります。 その中でもMonitは設定が簡単で、サービスの再起動も自動で行えるなど、非常に使いやすいです。

なので、基本的には全サーバーにMonitを入れて自分自身の監視を行わせています。

ただ、Monit自体が異常停止してしまうと気付かない、という問題があります。 これまで突然死に遭遇したことは無いですが、仮に死んでしまった時には気付きたいです。

複数台サーバーがあればお互いに監視させても良いですが、SPOFを作らないように5台のサーバーに相互監視させる、となると結構面倒です。

そんな時は、CloudWatchにMonitを監視させると便利です。 AWSを良く利用するので、リソース監視と併せて、Monitも監視させましょう。

環境

ざっくりと要点は以下です。

  • Ubuntu 12.04
  • Ruby 2.1.0
  • rvm

Rubyがインストールされていて、Javaがインストールされていない環境を想定しています。 rvmはシステムインストールしています。

設定

以下の2ステップで設定します。

  1. 監視対象のサーバーから定期的にMonitのプロセス数を CloudWatchへカスタムメトリックとして送信する
  2. CloudWatchで 1. で設定したカスタムメトリックの数字が1になっていることを監視する

監視対象サーバーでの作業

Monitのプロセス数を確認するRubyスクリプトを作成

こんな感じです。

#!/usr/local/rvm/rubies/ruby-2.1.0/bin/ruby

require "aws"
instance_name = Net::HTTP.get "169.254.169.254", "/latest/meta-data/instance-id"
count_of_monit_process =  `ps -e|grep monit|wc -l`.chomp
cw = AWS::CloudWatch.new(
  access_key_id: ENV["CW_ACCESS_KEY_ID"],
  secret_access_key: ENV["CW_SECRET_ACCESS_KEY"],
  region: "ap-southeast-1"
)
cw.put_metric_data(
  namespace: "Processes",
  metric_data: [{
    metric_name: "MonitProcesses",
    dimensions: [{
      name: "InstanceId",
      value: instance_name
    }],
  value: count_of_monit_process}]
)

監視対象サーバーがAWSであれば、そのサーバーから http://169.254.169.254/latest/meta-data/instance-id にアクセスすると、インスタンスIDが取れます。

監視対象サーバーがAWSで無ければ適当なものを指定します。

また、AWSというgemを利用するので、適切な権限を持ったユーザーでインストールしておきます。

$ gem install aws

~/.profileファイルにAWSのAPI認証情報を追加

deployというユーザーで監視するとします。このユーザーの~/.profileファイルの最後に下記を追加します。

export CW_ACCESS_KEY_ID="ABCDEFGHI0JKL1MNOPQR"
export CW_SECRET_ACCESS_KEY="abcdefghijklmnopqrstuvwxyz1234567890ABCD"

環境変数名は先のRubyスクリプトと合わせておきます。 CloudWatchに書き込みができるIAMユーザーのものを設定して下さい。

試しに実行してみましょう。

$ /usr/local/bin/check_procs.rb

何もエラー等が表示されなければOKです。 CloudWatchの管理画面へログインして、カスタムメトリックが増えているか確認しましょう。ProcessesというnamespaceにMonitProcessesというmetric名で登録しました。

8e45415e-fad3-48e1-6265-e9559de38f5d.png

実行したサーバーのインスタンスIDで「1」が登録されていればOKです。

b056c8af-3046-e126-0461-d4f44a5887ea.png

可能であれば、Monitを停止した状態で再度スクリプトを実行し「0」が登録されることも確認します。

cronに設定して定期的に情報をCloudWatchへ送る

動作確認ができたらこれをcronから自動実行しましょう。5分間隔に設定しました。

$ crontab -e

1行追加します。

*/5 * * * * . /home/deploy/.profile; GEM_HOME=/usr/local/rvm/gems/ruby-2.1.0 /usr/local/bin/check_procs.rb >> /home/deploy/cron.log 2>&1

cronからの起動も~/.profileが呼ばれたように記憶していたのですが、しなかったので読み込ませています。 また、rvmのためにGEM_HOME環境変数を付けて起動しています。

この状態で、しばらく放置して、先程と同様にCloudWatchの管理画面のカスタムメトリックにちゃんと数字を登録できているか確認しましょう。

もし、CloudWatch側に登録がされなかったらログファイル/home/deploy/cron.logを確認して対応します。

CloudWatch管理画面での作業

監視項目を追加する

CloudWatchの管理画面から「Create Alarm」を選択します。 「Custom Metric」をプルダウンから選択すると簡単に絞り込めます。

073999ea-08a2-da24-cc59-4da849c83cbb.png

対象のサーバーにチェックを付けて「Next」を押します。

88336d04-8e43-ecbf-ab3d-268e7287238b.png

アラートを出す閾値は「1未満(< 1)」にします。その他の条件は運用ポリシーに沿って決めます。 最後に「Create Alarm」を押せば完了です。

可能ならば、実際にMonitを停止して動作確認をします。

0