# 画面設計書 8-EventPipe Profiling Sample

## 概要

本ドキュメントは、.NET WebAssembly の EventPipe プロファイリングサンプル画面「EventPipe Profiling Sample」の設計内容を記載した画面設計書です。本画面は .NET Runtime リポジトリにおける WebAssembly の EventPipe 診断機能をデモンストレーションするサンプルアプリケーションです。

### 本画面の処理概要

本画面は、ブラウザ上で .NET WebAssembly ランタイムの EventPipe 機能を使用して、アプリケーション診断イベントの生成と収集をデモンストレーションするサンプルアプリケーションです。「Say Hi」ボタンをクリックすると、C# コードから EventSource イベントを発行し、その結果を画面に表示します。

**業務上の目的・背景**：本画面は、.NET WebAssembly アプリケーションにおける EventPipe 診断機能を検証・デモンストレーションするために作成されました。EventPipe は .NET の診断サブシステムで、パフォーマンスカウンター、トレーシング、イベント発行などの機能を提供します。本サンプルでは、カスタム EventSource（WasmHello）を使用してイベントを発行し、ConsoleWriterEventListener でイベントをキャプチャしてコンソールに出力します。

**画面へのアクセス方法**：ローカル開発サーバー（通常は `http://localhost:8000/`）にブラウザでアクセスすることで画面を表示できます。

**主要な操作・処理内容**：
1. 画面ロード時に JavaScript（main.js）が .NET WebAssembly ランタイムを初期化
2. C# の Main メソッドで EventSource と EventListener を初期化
3. `DisplayMeaning(42)` で結果を DOM に表示
4. `runMain()` でアプリケーションを実行
5. `SayHi()` を呼び出して初期挨拶を表示
6. 「Say Hi」ボタンクリックで `SayHi()` を再度呼び出し、EventSource イベントを発行

**画面遷移**：本画面は単一画面のサンプルアプリケーションであり、他画面への遷移はありません。

**権限による表示制御**：本画面は認証・認可機能を持たないデモアプリケーションであり、権限による表示制御はありません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Mono | 主機能 | WebAssembly ランタイム上で EventPipe プロファイリングを実行 |
| 49 | eventpipe | 主機能 | EventPipe による診断イベントのストリーミング |
| 28 | System.Diagnostics.DiagnosticSource | 主機能 | アプリケーション診断とトレーシング |
| 59 | WebAssembly Workload | 補助機能 | WebAssembly アプリケーションのビルドと実行をサポート |

## 画面種別

インタラクティブデモ画面（単一画面）

## URL/ルーティング

- ローカル開発: `http://localhost:8000/index.html`
- 静的ファイルパス: `src/mono/sample/wasm/browser-eventpipe/wwwroot/index.html`

## 入出力項目

| 項目名 | 入出力 | データ型 | 説明 |
|--------|--------|----------|------|
| - | - | - | 本画面にテキスト入力項目はありません |

## 表示項目

| 項目ID | 項目名 | 要素タイプ | 説明 |
|--------|--------|-----------|------|
| header | 画面タイトル | h3 | 「Wasm Browser EventPipe profiling Sample」と表示 |
| hello-button | Say Hi ボタン | button | クリックで SayHi() を呼び出し |
| out | 計算結果 | span | 「究極の問いへの答え」（42）を表示 |

## イベント仕様

### 1-画面ロード完了イベント

画面がロードされると、以下の処理が自動的に実行されます:

1. `main.js` がモジュールとして読み込まれる
2. `dotnet.create()` で WebAssembly ランタイムを初期化
3. `setModuleImports` で JavaScript 関数を C# から呼び出せるように登録
4. `getAssemblyExports` で C# の公開メソッドを取得
5. 「Say Hi」ボタンにクリックイベントを登録
6. `runMain()` で C# の Main メソッドを実行
7. `sayHi()` を呼び出して初期挨拶と EventSource イベントを発行

### 2-Say Hi ボタンクリック

1. `sayHi()` を呼び出し
2. C# の `SayHi()` メソッドが実行される
3. コンソールに「Hi from C#!」「Wave from C#!」「Bye from C#!」を出力
4. EventSource で HelloStart / HelloStop イベントを発行
5. IncrementingEventCounter で呼び出し回数をカウント（100,000 回インクリメント）
6. 例外のスロー・キャッチをテスト

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | 本画面はデータベースを使用しません |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| MSG-001 | 情報 | Hi from C#! {ActivityId} | SayHi 開始時にコンソール出力 |
| MSG-002 | 情報 | Wave from C#! {ActivityId} | SayHi 中間でコンソール出力 |
| MSG-003 | 情報 | Bye from C#! {ActivityId} | SayHi 終了時にコンソール出力 |
| MSG-004 | 情報 | Caught exception: {message} | 例外キャッチ時にコンソール出力 |
| MSG-005 | イベント | Started Hello({n}) | WasmHelloEventSource.HelloStart イベント |
| MSG-006 | イベント | Stopped Hello({n}) = {result} | WasmHelloEventSource.HelloStop イベント |

## 例外処理

| 例外種別 | 発生条件 | 対応処理 |
|---------|---------|---------|
| Exception | SayHiThrow() 呼び出し時 | SayHiCatch() で catch し、メッセージをコンソール出力 |
| JavaScript エラー | ランタイム初期化失敗時 | `exit(2, err)` で終了 |
| ボタンクリック例外 | SayHi() 実行中のエラー | `alert(exc)` で例外内容を表示 |

## 備考

- WasmHelloEventSource（カスタム EventSource）で診断イベントを発行
- ConsoleWriterEventListener で EventSource イベントをキャプチャ
- IncrementingEventCounter で呼び出し回数をカウント（"hello-calls"）
- EventLevel.Informational でイベントを有効化
- `EventSource.CurrentThreadActivityId` でアクティビティ ID を追跡
- コメントアウトされた環境変数設定で様々な診断モードをテスト可能

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、EventSource と EventListener の構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Program.cs | `src/mono/sample/wasm/browser-eventpipe/Program.cs` | WasmHelloEventSource と ConsoleWriterEventListener の定義を確認 |

**読解のコツ**: `[EventSource(Name = "WasmHello")]` でイベントソース名を定義し、`[Event(n)]` 属性でイベント ID を指定します。

#### Step 2: エントリーポイントを理解する

処理の起点となるファイル・関数を特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.html | `src/mono/sample/wasm/browser-eventpipe/wwwroot/index.html` | HTML 構造と Say Hi ボタンを確認 |
| 2-2 | main.js | `src/mono/sample/wasm/browser-eventpipe/wwwroot/main.js` | ランタイム初期化とボタンイベント登録を確認 |

**主要処理フロー (main.js)**:
1. **6-8行目**: `displayMeaning` 関数 - DOM を更新
2. **10-31行目**: `dotnet.create()` でランタイム初期化
3. **33-39行目**: `setModuleImports` で JavaScript 関数を公開
4. **40-42行目**: C# メソッドの取得
5. **45-51行目**: 「Say Hi」ボタンにクリックイベント登録
6. **53-56行目**: `runMain()` と `sayHi()` 呼び出し

#### Step 3: C# 側の EventSource 実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Program.cs | `src/mono/sample/wasm/browser-eventpipe/Program.cs` | SayHi メソッドと EventSource イベント発行を確認 |

**主要処理フロー (Program.cs)**:
- **14-34行目**: `ConsoleWriterEventListener` - EventSource イベントをコンソールに出力
- **38-47行目**: `Main` - EventSource 初期化と EventListener 作成
- **54-69行目**: `SayHi` - HelloStart/HelloStop イベント発行、CountCall インクリメント
- **109-160行目**: `WasmHelloEventSource` - カスタム EventSource 実装

### プログラム呼び出し階層図

```
[Browser] index.html 読み込み
    |
    +-- [JavaScript] main.js 実行
            |
            +-- dotnet.create() - WebAssembly ランタイム初期化
            |
            +-- setModuleImports() - displayMeaning を公開
            |
            +-- getAssemblyExports() - C# メソッドを取得
            |
            +-- #hello-button.click イベント登録
            |
            +-- runMain() - C# Main 実行
            |       |
            |       +-- [C#] Main()
            |               |
            |               +-- DisplayMeaning(42) --> [JS] displayMeaning(42)
            |               +-- WasmHelloEventSource.Instance.NewCallsCounter()
            |               +-- new ConsoleWriterEventListener()
            |
            +-- sayHi() - 初期呼び出し
                    |
                    +-- [C#] SayHi()
                            |
                            +-- Console.WriteLine("Hi from C#!")
                            +-- WasmHelloEventSource.HelloStart(counter)
                            +-- CountCall() x 100,000
                            +-- SayHiCatch() --> SayHiThrow() --> catch
                            +-- WasmHelloEventSource.HelloStop(counter, result)
                            +-- Console.WriteLine("Bye from C#!")

[User] #hello-button クリック
    |
    +-- sayHi() 呼び出し
            |
            +-- (同上の処理フロー)
```

### データフロー図

```
[入力]                      [処理]                           [出力]

                     +-- Main() ----+
                     |              |
                     v              v
              DisplayMeaning(42)   EventSource/Listener 初期化
                     |
                     v
              document.getElementById("out")
                 .innerHTML = "42"

ボタンクリック -----> SayHi()
                        |
           +------------+------------+
           |            |            |
           v            v            v
    HelloStart()   CountCall()   SayHiCatch()
    (Event ID=1)   x 100,000     例外テスト
           |            |            |
           v            v            v
    EventListener  IncrementingEventCounter   Console.WriteLine
    に通知         インクリメント           ("Caught exception")
           |
           v
    HelloStop()
    (Event ID=2)
           |
           v
    EventListener
    に通知
           |
           v
    Console.WriteLine
    (タイムスタンプ + EventName)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.html | `src/mono/sample/wasm/browser-eventpipe/wwwroot/index.html` | テンプレート | HTML エントリーポイント、Say Hi ボタン |
| main.js | `src/mono/sample/wasm/browser-eventpipe/wwwroot/main.js` | ソース | JavaScript エントリーポイント、イベント登録 |
| Program.cs | `src/mono/sample/wasm/browser-eventpipe/Program.cs` | ソース | C# メインロジック、EventSource、EventListener |
| dotnet.js | `_framework/dotnet.js` | ランタイム | .NET WebAssembly ランタイムローダー（ビルド時生成） |
