サイバーウェーブは Ruby on Railsの開発に強みがあります。開発中に不明な現象が発生したときこそ、エンジニアの腕の見せどころです。ていねいにログやスタックトレースをたどり、推論と検証を繰り返して、的確に原因の所在を突きとめます。
ログやスタックトレース、エラーメッセージは英語の羅列のため、プログラミングをはじめて日が浅い方はつい「うっ」となって、よく読まずにやみくもに原因を探そうとしがちです。ベテランのエンジニアほど、まずは目の前の「システムが問題だと言っていること」をしっかりと読み込みます。
じっさいに私が取り組んだ事例を例にして、エンジニアの基本スキルとしてログやスタックトレース、エラーメッセージからすばやく原因を突き止める手順を紹介します。
ログを調査するときのファイルとコマンド
不明な現象に遭遇したのは、サイバーウェーブの自社プロダクトである「VALUE KIT」と外部の他社サービスを連携させようと新機能を開発していたときでした。「ユーザーがトランザクションをキャンセルすると、キャンセルリクエストが多重送信されてしまうことがある」という現象でした。
今回の調査では「VALUE KIT」が出力するふたつのログを頼りにしました。
- 「VALUE KIT」と外部の他社サービスの通信ログ
- Ruby on Railsのログ
コマンドは下記の3つを使いました。
scp | ログファイルを別のサーバーから手元のフォルダへコピーする。 |
grep | テキストファイルの文字列を検索する。 |
zgrep | 圧縮されたファイルを解凍せずに文字列を検索する。ローテートされて圧縮されたログを調査するときはgrepではなくzgrepを使う。 |
手順1:発生している現象を整理し、原因はどのログを調査すればわかりそうかを特定する
他社の外部サービスへのつなぎこみでぶつかったのは「トランザクションをキャンセルできなかった」というアラートでした。まずはその現象が発生したときに、詳細はどのログに記録されるのかを特定します。開発環境を操作して現象を再現し、ログがどのように残るかを確認します。
検証したところ、以下のふたつのログに情報が残っていそうだと当たりをつけました。
- 「VALUE KIT」と外部の他社サービスの通信ログ
- Ruby on Railsのログ
ポイントは、手元で現象をくりかえし再現できるように、再現手順を特定すること。そしてその結果どのようなログが出力されるのかを特定することです。今回の現象は、ユーザーがトランザクションのキャンセルボタンをクリックしたときに再現されることを特定しました。そこで、他社サービスへの接続を試行するコマンドの文字列を検索することで該当箇所を調べられるーと推測しました。
また、この現象がほかにも影響を及ぼしていないかの調査も大切です。今回はトランザクションが意図せず多重でキャンセルされた結果、他社サービスが記憶しているデータの個数と、VALUE KITが記憶しているデータの個数が不一致になってしまう、という現象を把握しました。
手順2:問題を含むログを抽出し、調査しやすいように整形する
ログファイルを手元の作業フォルダにコピーし、grepまたはzgrepでキャンセルリクエストのログを抽出します。
zgrep -e '"transaction failed"' ./**/{{ Path to log file }}.log*.gz > cancel_logs.txt
※transaction failedは、トランザクションがキャンセルされたときに外部サービスが返してくるキーワード
transaction failedキーワードは外部サービスでの処理が失敗したことを示すのみです。原因を特定するためのポイントは、該当のログの前後も見ることです。今回は、外部サービスへのPOSTリクエストの成否を示すログだけでなく、続く行にあるPOSTメソッドの引数のログにヒントがありました。
エラーが発生するとき、ログには引数のプロパティauthenticity_tokenが同じ値をもつリクエストが複数存在していました。authenticity_tokenとは、Ruby on RailsがCSRF対策として自動生成するトークンを指します。
authenticity_tokenは画面を表示し直すたびに変わります。ところが同じauthenticity_tokenの値をもつログが、立て続けに記録されていました。つまり画面を更新していないのにいくつものリクエストが発行されています。authenticity_tokenが同じ値であるということは、ユーザーがリクエストの結果を待たずに同じリクエストを再送している。原因として有力候補なのは、ユーザーがリクエスト送信後に、さらに送信ボタンを連打できてしまっている可能性です。
仮説の正誤を確認するためには、transaction failedに続く数行を合わせて取得することで、多重リクエストしているかどうかを調べることができます。
ログを取り出しても、多くの場合は1行の長いテキストデータです。そのままだと読みづらく、原因を見つけづらい。そこで取り出したログを、テキストエディタで正規表現を用いて整形します。
整形する正規表現(Regex):
.*"status":"([^"]*)".+"merrMsg":"([^"]*)".+"transactionId":"([^"]*)".*
整形する正規表現(置換後のテンプレート):
$3t$1t$2
手順3:スプレッドシートで開いてデータを分析する
ログの抽出と整形が終わったら、より詳しく調べやすいよう、Google スプレッドシートやMicrosoft Excelで開きます。整形したデータをさらにカンマ区切りまたはタブ区切りに加工して開きます。
カンマ区切りにするかタブ区切りにするかの判断は、私はタブ区切りにすることが多いです。Webブラウザの入力フォームにおいて、カンマはユーザーが入力しやすい文字であるのに対して、タブは入力される可能性が低いためです。カンマが入力された行が混入した場合、ログの一部だけスプレッドシートのカラムが合わなくなってしまい、調査に戸惑うことがあるためです。
今回はGoogle スプレッドシートで開き、VLOOKUPやピボットテーブルを用いてより詳しい現象を把握します。トランザクションが多重キャンセルされたとき、他社サービスの記憶するデータ個数とVALUE KITの記憶するデータ個数を突き合わせ、差分がどのタイミングでどのように発生するかを調べました。
手順4:プログラムを修正する
原因が正しく特定できたら、問題を解決するようにプログラムを修正します。そして正しく修正できた試験をします。
調査方法の引き出しを広くもっておこう
ログやスタックトレース、エラーメッセージから原因をスマートに突き止める手法は、エンジニアが基本として身につけておくべきスキルです。もちろん、この記事で紹介した調査方法はあくまでも一例です。調査手順や方法は、プロジェクトやシステム構成、技術スタックの状況によりさまざまです。自分と会社にノウハウを蓄積し、いくつも引き出しをもって、柔軟に課題を解決できるようにしていきましょう。
サイバーウェーブでは一緒に働く仲間を募集しています
サイバーウェーブでは一緒に働く仲間を募集しています。当社は創業20年を機に「第2の創業期」として、事業を拡大方針へと舵を切りました。会社が急拡大しており、若いメンバーやインターン生がどんどん入社しています。個人の成長は、勢いのある環境のなかでこそ加速されるものです。成長事業に参画できるチャンスです!
サイバーウェーブはコード1行1行に対してこだわりを持って、プロ意識をもったエンジニアを育てている、技術力に自信のあるシステム開発会社です。社内には、創業23年のノウハウの詰まった研修コンテンツや、安定したシステム開発をするための手順が整っています。実力のあるシステム開発会社だからこそ、経験を積みながら、実践的なシステム開発の技術も学べます。自信をもって主義主張ができる『飯が食える』エンジニアを目指していただきます。
エンジニアとしてしっかりと飯を食べていけるまでには、道のりは決して短くありません。長期で頑張り、エンジニアになるという強い思いがあれば、実戦的な開発経験と、周りの仲間とコミュニケーションしながら、しっかりと成長できます。当社のノウハウを余すことなく活かし、技術力を大きく伸ばしていただきます。
ぜひ、エントリーをお待ちしております!
インターン採用
新卒・既卒・第二新卒採用