BigQueryこんにちは。モルトとシガーで生きてます。インフラエンジニアの光野(@kotatsu360)です。毎分届く大量の実行結果メールから開放されQoL向上という効果がありました。本日はその取り組みについてご紹介いたします。ジレンマ:動作監視と大量のメール冒頭の通り、VASILYでは定期的に実行したいバッチ処理をcrontabで管理しています。真新しさはありませんが、実行時間の指定が簡潔かつ柔軟で未だに愛用しています。2016年12月現在、crontabは120行ほどです。crontabで管理しているスクリプト達(以下cronスクリプト)の動作監視です。当時、VASILYのcronスクリプトは3箇所に結果を出力していました。*1)1.のログは調査用、2.のSlack通知は異常検知、3.のMAILTOは過去の動作記録とそれぞれ役割をもっているのですが、ここで問題になるのは3.です。ご存知の通り、crontabにてMAILTO要素にメールアドレスを設定しておくと、cronスクリプト実行後にメールを送信してくれます。お手軽で便利なのですが、cronスクリプトの量が増えてくるとspamよろしくメールが届きます。「動いた」という記録を取る意味では大変有用なため、日々大量のメールを受け取り続けていました。問題発生:解決手段の模索そんな状況をしばらく容認していたのですが、ある日メールがパタリと届かなくなるという問題が発生したため、一念発起、改善に着手します。ちなみにメールが届かなくなった原因ですが、なんということはなく、あまりに量が多いため迷惑メールフォルダに分類されていたのでしたその際、手段選定の条件としたのが次の3つです。既存のスクリプトをそのまま使う監視と本処理を独立させる1.と2.については、短期間で移行を完了するためです。既存のスクリプトを短期間かつ安全に移行することを考えるとあまり現実的ではないと思い止めました。3.については、cronスクリプトをこれ以上肥大化させないためです。監視のような「運用上は必要だけれども、スクリプト自体の処理には必要ない機能」を持たせたくありません。これらの条件を満たせるものとしてhorensoを採用しました。スクリプト実行結果の「報告」をつかさどってくれます。Goで実装されており、各プラットフォームに対応するバイナリを置くだけで利用可能です。バイナリを配置後、以下のように実行します。arg2--の後ろにあるのが、既存のcronスクリプトです。このようにして実行すると、--reporterで指定したスクリプトがcronスクリプトの実行結果をJSONで受け取ります。"5.812"}後はこのJSONをreporterのスクリプトで好きなように扱えば完了です。reporterには任意の実行権限がついたファイルを指定できます。詳細な使い方は、SongmuさんのブログエントリやGithubのREADMEをご覧ください。jobs.cron監視ver2.0horensoを使うことによってcronスクリプトの監視方法は以下のように変わりました。*2)crontabの中では、以下のサンプルのように呼び出します。args...用意したhorenso.rbの動作は大きく2つです。exitCodeが0以外、またはstderrに出力がある場合、Slackに通知ログをfluentdにフォワードこのログは最終的にBigQueryとS3に保存され記録されます。これにより、ほぼspamと化していたメールを廃止することができ、かつ動作記録が確実に記録できるようになりました。BigQueryにもインサートされているため、参照も非常に容易です。補足をいたしますと、horenso.rbに集約したSlack通知はあくまでも監視を目的とした通知です。個々のcronスクリプトの仕様として必要なSlack通知は、そのスクリプトで実装することにしています。導入初期に発生した諸々horensoによって、劇的にモダンになったcron監視環境ですが、導入初期にはいくつか問題も発生しました。cronスクリプト自体を直したほうが良いものもありますが、原則既存のスクリプトに手を入れず対応しています。./batch/script.rbというような呼び出し方をしているものがあります。horensoでは--以降で、cdをしても意味がありません。そこで、次のように移動した上でhorensoを呼び出すことで解決しています。batch.rb)stderr当初、exitCodeのみを基準に実装をしていたのですが、例外ケースがあり正しく検知できていませんでした。VASILYのcronスクリプトはRubyですが、幾つかのスクリプトでは``でシェルコマンドを呼び出しているものがあります。シェルコマンドが失敗した場合、Rubyとして例外は出力されないため、exitCode=0(ただし失敗している)ということになります。そのため、内部で失敗を検知し損ねているケースを考え、今のreporterスクリプトではstderrの有無も確認するようになっています。BigQueryのクォータ2つめの図の通り、horensoで受け取ったログは最終的にBigQueryとS3まで送られます。fluentdからBigQueryへはストリーミングインサートをしているのですがここには各種の制限が存在します。ドキュメントスクリプトによっては大量のログを出すものがあり、それらが一度のリクエストに重なると制限に引っかかる恐れがありました。現在は、ログを次のように加工してからフォワードしています。8601形式に変換commandArgsをJSON文字列に変換なお、後半の2つはあとで扱いやすくするだけのものなので、BigQueryの制限とは関係ありません。切り詰める前のログはサーバ側に残っているため、どうしても全てのログを見たいケースがあればそちらを見ます。まとめモダンなcron監視環境についてご紹介しました。動作記録を参照しやすい形で保存することが可能になりました。これまで見えていなかった情報も得られるようになりました。今後はこの環境を活かしてcronスクリプト自体の改良も行いたいと考えています。最後にVASILYではiQONを一緒に作っていく仲間を募集しています。興味のある方は以下のリンクからご応募お願いいたします。Lambdaを使ってRubyKaigi用のデモアプリを作った話こんにちは、開発部の塩崎です。Databaseの監視と運用こんにちは。リプレイスチームの杉山です。...2018-11-17RubyConf2018参加レポートこんにちは、サーバーサイドエンジニアの竹若です。11/...2017-06-30Embulkを利用したデータ転送基盤の構築こんにちは。バックエンドエンジニアインターンの田島です。VA...2017-04-14インターン生がデータ転送基盤を一から設計する、VASILYバックエンドインターンの紹介こんにちは、バックエンドエンジニアの塩崎です。BLOGプロフィール株式会社ZOZOテクノロジーズのテックブログです。