技術者には試行錯誤は圧倒的に悪であると腹落ちした話
私はシアトルのクラウドの中の人として、ソフトウェアの開発を行っているが、先日ある問題がきっかけで、技術者には試行錯誤がとても良くないということが腹落ちしたので、忘れないように書いておきたい。
先日起こった事
先日起こった事は、私がシアトルから一時帰国して、普段使わないラップトップを使って日本から仕事をしている。 Application Insights というログを管理するプラットフォームがあるのだが、とても不思議なことに、Application Insights のログファイルを見ると完全に正常に動いているようにしか見えないのだが、クラウドのポータルに行くと、テレメトリが来ていない。
Application Insights のチームのメンバーが助けてくれることになったので、彼女に、Teamsで画面共有をして、「ほら、出ないでしょ?」と見せると、なんとテレメトリがポータルに来ている。その後自分で何回も試してもやっぱり出ない。もう一回別のメンバーに助けを求めるチャットを書いて「Fiddlerつかって分析したらいいんじゃね?」とアドバイスをもらった瞬間にポータルを見ると、今まで一回もちゃんと出てないのに、今回だけテレメトリが出ている。マジ呪いかよ!とか思ってしまった。
試行錯誤
それは、WSL2で動作する Docker の中のホストプロセスから、 Application Insights のテレメトリをポータルに送るテストなので、私はいろいろ試してみた。自動化するためにスクリプトにしていたのだ。Application Insights にはサンプリングといって、パケットが沢山送られたときに、カットする設定があって、それが、Application Insights のログが見えないときの大抵の原因だからだ。もしくは、Application Insights のスロットリングにかかったんだろうか?ポータル側でフィルターがかかっているとも考えられる。
あれ、日本のリージョンに移ったから、USのリージョンにテレメトリを送っているよなぁ。いや、WSL2から、Windows10、インターネットにルーティングする過程でロストしている?
パターンを試して問題解決をはかろうとする
自分の頭のなかでは様々なアイデアが交差している。サンプリングの設定を調べると、自分の使っているものは、サンプリングの設定はデフォルトではセットされていない。ただし、ホストのプロセスの設定では、サンプリング設定は存在する。
私はいろんなパターンを試した。スクリプトを改造して、スロットリングを気にして、ログをInfoにしてみたものを試したり、ログの出力をコンソール+ファイルになっていたものを、ファイルのみにしてみたり、リージョンを日本のリージョンを使うように変えたり、スクリプトの実行パターンを数個だけにしたり、、、
問題の手がかり
さんざん試行錯誤して、1日ぐらいぶっ潰した挙句、上記の試行錯誤した結果はすべて失敗に終わった。そんな時に、ふと自分の脳裏に、Application Insights のチームの人はちゃんとデータは出ているいって、彼女がどうやってるかを説明してくれた時のことを思い出した。そう、彼女は、スクリプトを使わず手動でテストしていた。
自分も試しにスクリプトを使わず、手動で実施してみた。完璧に動作した。
問題は解決したのだが
問題は「スクリプト」だったのだ。じゃあどこが原因か?というのはすぐに思いついた。私のスクリプトは、リクエストを実行して、Docker Container の中の Application Insights のテスト結果のログを抽出し、Docker Container を終了させる。
ここでの問題は何か?というと、Application Insights のクライアントが、「いつポータルにテレメトリを送るか?」という問題である。それは、ログを吐いた瞬間ではない。ふつうはある程度貯めてから、フラッシュして、送信される。つまり、ローカルファイルの、ApplicationInsights のログが書かれたからといて、それが本当にポータルに送られたかはわからない。きっと大抵は、Container を終わらせたら、テレメトリをフラッシュする前に、終了するだろう。
ごくたまに、ラッキーだったときに、Container が終了するまえに、テレメトリをフラッシュして、ポータルに送るケースもあるかもしれない。これが意味不明の挙動の正体だ。私は、ワークアラウンドとして、docker kill の前に、30秒待つことにした。問題は完全に解決した。より完璧な解決は、コンテナを終わらせる前に、内部で動いているホストをグレースフルにシャットダウンさせるのが良いだろう。
自分に身についたものが何もない
問題は解決した。1日以上使って。しかし振り返ってみると、大きな問題があった。私は1日もかけたのに、知識的に「何も成長していない」。試行錯誤なので、自分の頭で考えたあーでもない、こーでもないを実施する。だから、時間がとってもかかる。しかし、問題は、この過程で、私は新たな知識を学んでいるわけではなく、ただ単にいろんなパターンを試して正解を探している。つまり、何も学んでないのだ。
まったく同じ状況で、まったく同じ問題が起こったら、メモをとっておけば、次回の解決はものすごく速くなると思うが、問題がちょっとでも違えばお手上げだ。なによりも私は「何も学んでいない」つまり、似たような問題が起こったとしても、また同じだけ時間を使ってしまうことも十分にある。
達人の言ったこと
プログラマとして、仙人のようであり、問題は一瞬で解決するTraskが、私にアドバイスしたのは、試行錯誤ではなく、「Fiddlerで分析する」だった。Fiddlerは、ネットワークのモニタリングを行うツールで、例えば、Application Insgihtsからどういうデータが出ているかをモニタ出来る。ただし、私は、それをどうやってWSL2のDockerに対して適用するのかがわからなかった。にっちもさっちもいかなくなったらそれをやろうと考えて、最後に撮って置いておいた。面倒だったのだ。
正解はFiddler
しかし、振り返ると、私のとるべき行動は、Fiddlerで、モニタリングすることだったと思う。2時間もあったら絶対にFiddlerぐらいセットアップ楽勝で出来る。そして、Fiddlerを見たら、WSL2側から、Application Insights のテレメトリが「来ていない」ことが一撃でわかるはずだ。
試行錯誤ルートではなく、わたしがこのルートをえらんでいたら、どうなっていただろう?多分Fiddlerのセットアップに時間がかかるだろう。WSL2からどう使うかの情報などはない。しかし、実際に私が後で試すと、実にスムーズで、1時間足らずで簡単にセットアップをしてブログもついでに書いた。
Fiddler ルートを選んでいたら
もし、そのルートをえらんでいたら、1時間で、Fiddlerがセットアップ出来て、恐らく、ApplicationInsights のテレメトリが「出ていない」ことに気づいただろう。そこから、先ほどの、Application Insightsのフラッシュタイミングの問題にたどり着くのはさらにステップが必要だろう。だが、少なくとも、「そもそも出ていない」ことには気づけたはずだ。
このルートの利点は、よくよく考えると、かなり早いだけではなく、私が「FiddlerをWSL2と一緒に使う」のはどうやってやるのか?ということを学んで試していることにある。つまり、特定の状況ではなく、様々なケースで使えるツールとコンフィグを学ぶので次からリクエストのキャプチャなど楽勝だ。このように、試行錯誤ケースと違って「未来の生産性」が向上している。
そのことに気づいて、問題を解決したあとだったけど、Fiddlerのセットアップは実際にやってみてブログを書いておいた。
技術をコントロール配下に置くこと
重要なことは、目先の問題を解くことではなく、その関連技術を理解して、いかに自分のコントロール下に置くか?である。コントロールできるようになればなるほど、そもそも問題が起こらない。
そのためには、試行錯誤ではなく、立ち止まって、科学的な方法、もしくは、経験者の話を聞いて、問題を一つ一つ狭めることが重要だ。科学的な方法は、基本的に「こうちゃうか?」ではなくて、「事実」を積み重ねる。変に想像するのではなく、コードを読む、書く、ツールを使って分析する、ログや、エラーメッセージをしっかり読んで理解する、分析する。
試行錯誤するぐらいなら、コードやドキュメントを読んだり、達人に聞いたり、ツールを使って1レイヤづつ分析するほうが、「再現可能性」が高くなり、「技術力が向上」する。
数日前に見たTwitterで流れていたが 「エンジニアが、書いてないことをやらないことは技術が必要である」というのは確かにそうなのかもしれない。試行錯誤や、ハックして書いたコードは、サポート範囲外になるかもしれない。試行錯誤したくなるのだが、ドキュメントやコードを読んで、ツールで分析して、一歩一歩進む。そちらの方がお得で、自分の実力アップにつながる。
自分の中で試行錯誤は無駄認定された
というわけで、やっぱ試行錯誤は無駄だわ。使うとしても、最後の、本当に最後の手段として。試行錯誤でたとえ正解を引いたとしても、問題は、「うまくいった理由」がわからない。たまたまうまくいったのかもしれない。つまり、「理解」できているとはいいがたい状態だからだ。「理解」できていないので、いつ似たような状況で違うエラーメッセージだと対処するのは難しいだろう。
一件遠回りに見えても、コードを読む、ドキュメントを読む、ツールで分析を優先させるのがいろいろ吉のようだ。