hubotを使ってあれこれする(mongodbをtailする)
サイトの50xエラー発生時になるべくリアルタイムで社内に周知する。
運用しているサイトで50xエラーが発生した際に、なるべくリアルタイムで社内に周知したいと考えていました。 nginxのログはcapped属性でmongodbにも集約しているので、これを常時tail監視してエラー検知時にアラートを発報するようにします。 さらにhubotのスクリプトとして動くようにすれば、hipchatにも周知しやすくなるので、今回はhubotのスクリプトにしました。(下記のサンプルではhipchatに流していませんが・・・)
簡単な仕様
- 動きとしては、mongoのカーソル使ってログを500系エラーのログのみtailするようにします。
- エラーかどうかはngxinログのupstream_statusのステータスコードで判定します。
- 該当データが発生した場合はonイベントで音を鳴らすようにします。音はafplayコマンドで指定のアラート音を鳴らすだけです。
- 瞬間的に大量の50xエラーが発生した場合、afplayコマンドが多重で大量に叩かれてプロセス生成できなくなるエラーが発生したので、afplayプロセス起動中は別のafplayが起動できないようにフラグ管理しておきます。
フラグはhubotのbrain(redis)で保持します。
scripts/mongo_tail.coffee
util = require('util') mongojs = require('mongojs') spawn = require("child_process").spawn; HOST = process.env.MONGO_HOST DB = process.env.MONGO_DB COLL = process.env.MONGO_COLL ALARM = "alarm_flag" FLAG_RESET_INTERVAL = 1 * 60 * 1000 SITE = "mysite" module.exports = (robot) -> cursor = {} db = {} robot.brain.set(ALARM, false) setInterval(()-> robot.brain.set(ALARM, false) , FLAG_RESET_INTERVAL) alarm = (site, doc) -> console.log("site:" + site) console.log(doc) unless robot.brain.get(ALARM) robot.brain.set(ALARM, true) cli = spawn("/usr/bin/afplay", ["/se/" + site + doc.upstream_status + ".mp3"]) cli.on 'exit', (code) -> robot.brain.set(ALARM, false) db = mongojs(HOST + '/' + DB, [COLL]) cursor = db[COLL].find({upstream_status:/50\d/}, {}, tailable: true timeout: false) cursor.on 'data', (doc) -> alarm(SITE, doc) return