フリーキーズ | 独学プログラミング

バグ修正ってどうやるの?エンジニアのログ追跡・調査フローを紹介

最終更新日

日々、開発の仕事をしているときに悩まされる大きな問題はバグです。
開発途中でも、本番サービスイン後でも、バグには頭を抱えさせられます。

このコンテンツでは、実際にエンジニアがどのようにバグを調査し、バグを解消するかについて紹介します。

開発におけるバグとは

まず、このコンテンツでバグとは何を指しているかを定義します。

  • Webサービスへアクセスしても何も表示されなくなった
  • 前触れもなくエラーメッセージを通知する箇所が発生した
  • 原因不明だが、機能が動かなくなった
  • 昨日まで何もなかったのに、今日になったらサービスが重くなっている
  • 矛盾したデータがデータベースに取り込まれている

などなど、エラーのシチュエーションは枚挙にいとまがありません。
「バグを定義する」場合、とにかく**「動作が期待通りではない」状態**だと言えます。

初心者がよく遭遇するバグの種類

上記のように、開発におけるバグは様々なパターンで発生しますが、自分がプログラミング初心者時代に個人開発をしていて遭遇したケースを紹介します。

  1. データベースがつながらない
    これはたいてい、ホストやユーザー名、パスワードが間違っています。そもそもデータベースのプロセスが停止している、というケースもあります。
  2. Webサイトやサービスが表示されない
    だいたいホストしているサーバーか、HTTPアクセスを制御しているWebサーバーの仕業です。設定が間違っているケースなどが多いです。
  3. データベースに矛盾発生
    実装そのものが間違っていることや、リレーションを正しく張れていないケースがあります。矛盾したデータのテストケースを使って単体テストを行いましょう。
  4. サービスが重い
    topコマンドを打つと、データベースのメモリ消費が100%を越えていた、なんてこともあります。スロークエリをEXPLAINで調査するところから始まります。

これらはあくまで一部です。主に初心者や入門者のときは、プログラミングは問題なくとも、サーバーやデータベースといった、目に見えづらい管理対象でバグ発生するケースが頻繁にあります。

中級者以上でもよく遭遇するバグの種類

ある程度経験を積んで様々なケースへ対処できるようになっても、まだバグとの付き合いは切れません。以下に、経験年数を越えてもよく見かけるバグを紹介します。

  1. Kubernetesのpodが止まった
    ビルドに失敗しているだけならマシな部類ですが、原因特定に時間がかかるパターンもあります。Terraformなどの設定が間違っている場合もあります。
  2. フロントエンドから送るAPIへのリクエストデータがおかしい
    フロントエンド技術の発達により、stateなどの管理に対し、シビアになる必要が出てきました。送るデータがおかしいときは保持しているデータの流れをしっかり管理しなくてはなりません。
  3. 「何か違う」というフィードバックが来る
    甘い要件定義のときにこういったフィードバックをされることがあります。「何が違うか」をしっかり話し合い、仕様に落とし込む作業は入念に行いましょう。
  4. 日次ワークフローからエラーが出た
    大きなデータパイプラインを組んでいると、ワークフローからエラー通知されることがあります。多くの場合、当日、流入したデータが想定外のものであったパターンだった際に発生します。

経験年数とともに、対応するバグの難易度が上がっていきますが、その分、ログ追跡するときは宝探しのような趣が出てきます。(できればそのような状況に陥りたくありませんが)

バグを調査・対応する技術

では実際に、ログを追跡し、バグを調査し、修正するまでの技術について紹介していきます。
大きく分けて、以下の3つの要素が大切です。

  1. ログトレース
  2. 原因調査
  3. 修正デプロイフロー

(できれば)ローカルでバグを再現

バグ対応の手順ではじめに重要な要素は、バグを再現できることです。
サービスにアクセスできない、などは簡単な再現の部類ですが、「特定条件下で発生する」タイプだと再現が厄介です。

発生を検知したエンドユーザーに聞き取りができると良いですが、それが困難な場合はUIテスト自動化ツールや手作業で発見していくことになります。

ログトレース(追跡)は事前準備が大事

ログトレースは「どこで」「どういった」バグが発生したかを調べるため際に良い指標です。ただし、あらかじめコードやツール、ソフトウェアにログ出力するように実装していないと、調査時間が延びてしまいます。

普段の開発から、ロガーに関するコーディング規約を決めたり、利用するツールやソフトウェアのログ設定を確認しておくなりして、事前に備えておきましょう。

コードやエラーメッセージからバグの原因を特定

ログが出力されていれば、ログをベースに原因追跡を始められますが、ログだけで完結しなかった場合はコードを追っていく作業となります。
コードのつながりや、再現したときに表示されるエラーメッセージから原因を特定していきましょう。

ここまで完了したら「調査」の段階は終了となります。

デバッグしながら修正作業

修正作業では、デバッグが重要となります。どういった値がどういったタイミングで発生し、それがどのように渡されているかを逐次確認しながら修正していきます。

このとき、使っているプログラミング言語やフレームワークのデバッガーを熟知しているとスムーズでしょう。多くのプログラミング言語には、高品質なデバッガーが組み込みで存在していたり、ライブラリとして提供されていたりするため、積極的に利用していきましょう。

複数のバグがある場合

もし、バグを追跡・修正している中で複数のバグが発見された場合は、1つずつ対処することを強くお勧めします。
理由として、ソースコードのバージョン管理や、インフラのデプロイ履歴が追いやすくなるためです。

1つのバグを直しても、そこから更にバグが派生した場合は、その修正履歴を追うだけで済みます。しかし、複数のバグを一度に修正した場合は、複数の修正箇所を追うことになるからです。

同じ箇所でバグを発生させないために

理想的なのは、二度と同じ箇所でバグを発生させないことです。もちろん、そのときのバグの要因は種々雑多となりますが、コードであれば型安全を守ることや、インフラであれば設定のチェッカーを実行するなどできることはたくさんあります。

障害発生はできれば遭遇したくないものの、素晴らしい学びのタイミングです。
どこが悪かったかをしっかり分析し、その後のより良い実装や設計に活かしていきましょう。

テストケースの追加

修正が終わった段階で必ずチェックしてほしいのが、単体テストのテストケースです。
もし不正なデータによるバグだった場合、その不正なデータはテストケースに入れ込みましょう。

ユースケースとして役立つだけでなく、テストそのものの質を上げることで、ソフトウェアを高品質にする一助となります。すべてのテストケースを網羅することは、人間の脳みそだけでは追いつかないことも多々あるので、積極的に事例は拾っていきたいところです。

本番サービスへデプロイする際に気をつけること

実際に修正が終わり、テストケースの追加をしても、本番デプロイには慎重になってください。リグレッションテストやデグレは当然のことですが、別口で実装されているコードの混入など、新たなバグを生むきっかけがデプロイに隠れている可能性があります。

もしレビュアーになれるエンジニアが不在であったり、個人開発のように一人で開発している場合は、GitHub ActionsのようなCI/CDツール上で可能な限り検査できるようにしておきましょう。

運用再開から「直った」と断定するまで監視する

バグ修正を無事本番デプロイし、運用を再稼働し始めたら終わり、ではありません。
常時稼働アプリケーションや日次ワークフローが回っている場合だけでなく、新たなバグが生まれる可能性はゼロではありません。

可能な限り、継続的に注視できるような体制を整えましょう。監視ツールの導入や、ログベースの通知機能の強化などを検討してください。

バグ対応能力はエンジニアにとって隠れた必須スキル

あまり転職活動や商談で注目されないバグ対応能力ですが、これがあるだけで職場やプロジェクトで重宝されるスキルです。
ときどき、普段目立たないのにバグ調査のときに頼りがいがある、というエンジニアがいます。こういった縁の下の力持ち的なエンジニアは、上長や管理者から見たらありがたい存在です。

まずは、自分で書いたコードや設計を見直してみましょう。
「もしもバグが起きたら」を考慮したときに、足りない材料があればしっかり対応しておくことで、より高品質で安全なソフトウェア開発が可能となります。