Apacheがトラフィックを監視して勝手にtweetしてみた(mod_mruby + iij/mruby)

少し前に、IIJさんによってmrubyの拡張ライブラリが公開されました。個人的にも待ちに待った公開だったので、これを使ってmod_mrubyで試しに何かしてみようと思い、エントリ名みたいな事をやってみました。

やったこととしては、

  • mod_mrubyをiij/mrubyの拡張ライブラリ版に対応
  • mod_mrubyでトラフィックを監視して閾値を超えたらtweetする機能を実装

です。

mod_mrubyをiij/mrubyの拡張ライブラリ版に対応

以下のように、Githubからmod_mrubyをダウンロードしてmakeすれば、iij/mruby拡張ライブラリ版のmod_mrubyがビルドされます。

make extend

インストールは今までどおりです。

make install

iij/mrubyの拡張ライブラリを使う事によって、mrubyで以下のようなクラスやメソッドが使えるようになります。ざっくりとリストアップしておきます。

  • 追加クラス
    • Digest
    • Env
    • File
    • IO
    • Process
    • Regex
    • TCP Socket
    • UNIX Socket
    • Syslog
  • 拡張クラス
    • Array
    • Kernel
    • String

細かい内容はiij/mrubyのgithubを見て下さい。mod_mrubyで追加したクラスとかぶっている所もありますが、変に先行で追加せずに公開を待ってよかったです。これからは、こちらを使っていこうと思います。これらが今後、mrubyの拡張ライブラリのスタンダードになれば良いですね。

mod_mrubyでトラフィックを監視して閾値を超えたらtweetする機能を実装

ということで、早速iij/mrubyを使って上記のような機能を実装してみました。これは非常に簡単で、mrubyでのtweetのサンプルをほとんどIIJさんが作ってくれていたので、それをmod_mruby用に少し改良してみただけです。ソースはgistに上げているので御覧ください。メインの処理は大体以下のようになっています。

class Traffic
  def initialize(rate)
    @rate = rate
  end
  def kbcheck
    sb = Apache::Scoreboard.new()
    kbpersec = sb.total_kbyte / sb.uptime * 100
    Apache.errlogger(4, "kbpersec: " + kbpersec.to_s)
    if kbpersec > @rate
      true
    else
      false
    end
  end
end

#
# mod_mruby_tweet phase
#

CONSUMER_KEY        = ''
CONSUMER_SECRET     = ''
ACCESS_TOKEN        = ''
ACCESS_TOKEN_SECRET = ''

simple_oauth = SimpleOAuth.new(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

r = Apache::Request.new()
r.content_type = "text/html"

# traffic kbyte / sec is 10000(10MB/sec)
threshold = 10000

t = Traffic.new(threshold)
if t.kbcheck
  msg = sprintf("mod_mruby: Traffic exceeded %s kbyte/sec on %s", threshold,  Time.now.to_s)
  response = simple_oauth.post('http://twitter.com/statuses/update.json', {
    :status => msg
  })
  if response.code.to_i == 200
    Apache.errlogger(4, sprintf("tweet success: '%s'", msg))
  else
    Apache.errlogger(4, sprintf("tweet failed: '%s'", msg))
    Apache.errlogger(4, response.body)
  end
end

Apache::return(Apache::DECLINED)

上記のコード内に、Twitterのhttps://dev.twitter.com/ からCreate appをして、CONSUMER KEYやACCECC TOKENを発行して登録します。そして、 例の如く、このスクリプトをApacheのconf、例えばmod_mrubyの設定であるmrubyAccessCheckerMiddleあたりに登録しておけば、アクセス時にApache内部のaccess_checkerフェイズでこのmrubyスクリプトをフックします。

このスクリプト内にthresholdで指定したトラフィック、例えば上記のサンプルコードのように10000KB/secを超えていたら、Apacheが勝手にそれを検知してtweetします。ですので、このままの実装だと、大量にアクセスがあるとその都度tweetしまくりますので、注意が必要です。即座にスパム登録されるでしょう。

きちんと、超過が継続中の場合はtweetせずに、超えた時あるいは下回った時だけtweetするような実装をした方がよいと思います。tweetが成功したかどうかをApacheのエラーログに記録するようにしています。

テストで閾値を0にしてみてためしてみると、きちんと以下のようにtweetされました。

 

 

 最後に

このように、Apacheモジュールで書こうとするとそれなりに大変なApacheの内部処理もmod_mrubyを使えば簡単にRubyで実装できちゃいます。また、mod_mrubyはかなり高速に動作しますので、性能劣化の心配も最小限に抑える事ができるでしょう。

IIJさんのおかげで、mod_mrubyを使ってApacheの内部をコントロールするための実装の幅が増えたと思われます。ありがとうございました!

「Apacheがトラフィックを監視して勝手にtweetしてみた(mod_mruby + iij/mruby)」への1件のフィードバック

コメントは受け付けていません。