ようへいの日々精進XP

よかろうもん

sensu から AWS の SNS を使ってアラートを飛ばしたい

おはようございます。

はじめに

sensuGraphite の連携については引き続きで追うとして...sensu にて異常を検知した場合に handler プラグインAWSSNS を利用するプラグインがあるのでそちらを利用させて頂いて通知を飛ばしてみたいなと思って試しているが現状は送れていないので、とりあえず handler の設定をメモる。


参考


設定

プラグイン

手動でプラグインを取得する。

cd /etc/sensu/handlers
sudo wget https://raw.githubusercontent.com/sensu/sensu-community-plugins/master/handlers/notification/sns.rb
sudo chmod 755 /etc/sensu/handlers/sns.rb

取得したプラグイン/etc/sensu/handlers 以下に置いて実行権限を付けている(一応)

config.json に追記

設定自体は /etc/sensu/conf.d/ 以下に置いても良さそうだが、/etc/sensu/config.jsonhandlers セクションに追記しておく。

  "handlers": {
    "default": {
      "type": "set",
      "handlers": [
        "stdout","sns"
      ]
    },
    "stdout": {
      "type": "pipe",
      "command": "cat"
    },
    // 以下追記
    "sns": {
      "type": "pipe",
      "command": "/etc/sensu/handlers/sns.rb",
      "topic_arn": "arn:aws:sns:ap-northeast-1:123456789012:hogehuga",
      "use_ami_role": "false",
      "region": "ap-northeast-1",
      "access_key": "AK123456789012345678",
      "secret_key": "1234567890123456789012345678901234567890"
    }
  },

"type": "pipe" を含む、以降の設定は必須。

check

例えば、以下のようなプロセスチェックにて "handlers": ["default"], とあるのでこの場合には上記の handlersdefault が適用されて nginx が落ちた場合等は SNS を介して Endpoint となるメールアドレス等に通知が飛ぶ...はず。

    "nginx_check": {
      "handlers": ["default"],
      "command": "/etc/sensu/plugins/system/check-procs.rb -p nginx -C 2 ",
      "interval": 60,
      "occurrences": 3,
      "subscribers": [ "monitoring" ]
    }

今のところ通知が飛ばない

異常を検知した際、handler から SNS に通知が飛んでいそうな瞬間に sensu-server.log に以下のようなログが残るところまでは確認出来ている。

{"timestamp":"2014-03-19T04:39:09.547104+0900","level":"info","message":"handler output","handler":{"type":"pipe","command":"/etc/sensu/handlers/sns.rb","topic_arn":"arn:aws:sns:ap-northeast-1:123456789012:hogehuga","region":"ap-northeast-1","access_key":"AK123456789012345678","secret_key":"1234567890123456789012345678901234567890","name":"sns"},"output":"Exception occured in SnsNotifier: undefined method `[]' for nil:NilClass\n"}
{"timestamp":"2014-03-19T04:39:09.547369+0900","level":"info","message":"handler output","handler":{"type":"pipe","command":"/etc/sensu/handlers/sns.rb","topic_arn":"arn:aws:sns:ap-northeast-1:123456789012:hogehuga","region":"ap-northeast-1","access_key":"AK123456789012345678","secret_key":"1234567890123456789012345678901234567890","name":"sns"},"output":"/etc/sensu/handlers/sns.rb:34:in `useAmiRole'\n"}
{"timestamp":"2014-03-19T04:39:09.547522+0900","level":"info","message":"handler output","handler":{"type":"pipe","command":"/etc/sensu/handlers/sns.rb","topic_arn":"arn:aws:sns:ap-northeast-1:123456789012:hogehuga","region":"ap-northeast-1","access_key":"AK123456789012345678","secret_key":"1234567890123456789012345678901234567890","name":"sns"},"output":"/etc/sensu/handlers/sns.rb:51:in `handle'\n"}
{"timestamp":"2014-03-19T04:39:09.547678+0900","level":"info","message":"handler output","handler":{"type":"pipe","command":"/etc/sensu/handlers/sns.rb","topic_arn":"arn:aws:sns:ap-northeast-1:123456789012:hogehuga","region":"ap-northeast-1","access_key":"AK123456789012345678","secret_key":"1234567890123456789012345678901234567890","name":"sns"},"output":"/usr/local/share/gems1.9/gems/sensu-plugin-0.2.2/lib/sensu-handler.rb:41:in `block in <class:Handler>'\n"}

むむ...なんか足りないのかな...。useAmiRole ってメソッドがあるけどこれって何に使うんだろう...。AMI って SNS のサービスには関係無さそう。もしかして IAM のことだったりしてw

追記(1)

aws-sdk for ruby を利用して SNS に通知を飛ばすサンプルスクリプト

#!/usr/bin/env ruby

require 'aws-sdk'

AWS.config(
  :access_key_id => 'AK1234567890',
  :secret_access_key => '1234567890123456789012345678901234567890',
  :region => 'ap-northeast-1'
)

(topic_arn, message) = ARGV
sns = AWS::SNS.new
t = sns.topics[topic_arn]
t.publish(message)

puts "\nMessage published"

引数に SNSARN とメッセージを渡せばエンドポイントで指定している通知先に通知が送られる。

追記(2)

プラグインruby スクリプトを弄っていたらアラートメールが飛ぶようになった(とりあえず)。

追記(2)の対処方法

/etc/sensu/config.json を以下のように設定。

  "handlers": {
    "default": {
      "type": "set",
      "handlers": [
        "stdout","sns"
      ]
    },
    "stdout": {
      "type": "pipe",
      "command": "cat"
    },
    "sns": {
      "type": "pipe",
      "command": "/etc/sensu/handlers/sns.rb"
    }
  }

/etc/sensu/handlers/sns.rb を以下のように修正。

--- sns.rb.original1    2014-03-19 12:52:54.341365921 +0900
+++ sns.rb      2014-03-19 12:54:22.024406246 +0900
@@ -22,45 +22,21 @@
     settings['sns']['topic_arn']
   end

-  def region
-    settings['sns']['region'] || 'us-east-1'
-  end
-
   def event_name
     "#{@event['client']['name']}/#{@event['check']['name']}"
   end

-  def useAmiRole
-    use_ami_role = settings['sns']['use_ami_role']
-    use_ami_role.nil? ? true : use_ami_role
-  end
-
-  def awsAccessKey
-    settings['sns']['access_key'] || ''
-  end
-
-  def awsAccessSecret
-    settings['sns']['secret_key'] || ''
-  end
-
   def message
     @event['check']['notification'] || @event['check']['output']
   end

   def handle
-    if (useAmiRole)
-      AWS.config(:region => region)
-    else
-      AWS.config({
-        :access_key_id => awsAccessKey,
-        :secret_access_key => awsAccessSecret,
-        :region => region
-      })
-    end
-
-    sns = AWS::SNS.new
-
-    t = sns.topics[topic_arn]
+    AWS.config(
+      :access_key_id => 'AK12345678901234567',
+      :secret_access_key => '123456789012345678901234567890',
+      :region => 'ap-northeast-1'
+    )
+    t = AWS::SNS::Topic.new('arn:aws:sns:ap-northeast-1:12345678912:hogehuga')

     if @event['action'].eql?("resolve")
       subject = "RESOLVED - [#{event_name}]"

とりあえずハンドラのスクリプトAWS の認証情報を直書きという暴挙に出てとりあえずはアラートは飛ぶようになったけど...(汗


むむ...

  • Graphite といい自分の中途半端感が否めないが引き続き調べる
  • とりあえず通知は普通のメールとかで代用出来ないかも検討する
  • sensu 奥深い