Sentry (sentry.io) とは
Sentry (sentry.io) は、アプリケーションのクラッシュやエラーをリアルタイムで監視・通知し、問題をデバッグ・解決するためのオープンソースのエラー・パフォーマンス監視プラットフォーム、ないしはその SaaS です。
つまり、アプリケーションから所定の Web API エンドポイントにクラッシ等の情報を送信すると、その情報が蓄積され、適宜メール等でクラッシュ発生を通知しつつ、ブラウザで開くダッシュボード表示でその送信された情報を閲覧可能にする、という Web システムです。および、各種プログラミング言語やライブラリ、フレームワークから利用するための SDK も豊富に提供されています。
ソースコードは下記 GitHub リポジトリで公開されています。
一般的には、上記リポジトリから clone して自分でセルフホストするよりは、Sentry の SaaS である https://sentry.io にサインアップして利用するほうが無難かと思います。
「いやいや、今日び、そういうのは OpenTelemetry の役割じゃなくて?」というのは、まぁ、そうなんですけれども、実は Blazor WebAssembly は OpenTelemetry のサポートがなぜか手薄いようで、自分が確認できた限りではある程度の回避策があるのみで、まだ実用に耐えないと判断しました (下記 GItHub Issue を参照)。
Blazor Server なら大丈夫なんですけどね...。もしも認識間違ってたらコメント等で教えて頂けると助かります。
ということで今回は、Blazor WebAssembly から Sentry を使って予期されない例外発生を記録・通知するところまでを実際に試して確認したいと思います。
Sentry (sentry.io) 上での作業
https://sentry.io にサインアップしたら、まずは Sentry 上に "プロジェクト" を作ります。Sentry の Web UI 上でプロジェクトの新規作成を開始し、プラットフォームとしては適当に "ASP.NET Core" を選んでおきます。どうやら、ここで選択する "プラットフォーム" はその後のガイド表示などに影響するのみのようでしたので、何を選ぶかあまり神経質にならなくてもよさそうです。ちなみに、そのものズバリの "Blazor" は選択肢として用意はされていませんでした。
他の指定項目は既定のままにして下へスクロールしていき、プロジェクトスラグを自分の好みや需要にあわせて入力し、[Create Project] をクリックしてプロジェクトの作成を完遂します。
プロジェクト作成完了のページが表示されます。ここで Sentry へログを送信するための組み込みの手順が書かれているのですが、これはサーバー側で実行される ASP.NET Core 向けの手順です。ブラウザ上で動作する Blazor WebAssembly 向けの手順はこれとは異なるのでひとまずこの手順は無視します。その代わりに、ログを送信する先を示す DSN (Data Source Name) を取得しておきます。
なお、DSN は以下の手順でも随時確認可能です。まずは [Insights] のメニューから対象のプロジェクトを開き、ページ右上の歯車のアイコンをクリックして、プロジェクトの設定ページを開きます。
プロジェクトの設定ページが開いたら、サブメニューの下の方に [SDK Setup] のカテゴリに [Client Keys (DSN)] という項目があるので、これを開きます。そうするとページ上に DSN が表示されます。
以上が、まずは Sentry 上での準備です。まとめると以下のとおりです。
- Sentry https://sentry.io にサインアップしてアカウントを作る
- Senty 上で "プロジェクト" を作成
- プロジェクトの "DSN" (Data Source Name、ログを送信する先の URL) を取得
Blazor WebAssembly 側の作業
Sentry SDK によるデータ収集を組み込む
Blazor WebAssembly プロジェクトに、NuGet パッケージ "Sentry.AspNetCore.Blazor.WebAssembly" を追加します。
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.0" PrivateAssets="all" />
+ <PackageReference Include="Sentry.AspNetCore.Blazor.WebAssembly" Version="5.16.2" />
</ItemGroup>
</Project>
次に Blazor WebAssembly アプリケーションの Program.cs で、Senry の使用を構成します。このときに、データ送信先として、先に控えておいた DSN を指定します。
using BlazorApp1;
using BlazorApp1.Services;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<CounterService>();
+ // DSN を指定して Sentry の使用を有効化
+ builder.UseSentry(options =>
+ {
+ options.Dsn = "https://********************************@*****************.ingest.us.sentry.io/****************";
+ });
+ // ILogger との統合(LogError 以上のログをイベントとしてキャプチャ)
+ builder.Logging.AddSentry(options =>
+ {
+ options.InitializeSdk = false;
+ });
await builder.Build().RunAsync();
最低限の実装はたったこれだけです。
動作確認
動作確認のために、わざと捕捉されない例外を発生するようにしてみます。このサンプルプログラムでは、Counter ページでのボタンクリック回数の計測を DI コンテナに登録するサービスと実装してあります (下記コード)。
namespace BlazorApp1.Services;
public class CounterService
{
public int CurrentCount { get; private set; } = 0;
public void IncrementCount()
{
CurrentCount++;
}
}
ここで、この Counter サービスの実装をいじり、CurrentCount が 3 以上になったら例外をスローするようにしてみます。
namespace BlazorApp1.Services;
public class CounterService
{
public int CurrentCount { get; private set; } = 0;
public void IncrementCount()
{
CurrentCount++;
+ if (CurrentCount >= 3) throw new Exception("これはテストです");
}
}
この状態でこの Blazor WebAssembly アプリケーションを実行し、Counter ページにて "Click me" ボタンを繰り返しクリックすると、3回目のクリックで例外が発射され、UI 上にはエラー発生の黄色いバーが表示されました。
すると、Sentry の使用を構成してあったので、この例外発生は Sentry SDK によって検知され、sentry.io に送信されています。その結果、senry.io からサインアップしたメールアドレスに、エラー発生を検知した旨のメールが届きます。
そこで sentry.io の Web ページを開き、[Issues] のサブメニューから [Feed] を開くと、いま発生させた例外の記録が表示されます。
例外の詳細を開くと、ちゃんと .NET/C# レベルでの呼び出し履歴 (スタックトレース) も記録され、Web UI 上で確認できるのがわかります。
このように、Blazor WebAssembly アプリケーション上で予期されない例外が発生すると、それが Sentry SDK によって検出され、指定された DSN = sentry.io に情報が送信されます。これをトリガーとして sentry.io からメールで例外発生が報され、senty.io の Web UI にアクセスすることで、呼び出し履歴 (スタックトレース) を含む例外の詳細を知ることができます。こうして、問題の発生を知ることと、その問題の解決のための情報入手とが Sentry によって実現されます。
"Breadcrumb (パンくずリスト)" の利用
Blazor WebAssembly 側に、もう少し手を加えてみます。
App.razor には以下のように <Route> コンポーネントがマークアップされていますが、
<Router AppAssembly="@typeof(App).Assembly"
NotFoundPage="typeof(Pages.NotFound)" >
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
</Router>
この <Router> コンポーネントのナビゲーション開始時のイベント OnNavigateAsync を捕捉し、遷移先の URL パスを、Sentry SDK の "Breadcrumb (パンくずリスト)" に登録するようにします。
<Router AppAssembly="@typeof(App).Assembly"
NotFoundPage="typeof(Pages.NotFound)"
+ OnNavigateAsync="OnNavigate">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
</Router>
+ @code {
+ private void OnNavigate(NavigationContext args)
+ {
+ SentrySdk.AddBreadcrumb("Navigating to " + args.Path, "navigation");
+ }
+ }
SentrySdk.AddBreadcrumb() を呼び出した時点では、sentry.io への情報の送信は行なわれません。このあと、予期されない例外発生などで sentry.io へのエラー情報送信時に、それまでに蓄積された "Breadcrumb (パンくずリスト)" が添えられる仕組みです。
この状態で、"/" → "/weather" → "/counter" とページを渡り歩いた後で "Click me" ボタンのクリック連打を行なうと (そして例外が発生すると)、sentry.io 上には以下のように "Breadcrumb (パンくずリスト)" が表示され、どのようなページを辿ってこの例外に至ったのかがわかるようになります。
このように "Breadcrumb (パンくずリスト)" を上手く使うと、何か問題が発生したときに、その問題発生に至るまでのユーザーの行動や内部状態の変遷を知ることができるようになり、問題の解決にあたって非常に強力なヒントとなり得ます。
まとめ
以上、Blazor WebAssembly におけるアプリケーション運用監視の例として、Sentry (sentry.io) の利用を紹介しました。先に書いたとおり、Blazor WebAssembly では、アプリケーション上で発生した予期されない例外を記録・通知する手段として OpenTelemetry のサポートが弱く、その点、Sentry は専用の SDK も提供され組み込みも簡単で、既定の構成でもじゅうぶん期待に応えてくれる印象です。Sentry の SaaS である sentry.io の課金体系については公式サイトを確認頂ければと思いますが、開発者の動作確認用の Developer プランは無償であったり、じゅうぶん安価な価格形態であるように感じました。
アプリケーション運用監視サービスには Microsoft Azure の Application Insights や New Relic、Raygun など他にもいろいろあると思いますが、とりわけ Blazor WebAssembly 用となると、Sentry はなかなかよい選択肢ではないか、と感じているところです。
上記記事がアプリケーション運用監視サービスの採用選定の一助になれば幸いです。
2025/12/18 追記
Sentry と同類のサービス、"Raygun" についての記事も以下に投稿しました。









