# 機能設計書 49-eventpipe

## 概要

本ドキュメントは、.NETランタイムにおけるeventpipeコンポーネントの機能設計を記述したものである。eventpipeは、診断イベントのストリーミング機能を提供するネイティブコンポーネントであり、アプリケーションのパフォーマンス分析やトラブルシューティングに使用される。

### 本機能の処理概要

eventpipeは、ランタイム内部で発生するイベント（GC、JIT、例外など）をキャプチャし、外部ツールにストリーミングまたはファイルに保存する機能を提供する。

**業務上の目的・背景**：.NETアプリケーションの性能分析や問題診断のために、ランタイムの内部動作を可視化する必要がある。eventpipeは、ETW（Event Tracing for Windows）やLTTng（Linux Trace Toolkit Next Generation）に代わる、クロスプラットフォームな診断ソリューションを提供する。

**機能の利用シーン**：
- `dotnet-trace`ツールでのトレース収集時
- `dotnet-counters`でのメトリクス監視時
- パフォーマンスプロファイリング時
- 本番環境での問題診断時
- 診断ポート経由のリモート診断時

**主要な処理内容**：
1. イベントプロバイダーの登録と管理
2. セッションの作成と管理
3. イベントのバッファリングとスレッドローカルストレージ
4. イベントのシリアライズとストリーミング
5. サンプルプロファイリング
6. 診断サーバー（IPC通信）

**関連システム・外部連携**：
- 診断クライアント（dotnet-trace, dotnet-counters）
- ファイルシステム（トレースファイル出力）
- IPC（診断ポート）

**権限による制御**：診断ポートへのアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 診断ツールCLI | 主機能 | dotnet-trace, dotnet-counters等 |

## 機能種別

ネイティブコンポーネント / 診断基盤

## 入力仕様

### 入力パラメータ（セッション作成時）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| output_path | string | No | 出力ファイルパス | - |
| circular_buffer_size_in_mb | uint32_t | Yes | 循環バッファサイズ | 正の整数 |
| providers | EventPipeProviderConfiguration[] | Yes | プロバイダー設定 | 少なくとも1つ |
| providers_len | uint32_t | Yes | プロバイダー数 | - |
| session_type | EventPipeSessionType | Yes | セッション種別 | 有効な列挙値 |
| format | EventPipeSerializationFormat | Yes | シリアル化形式 | 有効な列挙値 |
| rundown_keyword | uint64_t | No | ランダウンキーワード | - |
| stackwalk_requested | bool | No | スタックウォーク要求 | - |

### 入力データソース

- イベントプロバイダーからのイベント
- 診断ポート経由のコマンド
- 環境変数（DOTNET_DiagnosticPorts等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| EventPipeSessionID | uint64_t | セッション識別子 |
| トレースデータ | binary | NetTrace/Nettrace形式のイベントデータ |

### 出力先

- ファイル（.nettrace）
- IPCストリーム
- コールバック関数

## 処理フロー

### 処理シーケンス

```
1. eventpipeの初期化
   └─ ep_init()
   └─ プロバイダーの登録

2. セッションの作成
   └─ ep_enable() / ep_enable_2() / ep_enable_3()
   └─ バッファの確保
   └─ プロバイダーのアクティベーション

3. イベントの書き込み
   └─ ep_write_event() / ep_write_event_2()
   └─ スレッドローカルバッファへの書き込み
   └─ バッファフル時のフラッシュ

4. ストリーミング開始
   └─ ep_start_streaming()
   └─ ファイル/IPC出力

5. セッションの無効化
   └─ ep_disable()
   └─ ランダウンイベントの発行
   └─ バッファのフラッシュ

6. 終了処理
   └─ ep_shutdown()
```

### フローチャート

```mermaid
flowchart TD
    A[ep_init] --> B[プロバイダー登録]
    B --> C[ep_enable]
    C --> D[セッション作成]
    D --> E[バッファ確保]
    E --> F[ep_start_streaming]
    F --> G{イベント発生?}
    G -->|Yes| H[ep_write_event]
    H --> I[バッファ書き込み]
    I --> J{バッファフル?}
    J -->|Yes| K[フラッシュ]
    J -->|No| G
    K --> G
    G -->|セッション終了| L[ep_disable]
    L --> M[ランダウン]
    M --> N[ep_shutdown]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-49-01 | 最大セッション数 | 同時セッション数は64まで | EP_MAX_NUMBER_OF_SESSIONS |
| BR-49-02 | プロバイダー一意性 | プロバイダー名は一意である必要 | プロバイダー登録時 |
| BR-49-03 | スレッドセーフ | イベント書き込みはスレッドセーフ | 常時 |
| BR-49-04 | 循環バッファ | バッファフル時は古いイベントを上書き | セッションタイプによる |

### 計算ロジック

該当なし

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 初期化エラー | ep_init失敗 | ランタイム再起動 |
| - | セッションエラー | 最大セッション数超過 | 既存セッションを終了 |
| - | プロバイダーエラー | 無効なプロバイダー名 | 正しい名前を指定 |
| - | IOエラー | 出力ファイルアクセス失敗 | パーミッション確認 |

### リトライ仕様

リトライは行わない。

## トランザクション仕様

該当なし

## パフォーマンス要件

- イベント書き込みのオーバーヘッドを最小化
- スレッドローカルバッファによる競合回避
- 効率的なシリアル化

## セキュリティ考慮事項

- 診断ポートへのアクセス制御
- イベントデータの機密性（メモリ内容を含む可能性）

## 備考

- eventpipeはCross-platformで動作
- NetTrace形式はPerfView/dotnet-traceで解析可能
- ENABLE_PERFTRACINGマクロで有効化

---

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

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

### 推奨読解順序

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

まず、eventpipeの核となるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ep.h | `src/native/eventpipe/ep.h` | 10-15行目のグローバル変数、118-131行目のEventPipeSessionOptions |

**読解のコツ**:
- _ep_state: eventpipeの状態
- _ep_sessions: セッション配列
- _ep_number_of_sessions: アクティブセッション数
- _ep_allow_write: 書き込み許可フラグ

#### Step 2: 初期化と終了を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ep.h | `src/native/eventpipe/ep.h` | 230-236行目のep_init(), ep_finish_init(), ep_shutdown() |

#### Step 3: セッション管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ep.h | `src/native/eventpipe/ep.h` | 167-207行目のep_enable*(), ep_disable(), ep_get_session()等 |

**主要API**:
- ep_enable: 基本的なセッション有効化
- ep_enable_2: プロバイダー設定文字列でのセッション有効化
- ep_enable_3: EventPipeSessionOptions構造体でのセッション有効化
- ep_disable: セッション無効化

#### Step 4: イベント書き込みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ep.h | `src/native/eventpipe/ep.h` | 244-267行目のep_write_event*() |

#### Step 5: プロバイダー管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | ep.h | `src/native/eventpipe/ep.h` | 212-227行目のep_create_provider(), ep_delete_provider(), ep_get_provider() |

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

```
ep_init()
    │
    └─ プロバイダー初期化

ep_enable() / ep_enable_2() / ep_enable_3()
    │
    ├─ セッション作成
    │
    ├─ バッファマネージャー初期化
    │
    └─ プロバイダーアクティベーション

ep_write_event() / ep_write_event_2()
    │
    ├─ ep_volatile_load_allow_write() チェック
    │
    ├─ スレッドローカルバッファ取得
    │
    └─ イベントインスタンス書き込み

ep_start_streaming()
    │
    └─ 出力ストリーム開始

ep_disable()
    │
    ├─ ランダウンイベント発行
    │
    ├─ バッファフラッシュ
    │
    └─ セッション破棄

ep_shutdown()
    │
    └─ 全リソース解放
```

### データフロー図

```
[イベントソース]            [eventpipe]                    [出力]

Provider ──────────▶ ep_write_event()
                           │
                           ▼
                    スレッドローカルバッファ
                           │
                           ▼
                    バッファマネージャー
                           │
                    ┌──────┴──────┐
                    ▼             ▼
                File(.nettrace) IPC Stream
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ep.h | `src/native/eventpipe/ep.h` | ヘッダー | メインAPI定義 |
| ep-types.h | `src/native/eventpipe/ep-types.h` | ヘッダー | 型定義 |
| ep-session.h | `src/native/eventpipe/ep-session.h` | ヘッダー | セッション管理 |
| ep-provider.h | `src/native/eventpipe/ep-provider.h` | ヘッダー | プロバイダー管理 |
| ep-buffer.h | `src/native/eventpipe/ep-buffer.h` | ヘッダー | バッファ管理 |
| ep-buffer-manager.h | `src/native/eventpipe/ep-buffer-manager.h` | ヘッダー | バッファマネージャー |
| ep-event.h | `src/native/eventpipe/ep-event.h` | ヘッダー | イベント定義 |
| ep-event-instance.h | `src/native/eventpipe/ep-event-instance.h` | ヘッダー | イベントインスタンス |
| ep-file.h | `src/native/eventpipe/ep-file.h` | ヘッダー | ファイル出力 |
| ds-server.h | `src/native/eventpipe/ds-server.h` | ヘッダー | 診断サーバー |
