LIFULLには社内の広告データ管理システムがあり、そこで多くのバッチ処理が動いています。
そのシステムでembulkのかなり古いバージョンを使ってしまっていて、こちらのIssuesにあるように、一部のエラーの場合でもexit codeが0になるような問題があります。例えば「10日間遡って広告データを取得する」バッチ処理で、一部の日付で取得エラーが発生しても正常終了として扱われるため、これらのミスを検知できないことがありました。
でも他の作業のため、なかなか必要なバージョンまでたどり着けない…という悩みがずっとあったのですが、ひとまず標準出力にあるエラーメッセージを使って対症療法で対応することにしました。
#!/bin/bash -eu
search_string="org.jruby.exceptions.RaiseException" # エラーメッセージにある文言
embulk_error_detected=0
# 一時ファイルを用意する
temp_output=$(mktemp)
embulk "$@" | tee "$temp_output"
if grep -iq "$search_string" "$temp_output"; then
embulk_error_detected=1
fi
rm -f "$temp_output"
if [ $embulk_error_detected -eq 1 ]; then
echo "embulk error detected"
exit 1
else
exit 0
fi
これで、embulkの呼び出し側をこのスクリプトの呼び出しに変更します。
- embulk run <オプション>
+ ./embulk_wrapper.sh run <オプション>
私はbashの実装に苦手意識があったのですが、ChatGPTやCopilotなどの生成AIですぐ対応できるようになったので改善が進みますね!
余談
元々は一時ファイルを用意しない方法を探していて、生成AIからこういうコードを提案されたのですが、実は embulk_error_detected
の変数が書き換わらなかったり(サブシェルでの実行扱いで変数更新できないらしいです)、
#!/bin/bash -eu
search_string="org.jruby.exceptions.RaiseException"
embulk_error_detected=0
embulk "$@" | while IFS= read -r line; do
echo -e "$line"
# if echo "$line" | grep -iq "org.jruby.exceptions.RaiseException"; then
if echo "$line" | grep -iq "$search_string"; then
embulk_error_detected=1
fi
done
if [ $embulk_error_detected -eq 1 ]; then
echo "embulk error detected"
exit 1
else
exit 0
fi
次はこういうコードになったのですが、本番環境では必要な権限 tee: /dev/fd/3: Permission denied
が無かったりと苦戦しました。AIがあっても(しばらくは)試行錯誤は人間の仕事みたいです。
#!/bin/bash -eu
search_string="org.jruby.exceptions.RaiseException"
embulk_error_detected=0
exec 3>&1
embulk_output=$(embulk "$@" | tee >(grep -iq "$search_string" && embulk_error_detected=1) | tee /dev/fd/3)
if [ $embulk_error_detected -eq 1 ]; then
echo "embulk error detected"
exit 1
else
exit 0
fi