# 機能設計書 64-SLF4Jメトリクスレポーター

## 概要

本ドキュメントは、Apache FlinkのSLF4Jメトリクスレポーター機能（flink-metrics-slf4j モジュール）の設計仕様を記載する。

### 本機能の処理概要

SLF4Jメトリクスレポーターは、Flinkランタイムで収集されたメトリクス（Counter、Gauge、Histogram、Meter）をSLF4Jログフレームワーク経由でログ出力する機能である。

**業務上の目的・背景**：開発・デバッグ環境においてメトリクスの値を簡単に確認するため、または既存のログ収集インフラ（ELK Stack、Splunk等）を通じてメトリクスを収集するために使用される。追加の監視インフラを構築せずにメトリクスを取得できるため、シンプルな運用や初期検証に適している。

**機能の利用シーン**：
- 開発環境でのメトリクス値の確認・デバッグ
- 既存のログ収集システムを活用したメトリクス収集
- 外部システム連携なしでのメトリクス監視
- テスト環境でのメトリクス検証

**主要な処理内容**：
1. メトリクスの登録・削除通知の受信と識別子の生成
2. 定期的なレポート間隔でのメトリクス収集
3. 整形されたテキスト形式へのフォーマット
4. SLF4J Logger（INFOレベル）への出力

**関連システム・外部連携**：
- SLF4J Logger API
- 各種ログバックエンド（Logback、Log4j2等）

**権限による制御**：なし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は画面を持たないバックエンド処理機能 |

## 機能種別

データ連携（メトリクスのログ出力）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| （なし） | - | - | 設定パラメータなし | - |

### 入力データソース

- Flinkランタイムから通知されるメトリクス（Counter、Gauge、Histogram、Meter）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| レポートヘッダー | String | 開始・終了を示す区切り線 |
| セクションヘッダー | String | メトリクス種別（Counters/Gauges/Meters/Histograms） |
| メトリクスエントリ | String | 識別子: 値 形式 |

### 出力先

SLF4J Logger（org.apache.flink.metrics.slf4j.Slf4jReporter、INFOレベル）

## 処理フロー

### 処理シーケンス

```
1. レポーター初期化（open）
   └─ 処理なし（設定不要）

2. メトリクス登録（notifyOfAddedMetric）[AbstractReporter]
   └─ メトリクス識別子の生成
   └─ 種別に応じた内部マップへの登録

3. 定期レポート（report）
   └─ メトリクス存在チェック
   └─ StringBuilderによる出力構築
   └─ 種別ごとのセクション出力
   └─ LOG.info()による出力

4. メトリクス削除（notifyOfRemovedMetric）[AbstractReporter]
   └─ 内部マップからの削除

5. シャットダウン（close）
   └─ 処理なし
```

### フローチャート

```mermaid
flowchart TD
    A[開始: report] --> B{メトリクス存在?}
    B -->|No| C[スキップログ出力]
    B -->|Yes| D[StringBuilder初期化]
    C --> Z[終了]
    D --> E[開始区切り線追加]
    E --> F[Counters出力]
    F --> G[Gauges出力]
    G --> H[Meters出力]
    H --> I[Histograms出力]
    I --> J[終了区切り線追加]
    J --> K[LOG.info出力]
    K --> L[previousSize更新]
    L --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 空メトリクススキップ | 登録メトリクスが0件の場合はスキップログ出力 | 全マップが空の場合 |
| BR-02 | 文字フィルタなし | メトリクス名はそのまま使用（filterCharactersで変換なし） | 常時 |
| BR-03 | バッファサイズ最適化 | 前回の出力サイズを基に次回バッファを確保 | report()実行時 |
| BR-04 | 並行更新対応 | ConcurrentModificationException時はスキップ | メトリクス収集中 |

### 計算ロジック

Histogramメトリクスでは以下の統計値を一行で出力:
- count, min, max, mean, stddev
- p50, p75, p95, p98, p99, p999

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConcurrentModificationException | 並行エラー | メトリクス登録/削除の並行実行 | 自動スキップ（tryReport内でキャッチ） |
| NoSuchElementException | イテレータエラー | 反復中の要素削除 | 自動スキップ |

### リトライ仕様

- エラー発生時はスキップし、次回のレポートサイクルで再試行

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

- トランザクション概念なし（ログ出力のみ）

## パフォーマンス要件

- 初期バッファサイズ: 16384文字（約150メトリクス対応）
- 次回バッファ: 前回サイズ × 1.1 で動的調整
- システム改行コード使用（System.lineSeparator()）

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

- メトリクス値がログに出力されるため、機密情報を含むメトリクスに注意
- ログファイルのアクセス制御はログバックエンドの設定に依存

## 備考

- 開発・デバッグ用途に適している
- 本番環境では専用の監視システム（Prometheus、Datadog等）を推奨

---

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

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

### 推奨読解順序

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

本モジュールは専用のデータ構造を持たず、flink-metrics-coreのAbstractReporterの標準構造を使用する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Slf4jReporterFactory.java | `flink-metrics/flink-metrics-slf4j/src/main/java/org/apache/flink/metrics/slf4j/Slf4jReporterFactory.java` | ファクトリクラス |

**主要処理フロー**:
1. **29-31行目**: createMetricReporter()でSlf4jReporterインスタンスを生成

#### Step 3: メインレポーター実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Slf4jReporter.java | `flink-metrics/flink-metrics-slf4j/src/main/java/org/apache/flink/metrics/slf4j/Slf4jReporter.java` | メインレポーター実装 |

**主要処理フロー（Slf4jReporter.java）**:
- **43-48行目**: クラス定義とフィールド（LOG、lineSeparator、previousSize）
- **70-75行目**: open()/close()は空実装
- **77-86行目**: report()でtryReport()をエラーハンドリング付きで呼び出し
- **88-143行目**: tryReport()でメトリクス収集とログ出力
- **145-175行目**: report()オーバーロードでセクション別出力

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

```
Slf4jReporterFactory.createMetricReporter()
    │
    └─ new Slf4jReporter()
           │
           ├─ AbstractReporter（継承）
           │      ├─ notifyOfAddedMetric()
           │      └─ notifyOfRemovedMetric()
           │
           └─ report() [Scheduled]
                  │
                  └─ tryReport()
                         │
                         ├─ report(builder, "Counters", counters, ...)
                         ├─ report(builder, "Gauges", gauges, ...)
                         ├─ report(builder, "Meters", meters, ...)
                         └─ report(builder, "Histograms", histograms, ...)
```

### データフロー図

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

Flink Metrics          ┌─────────────────────────┐
  (Counter/Gauge/      │   Slf4jReporter         │           SLF4J Logger
   Histogram/Meter) ──▶│                         │──▶  LOG.info()
                       │   ┌─────────────────┐   │     (テキスト出力)
                       │   │ StringBuilder   │   │
                       │   │                 │   │
                       │   └─────────────────┘   │
                       └─────────────────────────┘
```

### 出力フォーマット例

```
=========================== Starting metrics report ===========================

-- Counters ---------------------------------------------------------------------
taskmanager.job.task.numBytesIn: 12345

-- Gauges ---------------------------------------------------------------------
taskmanager.Status.JVM.Memory.Heap.Used: 123456789

-- Meters ---------------------------------------------------------------------
taskmanager.job.task.numRecordsInPerSecond: 1000.5

-- Histograms ---------------------------------------------------------------------
taskmanager.job.task.latency: count=100, min=1, max=500, mean=50.5, stddev=25.3, p50=45, p75=60, p95=150, p98=200, p99=300, p999=450

=========================== Finished metrics report ===========================
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Slf4jReporter.java | `flink-metrics/flink-metrics-slf4j/src/main/java/org/apache/flink/metrics/slf4j/` | ソース | メインレポーター実装 |
| Slf4jReporterFactory.java | `flink-metrics/flink-metrics-slf4j/src/main/java/org/apache/flink/metrics/slf4j/` | ソース | ファクトリクラス |
| Slf4jTraceReporter.java | `flink-metrics/flink-metrics-slf4j/src/main/java/org/apache/flink/traces/slf4j/` | ソース | トレースレポーター |
| Slf4jEventReporter.java | `flink-metrics/flink-metrics-slf4j/src/main/java/org/apache/flink/events/slf4j/` | ソース | イベントレポーター |
| org.apache.flink.metrics.reporter.MetricReporterFactory | `flink-metrics/flink-metrics-slf4j/src/main/resources/META-INF/services/` | 設定 | SPIサービス定義 |
