ボクココ

個人開発に関するテックブログ

Heroku サーバでタイムアウト発生時に自動で再起動する仕組みを作った

Heroku でそれなりのアクセスが来るサービスを運用していると、以下のようにタイムアウトが発生してユーザがアクセスできないような時間帯が出てきてしまうことがある。

Sep 20 17:57:12 heroku/router:  at=error code=H12 desc="Request timeout" method=GET path="/" host=herokuapp.com request_id=502759a1-afde-4f03-9266-5b3256a8c536 fwd="182.249.246.34" dyno=web.1 connect=3ms service=30000ms status=503 bytes=0 

何かしらアクセスが詰まっているようなので、これを受けた時は自動で heroku restart を実行したい。

ログ監視サービス

Heroku のアドオンで、 Papertrail というものがある。これは、HerokuのログをS3に置いたり、リアルタイムで監視して問題のあるログが出てきたときにアラートを出したりすることのできる超便利アドオンだ。本番環境で運用するHerokuアプリには是非入れておくべき。

さて、これを利用すれば、timeout発生時に所定の所へメールを送ることができる。そのメールを受け取ったタイミングで heroku restart を実行できれば完璧だ・・!

Papertrail でアラート管理

HerokuダッシュボードのResouces の下部にある追加したPapertrail をクリックし、Papertrailのダッシュボードへ遷移する。Papertrail のダッシュボードから timeoutのログが出てきたときに所定のgmailアカウントへメールを送るような設定をしておこう。

Mac のメールアプリ

Mac にはデフォルトでメールアプリがある。これを先ほどPapertrailで登録したGmail アカウントと紐付けて、そこからAppleScript を実行させればいけそうだ。AppleScriptMicrosoft でいうVB みたいなもんで、Mac用のプログラミング言語だ。もちろんこんな言語を習得する必要は全くない。ただこのAppleScriptからシェルスクリプトを呼び出せればそれで良いのだ。

AppleScriptの作成

Marverics での場合。他はどうだか不明

~/Library/Application\ Scripts/com.apple.mail/apple.scpt って名前のファイルを作る。 このファイルの中身は

do shell script "/bin/sh /path/to/sh/restart_heroku.sh"

そして restart_heroku の中身は

export PATH=$HOME/.rbenv/shims:$PATH
heroku restart --app nofap-revolution

まぁherokuコマンドを使えれば他にどんなスクリプトでもよい。

メールにルールを追加

そしたらそのスクリプトを登録するだけだ。

メール -> 環境設定 -> ルール -> ルールを追加

これで出来上がり!

試しにPapertrail と timeout の文字列のある件名を指定Gmailアドレスに送って、Papertrailでログを眺めていると、Heroku restart が実行されているのが確認できた。これの欠点は、自分のMacのメールアプリを常時起動しておかないといけないという点w

あ、やべ。。これメール立ち上げてなくて、立ち上げた瞬間にそのメールがあったらScript実行しちゃうじゃんw まぁそのくらいの頻度でのrestart走ってもいいか。。