真のエラーを救い出せ!バックエンドのエラーを99.9%削減した話
はじめに
事の発端
私のチームでは日々多くのアラートがSlackに流れてきます。ほんとに対応しないといけないクリティカルなエラーもあれば、そうでないものもあります。
もはやオオカミ少年と化したエラーに、私たちはどう対応すべきか、それが問題でした。
今回取り掛かったのはNest.jsで稼働しているAPIサーバーとCloud Functions(TypeScript)のエラーを削減するプロジェクトです。
このプロジェクトが始まったころ、1日のエラーは約10万、止まらないエラー、埋もれていくクリティカルなエラー、それらを見つけるのは至難の業でした。
障害が起きればマネージャーが長年の勘と経験でクリティカルなエラーを見つけ、エンジニアがそれを修正する、というのが当たり前の流れでした。
そこで、エラーを削減して真に重要なエラーを見つけるためにこのプロジェクトが始まりました。
これは筆者(19歳)がリードしながら、TS未経験の2人メンバーと共にエラーを99%削減した奮闘記のようなものです。
(ちなみにこれは余談ですが、記事公開日の1/29から20歳になりました🎉)
プロジェクトの動機
1日約9.7万件ものエラーログが記録されており、どれが真のエラーなのか、リリース後にエラーは増えていないかなどがわからない状態となっていました。上記のように膨大な数のエラーログがあるため、万が一ユーザー影響のあるクリティカルなエラーが起きても気づくことはほぼ不可能だったと言えます。
さらに技術的な課題だけでなく、心理面の問題も非常に重要でした。TypeScript未経験のメンバーが複数おり、「99.9%なんて絶対に無理だ」と考えていた背景には、前Qで対応していたアプリ品質向上プロジェクトで思うようにエラーを減らせず苦い経験をしたことが影響していました。私自身は「できないわけがない。絶対できる」と考えていたのですが、メンバーとは「本当にそんな削減が可能なのか?」という認識ギャップがあったのです。
そこで、このプロジェクトでは膨大なエラーログを整理・削減すると同時に、チームの心理的ハードルを下げる取り組みも不可欠でした。TypeScript未経験者をサポートしながら「エラーを99.9%減らす」なんて大きな目標をどう進めていくのか、具体的な方針を示し、みんなが「やればできる」と思えるようにする必要があったのです。
プロジェクト全体の進め方
エラーの技術的な解決策としては、まずすべてのエラーログをIssue化してGitHub上で管理する仕組みを整えました。
同時に、未経験メンバーへの学習の場として「モブプログラミング」を採用しました。わからないところはすぐに質問できるため、TypeScript初心者にとって心理的ハードルが低くなるメリットがありました。前Qのプロジェクトで失敗した要因として「どう直せばいいか分からない」という状況があったと推測されるため、それを根本的に解消する形になっています。
こうした技術面と心理面の両側面からのアプローチが奏功し、チーム内でも次第に「99.9%削減なんて夢のまた夢だ」という雰囲気が薄れていきました。エラーログを可視化し、分類し、個別に対応していくうちに、「実は結構いけるんじゃないか」という意識が少しずつ生まれていったのです。
どのようにエラーを削減したか
まずはエラーを可視化することから始めました。直近2週間のエラーログ全てに目を通して1つずつ真心込めてGitHub Issueに登録しました。
登録したら除外クエリを書き、またエラーログを確認し、また登録し、除外クエリを書く、そんな作業を繰り返しました。
↓これはGitHubのissueの推移です。
このプロジェクトと同時に別のプロジェクトが進行しており、新規開発を行なっていたため、減らしたと思ったらまた増えてしまう、時間が取れない、などの問題がありました。12月中旬に一気に角度がついてるのは、片方が落ち着きこのプロジェクトに集中できたからです。
1. エラーを可視化する
先ほど述べたように、GCPのログから発生しているエラーを1件ずつ手で拾い、Issue化していきました。泥臭い方法ではありますが、膨大なノイズに阻まれていた真のエラーの姿を明らかにするうえで効果的でした。
2. エラーを分類する
可視化したエラーは更に「ユーザーに直接影響があるか」「外部起因なのか」「初心者でも取りかかりやすいものか」など、いくつかの軸で分類しました。全てのIssueにラベルを付与し、GitHub Projectsの看板上で管理することで、下記のようにどれだけ残っているか、どれが対応中かといった情報を簡単に確認できるようになったのです。
- これはユーザー影響がある
- これは外部起因だからどうしようもできない
- これはオンボーディングにちょうどいい学習タスク
最初はエラーの数が桁違いに多かったものの、こうして分類することで「急ぎで直すべきもの」と「あとで対応すればいいもの」を明確化し、作業を効率的に進められるようにしました。
成果
これらの取り組みによって、エラーログは1日約9.7万件から約150件まで大幅に削減されました。膨大なノイズに埋もれていた真のエラーが見えやすくなり、リリース後のエラー増加も容易に監視できるようになりました。もし重大なエラーが発生しても確実に見つけられるため、サービスの安定性の面でも大きなメリットがあります。
残っている約150件のエラーに関しては、通知関連や原因不明のものが含まれますが、修正可能と判断できるものについてはすべて対応を完了しています。当初、「こんな規模でエラー削減は無理では?」と感じていたメンバーも、段階的なTypeScript学習やモブプログラミングといったサポートの下で成功体験を積むうちに「本当に99.9%削減できるんだ」と確信を持つようになりました。
まとめ
このプロジェクトは、当初「とても無理だ」と思われていた1日約10万件のエラーログ削減を実現し、最終的に約150件まで絞り込むことに成功した事例です。大量のログをただ眺めるのではなく、すべてIssue化して“可視化”し、TypeScript未経験メンバーをモブプログラミングや基礎からのタスク割り当てで支援することで、地道に問題を解決していきました。
前Qのプロジェクトで思うように結果が出ず心理的ハードルを感じていたメンバーも、小さな成功を積み重ねることで「99.9%なんて不可能だ」という思い込みから脱却し、最終的にゴールを達成できました。クリティカルなエラーが埋もれて手遅れになる映像が頭をよぎるほどの状況だったにもかかわらず、実際のデータとチームの努力を可視化することで、想像以上の成果を上げられたのです。
今後、同じように大量のエラーログに悩むチームにとっても、あきらめずに“一つひとつをIssue化する”取り組みは効果的だと思われます。心理的なハードルがあったとしても、ノイズを減らし、本当に対応すべきエラーに集中できる体制を整えれば、十分に大幅な削減を目指せるのではないでしょうか。
Discussion