# 機能設計書 48-ロード統計

## 概要

本ドキュメントは、JenkinsのLoad Statistics（ロード統計）機能の設計を記載する。

### 本機能の処理概要

ロード統計は、Jenkinsのビルドエグゼキュータの利用状況を時系列で監視・表示する機能を提供する。オンラインエグゼキュータ数、ビジー状態のエグゼキュータ数、キュー長などの統計情報をグラフ化して表示する。

**業務上の目的・背景**：CI/CD環境のキャパシティプランニングにおいて、エグゼキュータの利用状況を把握することは重要である。ロード統計を分析することで、リソースの過不足を判断し、エージェントの追加や削減を計画できる。

**機能の利用シーン**：
- エグゼキュータ利用率の監視
- キャパシティプランニング
- ビルドキュー滞留の分析
- クラウドエージェントの自動スケーリング判断
- パフォーマンスボトルネックの特定

**主要な処理内容**：
1. 定期的なエグゼキュータ状態の収集（10秒間隔）
2. 時系列データの集計（分/時/日/週/月/年）
3. 統計グラフの生成
4. REST API経由でのデータ提供

**関連システム・外部連携**：NodeProvisioner（クラウドプロビジョニング）がロード統計を参照してエージェント増減を判断。

**権限による制御**：ロード統計の表示にはJenkins.READ権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 51 | ロード統計 | 主画面 | ロード統計グラフの表示 |

## 機能種別

監視 / 統計 / グラフ表示

## 入力仕様

### 入力パラメータ

#### グラフ表示

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | String | No | 時間スケール（sec10/min/hour/day/week/month/year） | 有効なTimeScale値 |

### 入力データソース

- Node/Computer状態（定期ポーリング）
- ビルドキュー状態

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| definedExecutors | int | 定義されているエグゼキュータ総数 |
| onlineExecutors | int | オンライン状態のエグゼキュータ数 |
| connectingExecutors | int | 接続中のエグゼキュータ数 |
| busyExecutors | int | ビジー状態のエグゼキュータ数 |
| idleExecutors | int | アイドル状態のエグゼキュータ数 |
| availableExecutors | int | 利用可能なエグゼキュータ数 |
| queueLength | int | ビルドキューの長さ |

### 出力先

- Web UI（グラフ画像）
- REST API（JSON/XML）

## 処理フロー

### 処理シーケンス

```
1. LoadStatisticsUpdater起動（PeriodicWork）
   └─ CLOCK間隔（デフォルト10秒）で実行
2. スナップショット収集
   └─ 各ノードのエグゼキュータ状態を収集
   └─ ビルドキューの長さを計算
3. 時系列データ更新
   └─ MultiStageTimeSeriesに各メトリクスを追加
4. グラフ描画要求時
   └─ JFreeChartでグラフ生成
   └─ PNG画像として返却
```

### フローチャート

```mermaid
flowchart TD
    A[LoadStatisticsUpdater.doRun] --> B[Jenkins.getLabels()取得]
    B --> C[各ラベルのloadStatistics更新]
    C --> D[computeSnapshot()実行]
    D --> E[全ノードの状態を収集]
    E --> F[各ノードに対してループ]
    F --> G{オンライン?}
    G -->|Yes| H[executors状態カウント]
    G -->|No| I[defined/connecting更新]
    H --> J[queueLength計算]
    I --> J
    J --> K[updateCounts()で時系列更新]
    K --> L{全ラベル処理完了?}
    L -->|No| C
    L -->|Yes| M[unlabeledLoad更新]
    M --> N[overallLoad更新]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-48-01 | 定期更新 | デフォルト10秒間隔でエグゼキュータ状態を更新 | 常時 |
| BR-48-02 | 減衰率 | 時系列データはDECAY（デフォルト0.9）で減衰 | 各更新時 |
| BR-48-03 | ラベル別統計 | 各ラベルごとにロード統計を保持 | 全ラベル |
| BR-48-04 | 全体統計 | overallLoadで全エグゼキュータの統計を保持 | Jenkins全体 |
| BR-48-05 | ラベルなし統計 | unlabeledLoadでラベルなしエグゼキュータの統計を保持 | ラベルなしノード |

### 計算ロジック

#### スナップショット計算
```
definedExecutors = オフラインノード含む全エグゼキュータ数
onlineExecutors = オンラインノードのエグゼキュータ数
connectingExecutors = 接続中ノードのエグゼキュータ数
busyExecutors = 実行中のエグゼキュータ数
idleExecutors = onlineExecutors - busyExecutors
availableExecutors = idleExecutors のうち acceptingTasks=true のもの
queueLength = 対象ラベルにマッチするBuildableItemの数
```

#### 減衰計算
```
半減期 = CLOCK * log(0.5) / log(DECAY)
         = 10秒 * log(0.5) / log(0.9)
         ≈ 約66秒（約1分）
```

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

ロード統計はメモリ上で管理され、永続化されない。Jenkins再起動時に統計はリセットされる。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IllegalArgumentException | 不正なTimeScale | typeパラメータが不正 | 有効なTimeScale値を指定 |

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

該当なし（メモリ上の統計データのみ）

## パフォーマンス要件

- スナップショット計算: ノード数に比例（100ノードで1秒以内推奨）
- グラフ生成: 1秒以内

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

- ロード統計の表示にはJenkins.READ権限が必要
- 機密情報は含まれないため、特別なセキュリティ対策は不要

## 備考

- DECAY値とCLOCK値はシステムプロパティで変更可能
- NodeProvisionerがロード統計を参照してクラウドエージェントをプロビジョニング

---

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

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

### 推奨読解順序

#### Step 1: LoadStatistics基盤を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LoadStatistics.java | `core/src/main/java/hudson/model/LoadStatistics.java` | ロード統計の基底クラス |
| 1-2 | MultiStageTimeSeries.java | `core/src/main/java/hudson/model/MultiStageTimeSeries.java` | 時系列データ管理 |

**主要処理フロー（LoadStatistics）**:
- **74-131行目**: 時系列フィールド定義（definedExecutors, onlineExecutors, busyExecutors等）
- **133-149行目**: コンストラクタ（各時系列の初期化）
- **189-226行目**: createChart() - JFreeChartでグラフ生成
- **239-241行目**: createTrendChart() - トレンドチャート生成
- **267-275行目**: updateCounts() - 統計値の更新
- **282行目**: getNodes() - 対象ノード取得（抽象メソッド）
- **291行目**: matches() - キューアイテムのマッチング判定（抽象メソッド）
- **304-334行目**: computeSnapshot() - スナップショット計算
- **341-346行目**: DECAY/CLOCK定数定義
- **352-385行目**: LoadStatisticsUpdater - 定期更新処理

**LoadStatisticsSnapshot（内部クラス）**:
- **392-439行目**: スナップショットデータ構造
- **564-619行目**: Builder - スナップショットのビルダー

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

```
LoadStatisticsUpdater (PeriodicWork)
    │
    ├─ Jenkins.get()
    │
    ├─ 各Label.loadStatistics.updateCounts()
    │      └─ computeSnapshot()
    │             ├─ getNodes() → Iterable<Node>
    │             └─ builder.with(node)
    │                    └─ Computer状態を収集
    │
    ├─ unlabeledLoad.updateCounts()
    │
    └─ overallLoad.updateCounts()

グラフ表示
    │
    └─ LoadStatistics.createTrendChart(timeScale)
           └─ MultiStageTimeSeries.createTrendChart()
                  └─ JFreeChart生成
```

### データフロー図

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

Node/Computer状態 ────▶ computeSnapshot() ─────────────▶ LoadStatisticsSnapshot
                              │
                              ├─ definedExecutors計算
                              ├─ onlineExecutors計算
                              ├─ busyExecutors計算
                              ├─ idleExecutors計算
                              ├─ availableExecutors計算
                              └─ queueLength計算

LoadStatisticsSnapshot ─▶ updateCounts() ──────────────▶ MultiStageTimeSeries
                              │
                              └─ 各TimeScaleで減衰更新

MultiStageTimeSeries ───▶ createTrendChart() ──────────▶ JFreeChart (PNG)
                              │
                              └─ TimeScale選択
                                     ├─ sec10
                                     ├─ min
                                     ├─ hour
                                     └─ ...
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LoadStatistics.java | `core/src/main/java/hudson/model/LoadStatistics.java` | ソース | ロード統計基盤 |
| MultiStageTimeSeries.java | `core/src/main/java/hudson/model/MultiStageTimeSeries.java` | ソース | 時系列データ |
| OverallLoadStatistics.java | `core/src/main/java/hudson/model/OverallLoadStatistics.java` | ソース | 全体統計 |
| UnlabeledLoadStatistics.java | `core/src/main/java/jenkins/model/UnlabeledLoadStatistics.java` | ソース | ラベルなし統計 |
| NodeProvisioner.java | `core/src/main/java/hudson/slaves/NodeProvisioner.java` | ソース | エージェントプロビジョニング |
| Label.java | `core/src/main/java/hudson/model/Label.java` | ソース | ラベル（統計保持） |
