# 帳票設計書 10-システム負荷平均

## 概要

本ドキュメントは、libuvライブラリにおける `uv_loadavg()` API関数の帳票設計書である。直近1分・5分・15分のシステム負荷平均を3要素のdouble配列に出力する機能について定義する。

### 本帳票の処理概要

本帳票は、UNIXシステムの負荷平均（load average）を取得する機能を提供する。負荷平均はCPU実行待ちプロセス数の時間平均であり、システムの負荷状況を示す基本的な指標である。

**業務上の目的・背景**：システムの負荷状況をリアルタイムに把握し、過負荷の検出やキャパシティプランニングに利用する。負荷平均がCPUコア数を超える場合はシステムが飽和状態にあることを示す。サーバーアプリケーションにおける自動スケーリング判断やヘルスチェックの指標として活用される。

**帳票の利用シーン**：サーバーヘルスチェック、自動スケーリングの判断基準、システム負荷モニタリング、キャパシティプランニング。

**主要な出力内容**：
1. avg[0]（double）：直近1分間の負荷平均
2. avg[1]（double）：直近5分間の負荷平均
3. avg[2]（double）：直近15分間の負荷平均

**帳票の出力タイミング**：`uv_loadavg(avg)` 呼び出し時に即座に配列に値が格納される。

**帳票の利用者**：運用監視チーム、SRE、アプリケーション開発者。

## 帳票種別

システム負荷レポート（配列出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | N/A（C API呼び出し） | N/A | `uv_loadavg(avg)` 関数呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | double配列（3要素） |
| 出力方法 | 配列要素への直接書き込み |

## 帳票レイアウト

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 備考 |
|----|-------|------|-------------|---------|------|
| 1 | avg[0] | 1分間負荷平均 | プラットフォーム依存 | double | |
| 2 | avg[1] | 5分間負荷平均 | プラットフォーム依存 | double | |
| 3 | avg[2] | 15分間負荷平均 | プラットフォーム依存 | double | |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| avg配列 | 3要素のdouble配列 | Yes |

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

### 参照テーブル一覧（プラットフォーム別）

| プラットフォーム | データソース | 取得方法 |
|----------------|------------|---------|
| macOS/BSD | sysctl(CTL_VM, VM_LOADAVG) | struct loadavg構造体 |
| Linux | /proc/loadavg | ファイル読み込み + sscanf |
| Linux（フォールバック） | sysinfo() | sysinfo.loads[]配列 |
| AIX | perfstat_cpu_total() | perfstat API |
| QNX | N/A | 常に0.0を返却 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| macOS: avg[n] | (double)info.ldavg[n] / info.fscale | 浮動小数点除算 | fscaleは固定小数点のスケール値 |
| Linux: avg[n] | sscanf()による直接パース | N/A | /proc/loadavgのテキスト値 |
| Linux（フォールバック） | (double)info.loads[n] / 65536.0 | 浮動小数点除算 | sysinfo()の固定小数点値 |

## 処理フロー

### 出力フロー（Linux版）

```mermaid
flowchart TD
    A[uv_loadavg呼び出し] --> B[/proc/loadavg読み込み]
    B --> C{成功?}
    C -->|Yes| D[sscanfで3つのdouble値をパース]
    D --> E{3値パース成功?}
    E -->|Yes| F[return]
    E -->|No| G[sysinfo実行]
    C -->|No| G
    G --> H{成功?}
    H -->|No| I[return]
    H -->|Yes| J[loads配列を65536.0で除算して格納]
    J --> I
```

### 出力フロー（macOS版）

```mermaid
flowchart TD
    A[uv_loadavg呼び出し] --> B[sysctl CTL_VM VM_LOADAVG]
    B --> C{成功?}
    C -->|No| D[return 配列未変更]
    C -->|Yes| E[ldavg[0-2]をfscaleで除算して格納]
    E --> F[return]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| N/A | 本関数はvoid型であり、エラーを返さない | N/A | 取得に失敗した場合は配列の値が未変更のまま |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 3件（固定） |
| 目標出力時間 | マイクロ秒オーダー |
| 同時出力数上限 | N/A |

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

システム負荷情報はセキュリティ上のリスクが低い。ただし、負荷状況からシステムの処理パターンを推測される可能性はある。

## 備考

- 戻り値がvoid型であるため、エラー通知手段がない。呼び出し元は事前に配列を0.0で初期化しておくことが推奨される
- Windowsでは常に0.0が返される
- QNXでも常に0.0が返される
- Linuxでは/proc/loadavgの読み込みを優先し、失敗した場合にsysinfo()にフォールバックする
- macOS/BSDではsysctlを使用し、固定小数点値をfscaleで除算して浮動小数点に変換する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_loadavg()のAPI宣言（1736行目）：`void uv_loadavg(double avg[3])` |

**読解のコツ**: 引数はdouble[3]の配列であり、構造体ではない。戻り値はvoid型でエラーを返さない。

#### Step 2: プラットフォーム別実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | darwin.c | `src/unix/darwin.c` | macOS版（141-151行目）：sysctl(CTL_VM, VM_LOADAVG)でstruct loadavgを取得し、fscaleで除算 |
| 2-2 | linux.c | `src/unix/linux.c` | Linux版（2451行目〜）：/proc/loadavgの読み込みとsscanfパース、sysinfo()フォールバック |

**主要処理フロー（macOS）**:
1. **142-144行目**: struct loadavg infoを宣言、sysctl whichを設定
2. **146行目**: sysctl()でVM_LOADAVGを取得
3. **148-150行目**: info.ldavg[0-2]をinfo.fscaleで除算して配列に格納

**主要処理フロー（Linux）**:
1. **2455-2457行目**: /proc/loadavgファイルを読み込み、sscanf()で3つのdouble値をパース
2. **2459-2460行目**: ファイル読み込み失敗時にsysinfo()にフォールバック
3. sysinfo()の場合: loads[n]を65536.0で除算

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

```
uv_loadavg(avg[3])                             [プラットフォーム別]
    |
    +-- [macOS] src/unix/darwin.c:141
    |       +-- sysctl(CTL_VM, VM_LOADAVG)     [BSD API]
    |
    +-- [Linux] src/unix/linux.c:2451
    |       +-- uv__slurp("/proc/loadavg")     [ファイル読み込み]
    |       +-- sscanf()                        [テキストパース]
    |       +-- sysinfo()                       [フォールバック]
    |
    +-- [FreeBSD] src/unix/freebsd.c
    |       +-- getloadavg()                    [BSD API]
    |
    +-- [QNX] src/unix/qnx.c:59
            +-- (常に0.0を設定)
```

### データフロー図

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

[macOS]                      uv_loadavg()                    double avg[3]
sysctl(VM_LOADAVG)           darwin.c:141                    avg[0] = 1分平均
  struct loadavg              ldavg[n] / fscale              avg[1] = 5分平均
    .ldavg[0-2] -------->    浮動小数点除算  -------->       avg[2] = 15分平均
    .fscale

[Linux]
/proc/loadavg -------->      sscanf("%lf %lf %lf") -------> avg[0-2]
  "0.12 0.34 0.56 ..."
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | uv_loadavg() API宣言 |
| darwin.c | `src/unix/darwin.c` | ソース | macOS版uv_loadavg()実装 |
| linux.c | `src/unix/linux.c` | ソース | Linux版uv_loadavg()実装 |
| freebsd.c | `src/unix/freebsd.c` | ソース | FreeBSD版実装 |
| openbsd.c | `src/unix/openbsd.c` | ソース | OpenBSD版実装 |
| netbsd.c | `src/unix/netbsd.c` | ソース | NetBSD版実装 |
| qnx.c | `src/unix/qnx.c` | ソース | QNX版実装（常に0） |
