0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Blazor WebAssembly で Sentry を使って予期されない例外発生を記録・通知する

0
Last updated at Posted at 2025-12-11

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" は選択肢として用意はされていませんでした。

image.png

他の指定項目は既定のままにして下へスクロールしていき、プロジェクトスラグを自分の好みや需要にあわせて入力し、[Create Project] をクリックしてプロジェクトの作成を完遂します。

image.png

プロジェクト作成完了のページが表示されます。ここで Sentry へログを送信するための組み込みの手順が書かれているのですが、これはサーバー側で実行される ASP.NET Core 向けの手順です。ブラウザ上で動作する Blazor WebAssembly 向けの手順はこれとは異なるのでひとまずこの手順は無視します。その代わりに、ログを送信する先を示す DSN (Data Source Name) を取得しておきます。

image.png

なお、DSN は以下の手順でも随時確認可能です。まずは [Insights] のメニューから対象のプロジェクトを開き、ページ右上の歯車のアイコンをクリックして、プロジェクトの設定ページを開きます。

image.png

プロジェクトの設定ページが開いたら、サブメニューの下の方に [SDK Setup] のカテゴリに [Client Keys (DSN)] という項目があるので、これを開きます。そうするとページ上に DSN が表示されます。

image.png

以上が、まずは Sentry 上での準備です。まとめると以下のとおりです。

  1. Sentry https://sentry.io にサインアップしてアカウントを作る
  2. Senty 上で "プロジェクト" を作成
  3. プロジェクトの "DSN" (Data Source Name、ログを送信する先の URL) を取得

Blazor WebAssembly 側の作業

Sentry SDK によるデータ収集を組み込む

Blazor WebAssembly プロジェクトに、NuGet パッケージ "Sentry.AspNetCore.Blazor.WebAssembly" を追加します。

*.csproj
<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 を指定します。

Program.cs
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 コンテナに登録するサービスと実装してあります (下記コード)。

Servcies/CounterService.cs
namespace BlazorApp1.Services;

public class CounterService
{
    public int CurrentCount { get; private set; } = 0;

    public void IncrementCount()
    {
        CurrentCount++;
    }
}

ここで、この Counter サービスの実装をいじり、CurrentCount が 3 以上になったら例外をスローするようにしてみます。

Servcies/CounterService.cs
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 上にはエラー発生の黄色いバーが表示されました。

image.png

すると、Sentry の使用を構成してあったので、この例外発生は Sentry SDK によって検知され、sentry.io に送信されています。その結果、senry.io からサインアップしたメールアドレスに、エラー発生を検知した旨のメールが届きます。

image.png

そこで sentry.io の Web ページを開き、[Issues] のサブメニューから [Feed] を開くと、いま発生させた例外の記録が表示されます。

image.png

例外の詳細を開くと、ちゃんと .NET/C# レベルでの呼び出し履歴 (スタックトレース) も記録され、Web UI 上で確認できるのがわかります。

image.png

このように、Blazor WebAssembly アプリケーション上で予期されない例外が発生すると、それが Sentry SDK によって検出され、指定された DSN = sentry.io に情報が送信されます。これをトリガーとして sentry.io からメールで例外発生が報され、senty.io の Web UI にアクセスすることで、呼び出し履歴 (スタックトレース) を含む例外の詳細を知ることができます。こうして、問題の発生を知ることと、その問題の解決のための情報入手とが Sentry によって実現されます。

"Breadcrumb (パンくずリスト)" の利用

Blazor WebAssembly 側に、もう少し手を加えてみます。

App.razor には以下のように <Route> コンポーネントがマークアップされていますが、

App.razor
<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 (パンくずリスト)" に登録するようにします。

App.razor
<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 (パンくずリスト)" が表示され、どのようなページを辿ってこの例外に至ったのかがわかるようになります。

image.png

このように "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" についての記事も以下に投稿しました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?