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

## 概要

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

### 本機能の処理概要

StatsDメトリクスレポーターは、Flinkランタイムで収集されたメトリクス（Counter、Gauge、Histogram、Meter）をStatsDデーモンにUDP経由でエクスポートする機能である。

**業務上の目的・背景**：StatsDはシンプルで広く採用されているメトリクス収集プロトコルであり、Graphite、DatadogAgent、InfluxDB Telegrafなど多くのバックエンドと連携可能である。本機能により、既存のStatsDベースの監視インフラストラクチャにFlinkメトリクスを統合できる。

**機能の利用シーン**：
- 既存のStatsD/Graphite監視インフラへのFlink統合
- 軽量なUDPベースのメトリクス収集
- オンプレミス環境でのシンプルな監視設定
- 複数言語・システムが混在する環境での統一メトリクス収集

**主要な処理内容**：
1. メトリクスの登録・削除通知の受信と識別子の生成
2. 定期的なレポート間隔でのメトリクス収集
3. StatsD Gauge形式（`name:value|g`）へのフォーマット
4. UDPパケットによる送信

**関連システム・外部連携**：
- StatsDデーモン（Graphite、DatadogAgent、Telegraf等）
- DatagramSocket（UDP通信）

**権限による制御**：認証機能なし（StatsDプロトコル仕様）

## 関連画面

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

## 機能種別

データ連携（メトリクスのStatsDへのエクスポート）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| host | String | Yes | StatsDサーバーホスト名 | 空でないこと |
| port | Integer | Yes | StatsDサーバーポート | 有効なポート番号（1-65535） |

### 入力データソース

- Flinkランタイムから通知されるメトリクス（Counter、Gauge、Histogram、Meter）
- 設定ファイル（flink-conf.yaml）からのレポーター設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| name | String | メトリクス識別子（スコープ付き） |
| value | String | メトリクス値 |
| type | String | 常に "g"（gauge） |

### 出力先

StatsDデーモン（UDPプロトコル、フォーマット: `name:value|g`）

## 処理フロー

### 処理シーケンス

```
1. レポーター初期化（open）
   └─ 設定パラメータの読み込みとバリデーション
   └─ DatagramSocketの作成
   └─ InetSocketAddressの設定

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

3. 定期レポート（report）
   └─ 全Gaugeの送信
   └─ 全Counterの送信
   └─ 全Histogramの送信（統計値展開）
   └─ 全Meterの送信

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

5. シャットダウン（close）
   └─ DatagramSocketのクローズ
```

### フローチャート

```mermaid
flowchart TD
    A[開始: report] --> B{closed?}
    B -->|Yes| Z[終了]
    B -->|No| C[Gauge処理]
    C --> D{closed?}
    D -->|Yes| Z
    D -->|No| E[Counter処理]
    E --> F[Histogram処理]
    F --> G[Meter処理]
    G --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | コロン変換 | メトリクス名中のコロン(:)はハイフン(-)に変換 | filterCharacters適用時 |
| BR-02 | Gaugeヌル対応 | Gauge値がnullの場合は送信スキップ | reportGauge時 |
| BR-03 | 負数対応 | 負の値は事前に0にリセットしてから送信 | send時 |
| BR-04 | 並行更新対応 | メトリクス収集中の並行変更は無視 | ConcurrentModificationException時 |

### 計算ロジック

Histogramメトリクスでは以下の統計値を個別送信:
- count: サンプル数
- min/max: 最小値/最大値
- mean: 平均値
- stddev: 標準偏差
- p50/p75/p95/p98/p99/p999: パーセンタイル値

Meterメトリクスでは以下を送信:
- rate: レート値
- count: カウント値

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IllegalArgumentException | 設定エラー | host/portが無効 | 設定を修正 |
| SocketException | ソケットエラー | DatagramSocket作成失敗 | RuntimeExceptionとして伝播 |
| IOException | 通信エラー | UDP送信失敗 | エラーログ出力（継続） |
| ConcurrentModificationException | 並行エラー | メトリクス登録/削除の並行実行 | 自動スキップ |

### リトライ仕様

- UDP送信は再試行しない（UDPの特性上、信頼性は保証しない）
- IOException発生時はログ出力のみで処理継続

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

- UDPはコネクションレスのため、トランザクション概念なし
- 各メトリクスは独立したパケットとして送信

## パフォーマンス要件

- 軽量なUDPプロトコルにより低オーバーヘッド
- UTF-8エンコーディングでパケット生成
- closedフラグによる早期終了で無駄な処理を回避

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

- UDP通信のため暗号化なし
- 認証機能なし（StatsDプロトコル仕様）
- ネットワークセグメンテーションでの保護を推奨

## 備考

- ReadyTalk社のmetrics-statsdを参考に実装
- StatsDの標準的なGaugeフォーマット（`name:value|g`）を使用

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AbstractReporter | `flink-core/src/main/java/org/apache/flink/metrics/reporter/AbstractReporter.java` | メトリクス管理の基底クラス |

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

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

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

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

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

**主要処理フロー（StatsDReporter.java）**:
- **64-82行目**: open()で設定読み込みとDatagramSocket初期化
- **84-90行目**: close()でソケットクローズ
- **95-125行目**: report()でメトリクス収集と送信
- **129-172行目**: 各メトリクス種別の送信処理
- **205-216行目**: send()でUDPパケット送信
- **219-243行目**: filterCharacters()でコロンをハイフンに変換

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

```
StatsDReporterFactory.createMetricReporter()
    │
    └─ new StatsDReporter()
           │
           ├─ AbstractReporter（継承）
           │      ├─ notifyOfAddedMetric()
           │      └─ notifyOfRemovedMetric()
           │
           ├─ open()
           │      └─ new DatagramSocket()
           │
           └─ report() [Scheduled]
                  │
                  ├─ reportGauge()
                  │      └─ send()
                  │
                  ├─ reportCounter()
                  │      └─ send()
                  │
                  ├─ reportHistogram()
                  │      └─ send() × 11 (各統計値)
                  │
                  └─ reportMeter()
                         └─ send() × 2 (rate, count)
```

### データフロー図

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

Flink Metrics          ┌─────────────────────────┐
  (Counter/Gauge/      │   StatsDReporter        │           StatsD Daemon
   Histogram/Meter) ──▶│                         │──▶  UDP Packets
                       │   ┌─────────────────┐   │     (name:value|g)
                       │   │ DatagramSocket  │   │
MetricConfig ────────▶ │   │                 │   │
  (host, port)         │   └─────────────────┘   │
                       └─────────────────────────┘
```

### 関連ファイル一覧

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