バッチあるある
- 出力全部捨ててる!
- ログがディスク圧迫!
- アラートが飛んでこないとか、 エラーでもないのにメールが来る!
- メール送信処理、ログファイル処理、ログローテート、、、などの本質的じゃないところの仕様どうしようとか、バグとか。
php
test.php
<?php
if(!defined('STDIN')) define('STDIN', fopen('php://stdin', 'rb'));
if(!defined('STDOUT')) define('STDOUT', fopen('php://stdout', 'wb'));
if(!defined('STDERR')) define('STDERR', fopen('php://stderr', 'wb'));
// これらは標準出力
echo "this is php debug message by echo()\n";
fputs(STDOUT, "this is php debug message by fputs(STDOUT).\n");
file_put_contents('php://stdout', "this is php debug message by file_put_contents(php://stdout).\n");
// こいつらはエラー出力
fputs(STDERR, "this is php error message by fputs(STDERR).\n");
file_put_contents('php://stderr', "this is php error message by file_put_contents(php://stderr).\n");
// これもエラー出力
trigger_error("trigger_error E_USER_NOTICE", E_USER_NOTICE);
trigger_error("trigger_error E_USER_WARNING", E_USER_WARNING);
trigger_error("trigger_error E_USER_ERROR", E_USER_ERROR);
exit(0); // 正常終了
exit(1); // 異常終了exit(1-254);
- 標準出力、エラー出力を分けよう
- 正常終了、異常終了を分けよう
- echo, fputs,などを色んな所に書くのではなく、ラッパー関数を作ってそれを呼ぶといいはず。logDebug($msg); logError($msg);とか。
shell
test.bash
#!/bin/bash
function create_pid {
echo $$ > $pid_file
}
function delete_pid {
rm $pid_file
}
function check_pid {
if [ -f $pid_file ]; then
pid=`cat $pid_file`
if (ps -e | awk '{print $1}' | grep $pid >/dev/null); then
echo "${0} is runnning, exit"
exit 1
fi
fi
}
function main {
echo "this is bash debug message." # 標準出力
echo "this is bash error message. 1>&2" 1>&2 # エラー出力
check_pid # 多重起動なら終了
create_pid # 多重起動チェック用ファイルを作成
# 外部プログラム実行して終了ステータスを判定
$batch_cmd
if [ $? -gt 0 ]; then
delete_pid # 多重起動チェック用ファイルを削除
exit 1 # 異常終了1-255
fi
delete_pid # 多重起動チェック用ファイルを削除
exit 0 # 正常終了
}
pid_file="/tmp/adachi-test-script-pid.`hostname`"
batch_cmd="/usr/bin/php /path/to/adachi/test.php"
main
- 標準出力、エラー出力を分けよう
- 外部プログラムの終了ステータスを判定しよう
- 正常終了、異常終了を分けよう
- 多重起動防止しておこう
cron
crontab
# メールを送らない設定。コメントには日本語も使えます
MAILTO=""
# MAILTOを上書きできます
MAILTO="yuki.adachi+foo@bar.com"
* * * * * cd /path/to/adachi; /bin/bash /path/to/adachi/test.bash >> /path/to/adachi/logs/`date +\%Y\%m\%d`.log
# MAILTOには複数のアドレスが設定出来ます
# 複数アドレスの時はダブルクォートなしで、,のあとのスペースもなしじゃなきゃダメかも?
MAILTO="yuki.adachi+hoge@hoge.com, yuki.adachi+hoge@foo.com"
# 1ヶ月前のログをfindして削除する
0 10 * * * find /path/to/adachi/logs/ -type f -name "`date +\%Y\%m\%d --date '1 month ago'`.log" -exec rm -f {} \;
# この例ではもともとメールを送らない設定だったのでもとに戻しておこう
MAILTO=""
- cronには出力をメール送信する機能があります。送信先はMAILTOで変えられます。MAILTO=""ならメール送信しません
- cron行ごとにMAILTOを設定できます。上書きできます
- 標準出力をログファイルにリダイレクトしよう
- ログファイルは20130620.logみたいな形式にしておこう
- 古いログファイルは適当に削除するcronもセットする
- プロジェクトルートにcdしておいたほうが楽できるよ
- 権限気にしなくて済むので/bin/bash /path/to/scriptが楽
こうすると
- デバッグログは必要な分だけ保存され続けるし、不要なメールは飛んで来ないし、エラーがあった時だけアラートが来る
- すでにあるlinuxアーキテクチャでつくるので、メール送信処理、ログファイル処理とか、むだに仕様決めなくて済む
- ちゃんと正常終了、異常終了のステータスを分けておくと/var/log/syslogにそれっぽく出てくれます。
そうは言っても
- fluentdでログったりもありえるし、個別にアラートメールしたりもする。ログファイルを自前で処理したり。アプリケーションによってはこれらは必要です。好きにすればいいよ
- フレームワークがあるならそれを使えば良いとおもいます。