# 帳票設計書 6-JmxSink メトリクスレポート

## 概要

本ドキュメントは、Apache Spark の MetricsSystem における JmxSink が出力する JMX MBean 形式メトリクスレポートの設計書である。Dropwizard Metrics ライブラリの JmxReporter を利用し、Spark の各コンポーネントのメトリクス情報を JMX MBean として公開する。JConsole や VisualVM 等の JMX クライアントツールからリアルタイムにメトリクスを参照可能にする。

### 本帳票の処理概要

JmxSink メトリクスレポートは、Spark の内部メトリクスデータを JMX（Java Management Extensions）MBean としてJVM のプラットフォーム MBean サーバに登録し、外部の JMX クライアントから参照可能にする帳票機能である。

**業務上の目的・背景**：JMX は Java プラットフォーム標準のモニタリング/管理インターフェースであり、追加のソフトウェアインストールなしに利用可能である。JConsole、VisualVM、Java Mission Control 等の標準ツールで Spark のメトリクスをリアルタイムに監視できるため、Java/JVM 運用に精通したチームにとって最も馴染みのある監視手段となる。また、Nagios や Zabbix 等の既存監視システムが JMX プラグインを持つ場合、容易にメトリクス収集を統合できる。

**帳票の利用シーン**：(1) JConsole/VisualVM でリアルタイムにメトリクスを監視する場合、(2) JMX ベースの既存監視システム（Nagios/Zabbix）に統合する場合、(3) Prometheus JMX Exporter 経由で Prometheus にメトリクスを公開する場合。

**主要な出力内容**：
1. Gauge メトリクス（JVM メモリ使用量等）を JMX Gauge MBean として公開
2. Counter メトリクス（タスク数等）を JMX Counter MBean として公開
3. Histogram メトリクス（実行時間分布等）を JMX Histogram MBean として公開
4. Meter メトリクス（スループット等）を JMX Meter MBean として公開
5. Timer メトリクス（応答時間等）を JMX Timer MBean として公開

**帳票の出力タイミング**：MetricsSystem の start() 呼び出し時に JmxReporter が起動し、MBean が登録される。定期的なポーリングは不要で、JMX クライアントからの参照時にリアルタイムの値が返される。

**帳票の利用者**：Java/JVM 運用エンジニア、Spark クラスタ管理者、インフラ監視チーム。

## 帳票種別

メトリクスレポート（JMX MBean 公開型のリアルタイムモニタリング）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | JMX クライアント | JMX URL（例: service:jmx:rmi:///...） | JConsole/VisualVM で接続して参照 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JMX MBean |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（MBean オブジェクト名で識別） |
| 出力方法 | JVM プラットフォーム MBean サーバへの登録 |
| 文字コード | N/A |

### JMX 固有設定

| 項目 | 内容 |
|-----|------|
| MBean ドメイン | Dropwizard Metrics のデフォルトドメイン |
| データ更新方式 | リアルタイム（参照時に最新値を返す） |
| ポーリング | 不要（JmxReporter はイベント駆動） |

## 帳票レイアウト

### レイアウト概要

JMX MBean ツリーとして構造化される。各メトリクスは MBean として登録され、属性（Attribute）としてメトリクス値を公開する。

```
JMX MBean Tree
  └── {domain}
       ├── name={gauge_name}, type=gauges
       │      └── Value (attribute)
       ├── name={counter_name}, type=counters
       │      └── Count (attribute)
       ├── name={histogram_name}, type=histograms
       │      └── Count, Max, Mean, Min, StdDev, ... (attributes)
       ├── name={meter_name}, type=meters
       │      └── Count, MeanRate, ... (attributes)
       └── name={timer_name}, type=timers
              └── Count, Max, Mean, Min, ... (attributes)
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | ObjectName | MBean のオブジェクト名 | JmxReporter | domain:name=xxx,type=xxx |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | Attributes | メトリクス種別に応じた属性群 | MetricRegistry | JMX 属性 | N/A |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | フッターなし | JMX MBean にフッターは存在しない | N/A | N/A |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| MetricRegistry 登録 | MetricRegistry に登録されている全メトリクスが MBean として公開される | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| N/A | JMX MBean はツリー構造であり、ソート順は JMX クライアント依存 | N/A |

### 改ページ条件

JMX MBean のため改ページなし。

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを参照しない。

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| N/A（MetricRegistry） | メトリクスデータの取得元 | N/A |

### テーブル別参照項目詳細

#### MetricRegistry（インメモリ）

| 参照項目 | 帳票項目との対応 | 取得条件 | 備考 |
|---------|----------------|---------|------|
| 全メトリクス | JMX MBean 属性 | JmxReporter がリスナーとして登録 | メトリクスの追加・削除をリアルタイムに反映 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| N/A | JMX MBean はリアルタイムで値を返すため、事前計算は不要 | N/A | MetricRegistry の値をそのまま公開 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[MetricsSystem.start] --> B[JmxSink.start]
    B --> C[JmxReporter.start - MBean 登録開始]
    C --> D[MetricRegistry のメトリクスを MBean として登録]
    D --> E{JMX クライアント接続}
    E --> F[MBean 属性参照リクエスト]
    F --> G[MetricRegistry からリアルタイム値取得]
    G --> H[JMX クライアントへ値返却]
    H --> E
    I[MetricsSystem.stop] --> J[JmxSink.stop]
    J --> K[JmxReporter.stop - MBean 登録解除]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| MBean 登録失敗 | 同名の MBean が既に存在する | JMX 例外（JmxReporter 内部） | メトリクス名の重複を解消 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | メトリクス数に依存 |
| 目標出力時間 | リアルタイム（MBean 参照時に即座に値を返却） |
| 同時出力数上限 | JMX クライアントの同時接続数に依存 |

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

- JMX リモートアクセスを有効にする場合は、認証・SSL を設定すること
- JMX ポートへの外部アクセスをファイアウォールで制限すること
- JMX 経由でメトリクスだけでなく JVM 操作も可能となるため、アクセス権限を適切に管理すること

## 備考

- 設定は `metrics.properties` ファイルで行う。設定例：
  ```
  *.sink.jmx.class=org.apache.spark.metrics.sink.JmxSink
  ```
- JmxSink は他の Sink と異なり、period/unit 等の設定項目を持たない（ポーリング不要）
- report() メソッドは空実装であり、呼び出しても何も行わない
- JMX リモートアクセスの設定は JVM 起動オプションで行う（例: `-Dcom.sun.management.jmxremote.port=9999`）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Sink.scala | `core/src/main/scala/org/apache/spark/metrics/sink/Sink.scala` | Sink トレイトの3メソッド定義（行20-24） |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MetricsSystem.scala | `core/src/main/scala/org/apache/spark/metrics/MetricsSystem.scala` | registerSinks()（行199-240）と start()（行97-106） |

#### Step 3: JmxSink の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | JmxSink.scala | `core/src/main/scala/org/apache/spark/metrics/sink/JmxSink.scala` | クラス全体（行26-41）を通読。他の Sink と比べて最もシンプルな実装であり、設定パラメータを持たない点が特徴 |

**主要処理フロー**:
- **行26-27**: Properties と MetricRegistry をコンストラクタ引数として受け取る（Properties は使用しない）
- **行29**: JmxReporter.forRegistry(registry).build() で直接レポーターを構築。設定パラメータなし
- **行31-33**: start() で JmxReporter.start() を呼び出し（MBean 登録開始）
- **行35-37**: stop() で JmxReporter.stop() を呼び出し（MBean 登録解除）
- **行39**: report() は空実装（JMX はポーリング不要のため）

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

```
MetricsSystem.start()
    |
    +-- registerSinks()
    |       +-- JmxSink.<init>(properties, registry)
    |               +-- JmxReporter.forRegistry(registry).build()
    |
    +-- sinks.foreach(_.start())
            +-- JmxSink.start()
                    +-- JmxReporter.start()
                            +-- MBean サーバに MBean 登録
                            +-- MetricRegistry リスナー登録
```

### データフロー図

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

MetricRegistry         JmxSink                      JMX MBean サーバ
(Gauges,               +-- JmxReporter               MBean ツリー
 Counters,                 +-- forRegistry()          +-- gauges
 Histograms,               +-- build()               +-- counters
 Meters,                   +-- start()               +-- histograms
 Timers)                       (MBean 登録)          +-- meters
                                                      +-- timers
JMX クライアント                                       |
(JConsole,              <-- MBean 属性参照 <----------+
 VisualVM)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Sink.scala | `core/src/main/scala/org/apache/spark/metrics/sink/Sink.scala` | ソース | Sink トレイト定義 |
| JmxSink.scala | `core/src/main/scala/org/apache/spark/metrics/sink/JmxSink.scala` | ソース | JMX MBean 公開 Sink の実装 |
| MetricsSystem.scala | `core/src/main/scala/org/apache/spark/metrics/MetricsSystem.scala` | ソース | Sink の登録・管理・起動 |
