2016/03/30

horensoのSlack reporterを書いた

すっかり季節は年度末ですね〜。なんと明後日には新年度で新入社員が入社してくるぞ!! ということで新卒研修の準備に追われてる今日この頃ですが、みなさまいかがお過ごしでしょうか。

さて、研修準備も長々やると疲れてくるのでちょっと現実逃避に…というわけではないんですが、最近horensoというGoogleじゃないほうのcronなどでコマンドをwrapして成功失敗の通知を仕組み化するツール(詳しくは作者のSongmuさんのブログをご参照ください)用にSlack Reporterを書きました。ちなみにGoogleのhorensoは漢字入力システムです。

で、きっと今どきのWeb系の会社はSlack使ってるところ多いし、社内の各プロジェクトで汎用的に使えるように作ったから勢いよく全世界に公開しておくか〜と思った次第なので、この記事を(現実逃避に)書いてます。この前とある勉強会に行ったときも自席から前側の人たちのMacでSlackっぽい画面が出てる率がだいぶ高かったのですごい浸透してるんだなぁと驚きました。

このSlack Reporterはperl製です。Perlの標準モジュールしばりで書いたので、Perl 5.14以降であれば基本的に追加のCPANモジュール無しで動きます(Perl 5.12以前を使ってる人はJSON::PPをインストールしてください)。SlackのAPIを呼ぶ以上HTTPS通信が必要なんですが、そこはcurlコマンドを使っていますのでcurlの入ったLinuxシステムになっている必要があります(BSD系はちょっとわかりません)。

ということでこちらです: https://gist.github.com/acidlemon/f8faacd20e575fff05cf67a254ab6bc7

horensoがrepoterを呼び出すときにはとくにカスタムオプションみたいなのを渡す機能はないので、reporterのオプションは外部から環境変数で与えています。実際の利用シーンでは以下のようなスクリプトを書いてcronでスクリプトを呼ぶようにしてhorensoから実行ジョブを呼び出すことになるので、環境変数で十分でしょう。

#!/bin/sh
export PATH=/opt/perl-5.20.2/bin:/home/app/bin:/usr/local/bin:$PATH

cd /path/to/project

export SLACK_ENDPOINT="https://hooks.slack.com/services/T0XXXXXX/B0XXXXX/XXXXXX"
export SLACK_USERNAME="おしらせBOT"
export SLACK_ICON_EMOJI=":cop:"
export SLACK_CHANNEL="#my-project"
export SLACK_MENTION="@acidlemon"
export SLACK_MUTE_ON_NORMAL=1
export SLACK_PASTEBIN_CMD="my-pastebin"

exec horenso -r script/cron/slack_reporter.pl -- \
    setlock -Xn /var/tmp/my-cron-job.lock \
    carton exec perl  script/cron/my-cron-job.pl

cronで頻繁にまわすやつだと二重実行されないようにsetlockを併用するパターンになりますが、その時はhorensoとsetlockのどっちを外側にするか? みたいな話を考えることになります。上記は「普通は次の実行までに終わってるはずだからsetlockが二重実行でエラーになったときは異常なので知りたい」というのをhorensoで拾うというパターンの例になっています。逆に「カジュアルによくsetlockで実行を1回スキップすることあるわ〜」というときはsetlockを外側にして内側でhorensoを実行すればよいですね。

以下は簡単な環境変数の説明です。ENDPOINT以外は省略可能です。

SLACK_ENDPOINT

Incoming WebhookのエンドポイントURLを指定してください(必須です)。

SLACK_USERNAME

Slackで通知してくるBOTのユーザ名です。未指定の場合slackbotになります。

SLACK_CHANNEL

Slackの通知先チャンネルです。未指定の場合は勇敢にも#generalに投げちゃいます。

SLACK_MENTION

horensoで通知するときにmention飛ばしたいアカウントを書きます。複数指定したいときは"@acidlemon @fujiwara"のようにスペース区切りで書いておけばよいです。未指定の場合にはなにも起きません。

SLACK_MUTE_ON_NORMAL

正常終了のときは通知いらないよ! という場合は1を指定してください。たとえば2分に1回走るから正常終了で通知したらエラいことになるけど、失敗したのは知りたいというときに使います。未指定の場合は成功失敗関係なくSlackに実行結果情報を送ります。

SLACK_PASTEBIN_CMD

ここになんか外部コマンドを指定しておくと、horensoからもらったコマンドの出力(標準出力と標準エラー出力をマージしたもの)を指定したコマンドの標準入力に渡して外部コマンドを呼び出します。で、外部コマンドの出力をSlackに送るメッセージに含めます。指定しなかった場合はSlackに直接horensoで実行したコマンドの出力を送ります。

ざっくりいうと、horensoで実行したコマンドの出力がとても長い場合に、pastebin的なところに貼り付けておいて、SlackにはそのpastebinのURLをショートカットとして送りたい、という時に使います。という説明で通じるでしょうか!!

という感じです。なお、horensoには大量の出力を吐くとhorensoプロセスが残ってしまうというバグがあることが分かったのですが、今日修正のPRがマージされたのでこちらがリリースされてから本番投入するのがオススメという感じになっています。よろしくおねがいします🙏

うされもん @acidlemonについて

|'-')/ acidlemonです。鎌倉市在住で、鎌倉で働く普通のITエンジニアです。

30年弱住んだ北海道を離れ、鎌倉でまったりぽわぽわしています。

外部サイト情報

  • twitter
  • github
  • facebook
  • instagram
  • work on kayac