Article by: (読了時間:6分)
あなたの .NET アプリが MongoDB とやり取りしているなら、遭遇しうるパフォーマンスの問題を効果的にデバッグできるようDB のパフォーマンスを計測できるようにしたいと、まず間違いなく考えるはずです。
そのためには、どのデータベースコマンドが実行されていたのか、どれくらいの時間がかかったのか、そしてそれが一度きりの小さな異常なのか、それともより大きなパターンの一部なのかを知る必要があります。理想を言えば、そのトレースから、関連するエラーやリプレイへと、手作業でつなぎ合わせることなく移動できるようにもしたいところです。
この記事では、まさにそれを実現する方法を次のものを使って紹介します。
- MongoDB に組み込まれた OpenTelemetry インストルメンテーション
- .NET SDK での Sentry の OTLP 取り込みサポート
- エンドツーエンドの流れを示す、小さなサンプルアプリ
一通り終える頃には MongoDB のスパンとクエリデータを Sentry 上で確認し、次のように掘り下げられるようになります。


核心となる考え方はシンプルです。スパンの生成とエクスポートは OpenTelemetry が担い、一方で Sentry は引き続き、クラッシュレポート、エンドツーエンドのオブザーバビリティの関連付け、そして UI での探索を担います。
注:UseOtlp() を使わないと、OpenTelemetry と Sentry 組み込みのトレーシングフックの両方が重複するテレメトリを生成しようとして、スパンが重複してしまうことがあります。
有用な MongoDB クエリデータを取得する
スパンを取得できるのは、当たり前の前提です。面白いのは、それらのスパンに付随するコンテキストのほうです。
MongoDB のインストルメンテーションでは、そこにコマンドやクエリの詳細が含まれるため、次のようなことを判断できます。
- どのコレクションが関係していたか
- どの操作タイプが遅いのか
- これは繰り返し現れるクエリパターンなのか、それとも一度きりのスパイクなのか
このサンプルではクエリコマンドのコンテキストを出力し、それを Sentry のトレース詳細や Queries の画面で見られるように、MongoDB と OpenTelemetry を設定しています。

クエリデータ内の PII はどうするか?
クエリのペイロードには、ユーザー識別子、メールアドレス、トークン、その他の機密フィールドが含まれることがあり、それらを Sentry に保存することに抵抗がある(あるいは法的に認められていない)場合もあります。
Sentry が OTLP 経由で MongoDB のスパンを受け取ると、Relay はそのクエリをパラメーター化したコピーを生成し、DB の属性を正規化し、クエリの値をすべてスクラブします(それらを ? に置き換えます)。このパラメーター化された文字列が、Queries モジュールでクエリをグループ化して表示する際に使われます。
ただし、Relay は元の db.query.text を削除したり上書きしたりすることは決してありません。そのため、{ "name": "Alice Smith" } のような実際の値を含む生のコマンドは、保存されたスパン上にそのまま保持され、スパンや代表例(exemplar)の詳細ビューに表示されます。つまり、集計された Queries ビューでは値は安全ですが、生の PII は依然として保存され、スパン単位で閲覧可能なままだということです。
このデータをスクラブするための選択肢は、3つあります。
クエリテキストをそもそも取得しない
これが最もシンプルで、最も確実です。ただし、その分、非常に有用になりうるコンテキストの一部を取り逃すことにはなります。
OTEL スパンプロセッサーでクライアント側でマスクする
.NET 向けの OTEL SDK では、BaseProcessor<Activity> を継承したクラスを登録でき、これを使って Activity.OnEnd フック経由で PII をマスクできます。これは Sentry の MongoDB サンプルで示している手法です。

上記のスクラバーは contributor フィールドの値をすべて [Filtered] というテキストに置き換えます。これにより、Sentry に送信・保存されるのは、PII を一切含まないマスク済みのバージョンになります。

サーバー側の高度なデータスクラビング
高度なデータスクラビングのルールは、db.query.text を対象にできます。
デフォルトのルールは、既知の機密パターン(パスワード、トークン、カード番号)しか捕捉しません。任意のフィールドの値をパラメーター化してくれるわけではないため、一般的な PII に対しては、明示的なルールやセレクターを追加することになります。
トレースを Sentry のエラーやリプレイと関連付ける
OTLP インテグレーションで重要なポイントの1つが、伝播コンテキストのブリッジングです。
トレースが OpenTelemetry の Activity によって生成される場合でも、Issue、トランザクション、そして下流のサービスが正しく揃うように、Sentry は適切なトレースヘッダー(sentry-trace と baggage)を注入し、読み取る必要があります。そのサポートはエクスポーターのインテグレーションに組み込まれているため、アプリケーションのコードに追加の配線をしなくても、トレーシングとエラーを横断した関連付けが得られます。
実際には次のことを意味します。
- 遅い MongoDB のスパンから、同じトレース内の関連するエラーやログへとジャンプできます。
- サービスの境界を越えても、一貫した分散トレーシングのコンテキストを保てます。

Sentry でデータを見る
サンプルを実行して MongoDB のアクティビティを発生させると、いくつかの場所でデータを探索できます。
- Explore → Traces:エンドツーエンドのトランザクションのタイムラインを見る
- Span samples:個々の MongoDB 操作を調べる
- Trace samples:スパンがリクエストのライフサイクルの中にどう収まっているかを示すウォーターフォールを見る
- Queries:スパンレベルの挙動を検索・グループ化する
ここでこそ、OTLP というルートが本領を発揮します。あなたが目にしているのは、独自のサイドチャネル的なインテグレーションではありません。Sentry のオブザーバビリティのワークフロー全体と自然に馴染む、第一級のトレースデータなのです。
おわりに
MongoDB はすでに適切なシグナルを出力しています。OpenTelemetry はそれらの処理方法をすでに心得ており、そして今や Sentry は、それらのトレースを OTLP 経由でネイティブに取り込みます。
もう1つ専用の SDK インテグレーションを保守する代わりに、オープンな標準を使い、セットアップをシンプルに保ちながら、それでいて Sentry の関連付けとデータ安全性の仕組みを維持できます。
さらに詳しく知るには
- リポジトリの MongoDB サンプルを試してみる
- OTLP インテグレーションのドキュメントを確認する
いつものように、質問、フィードバック、あるいはこの先どこへ進めるべきかというアイデアも大歓迎です。sentry-dotnet の discussions で、お気軽にディスカッションを始めてください。
Original Page: MongoDB Query Tracing in .NET with Sentry + OTLP
IchizokuはSentryと提携し、日本でSentry製品の導入支援、テクニカルサポート、ベストプラクティスの共有を行なっています。Ichizokuが提供するSentryの日本語サイトについてはこちらをご覧ください。またご導入についての相談は「お問い合わせ」からお気軽にお問い合わせください。

