# 機能設計書 57-メトリクスコア

## 概要

本ドキュメントは、Apache Flink のメトリクス収集基盤（flink-metrics-core）の機能設計書である。本モジュールが提供するメトリクスの定義、収集、レポーティングの基盤機能について、処理内容、インターフェース設計、およびコードの構造を詳細に記載する。

### 本機能の処理概要

**業務上の目的・背景**：分散ストリーム処理システムにおいて、ジョブの健全性、パフォーマンス、リソース使用状況を監視することは運用上不可欠である。メトリクスコアは Flink のメトリクスシステムの基盤を提供し、カウンター、ゲージ、ヒストグラム、メーターの4種類のメトリクスを定義・収集し、様々な外部システムにレポートする仕組みを提供する。

**機能の利用シーン**：
- ジョブのスループット・レイテンシを監視する場合
- JVM メモリ使用量・GC 状況を監視する場合
- オペレーター単位のパフォーマンスを計測する場合
- カスタムメトリクスをアプリケーションから収集する場合

**主要な処理内容**：
1. Metric インターフェースと具体的なメトリクス型（Counter, Gauge, Histogram, Meter）の定義
2. MetricGroup による階層的なメトリクス管理
3. MetricReporter インターフェースによる外部システムへのエクスポート
4. MetricReporterFactory によるレポーターのプラグイン機構
5. 定期的なレポーティング（Scheduled インターフェース）

**関連システム・外部連携**：
- JMX（flink-metrics-jmx）
- Prometheus（flink-metrics-prometheus）
- Graphite（flink-metrics-graphite）
- その他メトリクスバックエンド

**権限による制御**：特になし（メトリクスは読み取り専用）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | オーバービュー | API連携 | クラスター統計データのメトリクス収集 |
| 6 | ジョブ概要（DAGグラフ） | API連携 | バックプレッシャー、データスキュー、ウォーターマークのメトリクス取得 |
| 9 | データスキュー | API連携 | メトリクスからのスキュー率計算 |
| 19 | メトリクスチャート | 補助機能 | メトリクスのチャート描画・時系列表示 |
| 20 | バックプレッシャー | 補助機能 | バックプレッシャー状態の視覚化 |
| 21 | フレームグラフ | 補助機能 | CPU使用率のフレームグラフ描画 |
| 23 | JobManagerメトリクス | 補助機能 | JVMメモリ、GC情報などのメトリクス表示 |
| 30 | JobManagerプロファイラ | 補助機能 | プロファイリングインスタンスの作成・結果取得 |
| 33 | TaskManagerメトリクス | 補助機能 | JVMメモリ、GC情報などのメトリクス表示 |
| 37 | TaskManagerプロファイラ | 補助機能 | プロファイリングインスタンスの作成・結果取得 |

## 機能種別

基盤機能 / 監視・可観測性

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| metrics.reporters | String | No | 有効なレポーターのリスト | カンマ区切り文字列 |
| metrics.reporter.<name>.class | String | No | レポータークラス名 | 完全修飾クラス名 |
| metrics.reporter.<name>.interval | Duration | No | レポート間隔 | 有効な期間 |

### 入力データソース

- Flink Configuration（flink-conf.yaml）
- アプリケーションコードからの直接登録

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Counter | long | カウント値 |
| Gauge | T | 任意の型の瞬時値 |
| Histogram | HistogramStatistics | 統計情報（mean, stddev, min, max, quantiles） |
| Meter | double | レート（イベント/秒） |

### 出力先

設定されたメトリクスレポーター（JMX, Prometheus, Graphite 等）

## 処理フロー

### 処理シーケンス

```
1. MetricReporterFactory.createMetricReporter() でレポーター生成
2. MetricReporter.open(MetricConfig) でレポーター初期化
3. MetricGroup.counter/gauge/histogram/meter() でメトリクス登録
4. MetricReporter.notifyOfAddedMetric() で追加通知
5. [定期的] Scheduled.report() でメトリクスをエクスポート
6. MetricReporter.notifyOfRemovedMetric() で削除通知
7. MetricReporter.close() でレポーター終了
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[MetricReporterFactory.createMetricReporter]
    B --> C[MetricReporter.open]
    C --> D{メトリクス操作}
    D -->|登録| E[MetricGroup.counter/gauge/...]
    E --> F[notifyOfAddedMetric]
    F --> D
    D -->|レポート| G[Scheduled.report]
    G --> D
    D -->|削除| H[notifyOfRemovedMetric]
    H --> D
    D -->|終了| I[MetricReporter.close]
    I --> J[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | メトリクス型 | 4種類のメトリクス型をサポート（Counter, Gauge, Histogram, Meter） | 常時 |
| BR-57-02 | 階層構造 | MetricGroup による階層的なスコープ管理 | 常時 |
| BR-57-03 | 変数展開 | MetricGroup の変数（<host>, <tm_id> 等）を識別子に展開 | メトリクス識別子生成時 |
| BR-57-04 | スレッドセーフ | Counter の実装はスレッドセーフであることが推奨 | 並行アクセス時 |

### 計算ロジック

**MeterView**: 時間窓に基づいたレート計算
- rate = (currentCount - previousCount) / interval

**HistogramStatistics**:
- mean, stddev, min, max
- quantile（50th, 75th, 95th, 98th, 99th, 99.9th パーセンタイル）

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UnsupportedOperationException | 非対応メトリクス型 | カスタムメトリクス型を使用 | 標準のメトリクス型を使用 |
| RuntimeException | レポーター初期化エラー | 設定が不正 | 設定を確認 |

### リトライ仕様

メトリクスレポーターの実装に依存。基盤としてはリトライ機構を提供しない。

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

該当なし

## パフォーマンス要件

- メトリクス収集はジョブパフォーマンスに影響を与えないこと
- ThreadSafeSimpleCounter によるロックフリーなカウント
- レポート間隔は設定可能（デフォルト: 10秒）

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

- メトリクスに機密情報を含めないこと
- レポーターへのアクセス制御は各レポーターの実装に依存

## 備考

- View インターフェースはメトリクス表示の更新契機を定義
- CharacterFilter でレポーター固有の文字変換をサポート

---

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

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

### 推奨読解順序

#### Step 1: メトリクスインターフェースを理解する

メトリクスの基本型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Metric.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Metric.java` | 基底インターフェース |
| 1-2 | Counter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Counter.java` | カウンターインターフェース |
| 1-3 | Gauge.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Gauge.java` | ゲージインターフェース |
| 1-4 | Histogram.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Histogram.java` | ヒストグラムインターフェース |
| 1-5 | Meter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Meter.java` | メーターインターフェース |

**主要処理フロー（Counter.java）**:
- **27行目**: void inc() - カウントを1増加
- **35行目**: void inc(long n) - カウントをn増加
- **38行目**: void dec() - カウントを1減少
- **45行目**: void dec(long n) - カウントをn減少
- **52行目**: long getCount() - 現在のカウント値を取得

**読解のコツ**: Metric インターフェースは getMetricType() メソッドを持ち、各具象型は適切な MetricType を返す。

#### Step 2: MetricGroup を理解する

階層的なメトリクス管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MetricGroup.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/MetricGroup.java` | メトリクスグループインターフェース |

**主要処理フロー**:
- **63-73行目**: counter() メソッド - Counterの登録
- **105-117行目**: gauge() メソッド - Gaugeの登録
- **127行目**: histogram() メソッド - Histogramの登録
- **149行目**: meter() メソッド - Meterの登録
- **183行目**: addGroup() メソッド - サブグループの追加
- **211行目**: getScopeComponents() メソッド - スコープ配列取得
- **228行目**: getMetricIdentifier() メソッド - 完全修飾名取得

#### Step 3: MetricReporter を理解する

レポーターインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MetricReporter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/reporter/MetricReporter.java` | レポーターインターフェース |
| 3-2 | MetricReporterFactory.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/reporter/MetricReporterFactory.java` | ファクトリインターフェース |
| 3-3 | AbstractReporter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/reporter/AbstractReporter.java` | 基底実装クラス |

**主要処理フロー（MetricReporter.java）**:
- **45行目**: notifyOfAddedMetric() - メトリクス追加通知
- **54行目**: notifyOfRemovedMetric() - メトリクス削除通知

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

```
MetricReporterFactory
    │
    └─ createMetricReporter(Properties)
           │
           └─ MetricReporter
                  │
                  ├─ open(MetricConfig)
                  │
                  ├─ notifyOfAddedMetric(Metric, name, MetricGroup)
                  │      └─ MetricGroup.getMetricIdentifier(name)
                  │             └─ getScopeComponents()
                  │             └─ getAllVariables()
                  │
                  ├─ [Scheduled] report()
                  │      └─ Counter.getCount()
                  │      └─ Gauge.getValue()
                  │      └─ Histogram.getStatistics()
                  │      └─ Meter.getRate()
                  │
                  ├─ notifyOfRemovedMetric(Metric, name, MetricGroup)
                  │
                  └─ close()
```

### データフロー図

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

アプリケーションコード ────▶ MetricGroup.counter() ──────▶ Counter登録
                                 │
ジョブ状態変化 ──────────────▶ Gauge.getValue() ──────────▶ 瞬時値
                                 │
イベント発生 ────────────────▶ Histogram.update() ────────▶ 統計情報
                                 │
スループット計測 ────────────▶ Meter.markEvent() ─────────▶ レート
                                 │
定期トリガー ────────────────▶ MetricReporter.report() ──▶ 外部システム
                                                            (JMX/Prometheus/...)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Metric.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Metric.java` | ソース | 基底インターフェース |
| Counter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Counter.java` | ソース | カウンターインターフェース |
| Gauge.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Gauge.java` | ソース | ゲージインターフェース |
| Histogram.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Histogram.java` | ソース | ヒストグラムインターフェース |
| Meter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/Meter.java` | ソース | メーターインターフェース |
| MetricGroup.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/MetricGroup.java` | ソース | グループインターフェース |
| MetricReporter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/reporter/MetricReporter.java` | ソース | レポーターインターフェース |
| MetricReporterFactory.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/reporter/MetricReporterFactory.java` | ソース | ファクトリインターフェース |
| AbstractReporter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/reporter/AbstractReporter.java` | ソース | 基底レポーター実装 |
| SimpleCounter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/SimpleCounter.java` | ソース | シンプルカウンター実装 |
| ThreadSafeSimpleCounter.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/ThreadSafeSimpleCounter.java` | ソース | スレッドセーフカウンター |
| MeterView.java | `flink-metrics/flink-metrics-core/src/main/java/org/apache/flink/metrics/MeterView.java` | ソース | メータービュー実装 |
