おそらくはそれさえも平凡な日々

App::RunCron has been released!

https://metacpan.org/module/App::RunCron

tl;dr

cronlogより可搬性は落ちてシンプルさには欠けるけど、もうちょっと機能拡張してプラガブルな設定ができるruncronてやつを作った。コマンドの成功/失敗に応じて通知方法を変更できるようになっている。

本題

cronで困るのは、ログだったり通知であったりをどうするかというところです。

で基本的にどうするか、というところは@fujiwara組長の、 「cron で > /dev/null して椅子を投げられないための3つの方法」 に書いてあります。まとめると以下になります。

  • 全部メールで投げる(> /dev/null は論外)
  • 標準出力、エラー出力をまとめて、何らかのloggerに投げる(syslogがお手軽)
  • 場合によってはcronlogで選別して失敗した時のみ通知する

最近は以下のように、syslogを使わずにfluentdに投げたりしているプロジェクトもあります。

LOGGER="/usr/local/bin/fluent-agent-lite -f msg"
* * * * * /path/to/command 2>&1 | $LOGGER cron.command - fluentd-srv localhost

ただ、結局まとめて投げてしまうとノイズが多くなるし、ログの受け側で正しく選別したりとか、スクリプト側でちゃんとエラー時の処理を書いたりするのがめんどくさい。ログの受け側でコマンドの終了コードを知るのが難しいところも悩ましいところですね。

そこで、先程も少し触れましたが、安心と信頼のkazuho wareであるcronlogというものがあるわけです。

これは、コマンドの終了コードに応じて処理が分けられるようになっています。コマンド成功時は何も出力しないし、失敗時は標準出力に出力されるようになっているという具合です。--logfile で別途ログを残しておくことも可能です。一枚岩でPerlの標準モジュールだけで動くので、非常に可搬性に優れていて、完成されています。

ただ、これは元々、監視用途に寄っているユースケースなので、もうちょっと細かい制御をアプリケーションでやろうとすると、もう少し機能が欲しくなってきます。

具体的には以下のような感じです。

  • コマンド成功時、失敗時の通知処理を標準出力以外も指定したい
  • --log-fileが '%Y%m%d.log' とか指定できるようになっていて欲しい

そこで、それらを解決するべく、App::RunCronというものを作りました。かなりcronlogのコピペです。

% cpanm -v App::RunCron

で、runcronというコマンドがインストールされます。runcronは標準では、cronlogとほとんど同じ動きをしますが、引数を指定することにより、通知の振る舞いを変更することが可能です。一番簡単なのは、-cで設定ファイルを指定するか、実行ディレクトリに'runcron.yml'というファイルをおいておくことです。以下の様な具合です。

timestamp: 1
reporter:
  - Stdout
  - "+MyApp::Reporter::IRC"
error_reporter:
  - Stdout
  - "+MyApp::Reporter::IRC"
  - "+MyApp::Reporter::Alert"

こうすれば、コマンドが失敗した場合に、アラートを飛ばすことができるようになります。あとは以下のようにcrontabに設定するだけです。

LOGGER="/usr/local/bin/fluent-agent-lite -f msg"
LAUNCH="/home/app/project/env.sh runcron -- "
* * * * * $LAUNCH command ...  2>&1 | $LOGGER cron.command - fluentd-srv localhost

env.shはよくあるラッパーシェルで、これを噛ませると、環境変数を適宜設定した後、プロジェクトディレクトリにcdしてくれるようなやつです。

runcron --logfile=log/\%Y-\%m-%d.log とかも可能ですが、crontab内では、%にエスケープが必要なことにご注意下さい。

Reporterモジュールの作り方とかはドキュメント読んで下さい。非常に簡単です。

runcronコマンドを使わずとも、App::RunCronを直接使うことで独自のラッパーコマンドも簡単にお作りいただけます。

ロック機構入れようかと一瞬思ったけど、setlock使えばいいよねってことで却下しました。

お試し下さい。

created at
last modified at

2016-01-05T02:27:33+0900

comments powered by Disqus