Mackerelの分散トレーシングのハンズオンをやりながら考えていたこと

# はじめに

先日、はてなさんの主催するハンズオンに参加しました。
https://mackerelio.connpass.com/event/342156/

オフラインのハンズオンで、先日リリースされたMackerelの分散トレーシング（旧：Vaxila）機能の説明だけではなく、
OpenTelemetryの概念や分散トレーシングのなかで問題のあるレスポンスやクエリ、エラーの原因解析などかなり丁寧なハンズオンでした。

参考：Mackerelはアプリケーションパフォーマンスモニタリングへ対応します
https://mackerel.io/ja/blog/entry/announcement/20250203

本記事では、ハンズオンの概要とハンズオンを踏まえ分散トレーシングを自分たちのサービスに取り入れていく際に大事なことを少し考察してみたいと思います。

# ハンズオンの概要
ハンズオンでは、ローカルで作ったDockerコンテナベースのアプリケーションのテレメトリをMackerelに送付し、分散トレーシング機能を使いながらアプリケーションの改善を行っていきます。
したがって、下記のような環境を用意する必要があります。

### 前提条件
* ローカルPCにGitがインストールされていること
* ローカルPCでDockerが利用可能なこと
* Mackerelのオーガニゼーションが開設されていること
※2025年2月時点では分散トレーシング機能はβ版のため、無料で使うことができます

ハンズオン資料は公開されており、READMEがかなり詳細に記載されているため、読み進めるだけでも勉強になります。
https://github.com/mackerelio/mackerel-handson/tree/main/tracing

# ハンズオンの流れ
1\. 分散トレーシングのデモ
HotRODという架空のタクシー配車アプリを使って、ハンズオンは進みます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/8d54da79-b4ea-4c0a-97f3-1a1ac6b70dcc.png)

レイテンシーの分布
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/2de4c269-4a0b-42f7-95a7-dd5def4518d6.png)

トレースごとのサマリーを表示することができ、メソッドやレイテンシーを確認できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/e102d6c1-502a-49d4-87c5-a386792f61e1.png)

トレースの集計もることができます。トレース一覧のスパンの属性について、その値のバラつきを表示します。たとえばhttp.route属性はリクエストパス、http.status_code属性はレスポンスのステータスコードを示しますが、どのようなリクエストパスが多いのかや、レスポンスのエラー率などを見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/4ceaf860-a441-4e2b-8c83-d7ea7b9a4430.png)

リクエストが集中すると、遅延が発生するアプリのようです。
個別のリクエストを見ると、SQL SELECTが原因ではないかという推測ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/ecab0c06-02f3-42d4-b2a5-c7cad0213af0.png)

### エラーログの解析
同じアプリを改良していくと、エラーが発生するようになったので、課題という欄を選択すると、エラー情報が出てくるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/1392b2e7-b61e-4cb0-b64d-0e4b030a3782.png)

routeの処理があからさまに遅いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/c2c5ee0f-9a91-4fc7-a4ae-d783d290d1e3.png)

どうやら、ここでexcenptionが発生しているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/4da3bc4e-1511-45bb-8ba4-0d05e23b0485.png)

推測される理由も表示され、ここから原因を特定することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/9f665d07-96d6-44ca-87b2-545a722c78b3.png)

このように、分散トレーシング機能を使って、原因を推測することができるようになっています。

2\. トレースをもとにRuby on Rails アプリを改善

次のハンズオンでは、エラーの発生しているアプリを修正していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/d4ab7843-fa5c-4abc-a9ec-9274f680cc86.png)

method_sampleに問題がありそうだと視覚でもわかりやすくなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/ebb0cad1-9976-457d-9a38-b44a8ac0b90c.png)

どの行に問題があるかも見えました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/fcabe1ab-e12c-4e62-be57-32b4669f4337.png)

コードを見ると、改善点が示されています（デモなので、わかりやすく・・・）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/cf5d6ea1-08bc-4d47-be70-44a2a8e70728.png)

エラーはなくなりましたが、まだmethod_sampleは遅いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/2becd44f-9114-46ed-9856-d4a69dcf0a7f.png)

なんか怪しい属性があるので、ここを修正してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/0576224a-026a-4205-9fc0-39fd615b7326.png)

修正するとmethod_sampleは改善されましたが、細かい処理が大量に出ていますので、探ってみると、どうやらSQLの書き方に問題がありそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/1a87fa37-3620-4bf0-9929-eb2981577434.png)

これを改善して、レイテンシーが改善されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/f6c2147c-332a-4f1e-b457-d3d869a12de2.png)

データベースのクエリごとの集計もこのようにみることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308706/fff178ce-1bab-4606-ac0a-ff0513f9a4d8.png)

こんな形で、ハンズオンはここまでになります。
詳しいハンズオンの進め方は公式資料を見ていただくとよいかと思います。

# 分散トレーシングを業務に取り込んでいく際に考慮すべきこと
上記のハンズオンを踏まえたうえで考慮すべきことを書いていきます。実際はもっとあると思いますが、いったん思いついたことを記載しておきます。

* 可読性の高いコード
分散トレーシングを導入するしないに限らず、可読性の高いコードは意識されていると思いますが、デモのようにエラーメッセージがわかりやすくなっているとは限りません。普段からエラー処理やエラーメッセージを理解しやすくしておく必要があります。
開発と運用の組織が分かれていなくても、自分以外の人がコードを見る可能性は十分にあります。万が一自分が開発チームから離れた際も後続のメンバーのことを考えてこれらの処理を考えていく必要があります。

* 分散トレーシングを集中的に取り組むタイミング
トレーシングを日常的に取り組むこともあると思いますが、濃淡はあると思います。リリース直後のタイミングは集中的に取り組み、安定してきたら少し頻度を減らす、ということも考えたほうがよいでしょう。
Mackerelに限らず、トレースやログを保管するとそれだけでストレージ料金がかかっていくこともあるので、リリース直後と、安定化したタイミングでOpenTelemetry Collectorの収集間隔を変えたり、ログやトレースの保持期間を短くするなどの工夫が必要になります。

* テレメトリの保持期間
分散トレーシングを過去にさかのぼって行うこともできますが、その分ストレージの容量を増やすことになるので、どのくらい遡れるようにするかは決めておく必要があります。

* OpenTelemetry Collectorの可用性
OpenTelemetry　Collectorの可用性にも注意が必要です。サイドカーコンテナを利用する場合や、モノリシックなインフラに置かれたサービスの計装であればインフラの可用性と同期しますが、OpenTelemetry Collectorを別のインフラに置く場合などはそれ自体の監視や運用も必要になってきます。

* テレメトリのセキュリティ
今回のハンズオンではあまり触れてなかったのですが、OpenTelemetryで外部のツールに送る場合のセキュリティを考慮する必要があります。
HTTPSの暗号化はもちろんのこと、外部のツールのエンドポイントにExporterの通信を絞る、といったセキュリティの考慮も必要となります。

~~そもそもアプリケーションやインフラ構成で分岐がありすぎてドキュメントをあっちゃこっちゃしてOpenTelemetryでの計装を始めるまでがつらいのをなんとかしたい・・・~~（ここはMackerel関係ないので検閲されましｔ）

# まとめ
Mackerelらしく非常にグラフィカルで直感的で理解しやすいインターフェースを志向していることはよくわかる一方で、インフラ監視のインターフェースと比較するとまだまだ洗練されてはいないように思えました。
ただ、Mackerelの開発のみなさんもそこは認識しているようで、これから新機能や改善を行っていくようなので、正式リリースまでには私ももっとOpenTelemetryを理解して使えるようにしていきたいと思います。

フィードバックフォームもあるようなので、ぜひ気づいたことがあればフィードバックを送ってみるのが良いと思います。
https://docs.google.com/forms/d/e/1FAIpQLSdgVvOwLW-OU6cd06M9eT-QMSrBrPRubCzLnjnt8NX5VUTpPQ/viewform