# 機能設計書 175-メトリクス情報取得

## 概要

本ドキュメントは、libuv の `uv_metrics_info()` 関数によるイベントループのメトリクス（ループ回数・イベント数等）取得機能について、その設計仕様を記載する。

### 本機能の処理概要

`uv_metrics_info()` は、イベントループの実行統計情報（メトリクス）を `uv_metrics_t` 構造体にコピーして返す関数である。取得できるメトリクスには、ループ実行回数、処理されたイベント数、待機中のイベント数が含まれる。

**業務上の目的・背景**：非同期イベント駆動アプリケーションのパフォーマンス監視・チューニングにおいて、イベントループの動作状況を把握することは重要である。本機能はイベントループがどれだけの回数実行され、どれだけのイベントを処理したかという統計情報を提供し、パフォーマンスのボトルネック分析やモニタリングに活用できる。

**機能の利用シーン**：アプリケーションのパフォーマンスモニタリング、イベントループのヘルスチェック、負荷テスト時の統計収集、パフォーマンスチューニングのための基礎データ収集、プロダクション環境でのメトリクスダッシュボード表示などに利用される。

**主要な処理内容**：
1. ループ内部のメトリクス構造体からデータをメモリコピー
2. 呼び出し元の uv_metrics_t 構造体に格納

**関連システム・外部連携**：イベントループの内部フィールド（`uv__loop_metrics_t`）から統計情報を取得する。メトリクスの更新はイベントループのコア処理（I/Oポーリング等）で行われる。

**権限による制御**：特別な権限は不要である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 30 | メトリクス | 主機能 | uv_metrics_info()によるイベントループメトリクス取得のAPI定義 |

## 機能種別

データ取得処理（イベントループ統計情報の読み取り）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | メトリクスを取得するイベントループ | - |
| metrics | uv_metrics_t* | Yes | メトリクスを格納する構造体へのポインタ | - |

### 入力データソース

イベントループの内部フィールド（`uv__loop_internal_fields_t` 内の `uv__loop_metrics_t`）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| metrics->loop_count | uint64_t | イベントループの実行回数 |
| metrics->events | uint64_t | 処理されたイベントの総数 |
| metrics->events_waiting | uint64_t | I/Oポーリング開始時に待機中だったイベントの総数 |
| 戻り値 | int | 常に 0 |

### 出力先

呼び出し元に戻り値として返却。メトリクスデータは引数として渡された構造体に格納。

## 処理フロー

### 処理シーケンス

```
1. メトリクスデータのコピー
   └─ uv__get_loop_metrics(loop)->metrics から引数の metrics へ memcpy
2. 0 を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[uv__get_loop_metrics でメトリクスポインタ取得]
    B --> C[memcpy でメトリクスデータをコピー]
    C --> D[0 を返す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-175-01 | メトリクスのスナップショット | 取得される値はコピー時点のスナップショットであり、その後の更新は反映されない | 常時 |
| BR-175-02 | ループカウントのインクリメント | loop_count はイベントループの各イテレーションでインクリメントされる | イベントループ実行中 |
| BR-175-03 | イベントカウントの累積 | events と events_waiting は累積値であり、リセットされない | 常時 |

### 計算ロジック

`memcpy(metrics, &uv__get_loop_metrics(loop)->metrics, sizeof(*metrics))` による単純なメモリコピー。

メトリクスの更新はマクロで行われる:
- `uv__metrics_inc_loop_count(loop)`: loop_count をインクリメント（src/uv-common.h L372-375）
- `uv__metrics_inc_events(loop, e)`: events を加算（src/uv-common.h L377-380）
- `uv__metrics_inc_events_waiting(loop, e)`: events_waiting を加算（src/uv-common.h L382-385）

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

### 操作別データベース影響一覧

該当なし。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| (なし) | - | 本関数は常に 0 を返す | - |

### リトライ仕様

不要。常に成功する。

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

該当なし。メトリクスの読み取りはアトミックではないが、memcpy による一括コピーである。

## パフォーマンス要件

memcpy による単純なメモリコピーのため、極めて軽量。ナノ秒オーダーで完了する。

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

特別なセキュリティ要件はない。

## 備考

- `uv_metrics_t` 構造体には `reserved[13]` フィールドがあり、将来の拡張用に予約されている。
- メトリクス収集にはイベントループのオプション `UV_METRICS_IDLE_TIME` を有効にする必要がある場合がある（アイドル時間計測の場合）。
- メトリクスの更新はイベントループの各フェーズで行われ、排他制御はマクロ内で直接行われる（インクリメント操作のみ）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_metrics_t 構造体の定義（1390-1396行目）。loop_count, events, events_waiting の3フィールド |
| 1-2 | uv-common.h | `src/uv-common.h` | uv__loop_metrics_t 内部構造体（399-404行目）。uv_metrics_t を含み、provider_entry_time, provider_idle_time, lock を持つ |

**読解のコツ**: `uv_metrics_t` は公開API用の構造体で、`uv__loop_metrics_t` は内部用の拡張構造体。`uv__get_loop_metrics()` マクロでループ内部フィールドからメトリクス構造体へのポインタを取得する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | API宣言（1398行目）: `int uv_metrics_info(uv_loop_t* loop, uv_metrics_t* metrics)` |

#### Step 3: 実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | uv-common.c | `src/uv-common.c` | `uv_metrics_info()` 実装（1033-1039行目） |

**主要処理フロー**:
- **1034-1036行目**: `memcpy` で `uv__get_loop_metrics(loop)->metrics` から `metrics` に構造体コピー
- **1038行目**: 常に 0 を返す

#### Step 4: メトリクス更新マクロを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | uv-common.h | `src/uv-common.h` | メトリクス更新マクロの定義（369-385行目） |

**主要処理フロー**:
- **369-370行目**: `uv__get_loop_metrics()` マクロ - ループ内部フィールドからメトリクスポインタを取得
- **372-375行目**: `uv__metrics_inc_loop_count()` - loop_count インクリメント
- **377-380行目**: `uv__metrics_inc_events()` - events 加算
- **382-385行目**: `uv__metrics_inc_events_waiting()` - events_waiting 加算

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

```
uv_metrics_info(loop, metrics)
    |
    +-- uv__get_loop_metrics(loop)
    |   +-- uv__get_internal_fields(loop)->loop_metrics
    |
    +-- memcpy(metrics, &...->metrics, sizeof(*metrics))
```

### データフロー図

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

loop ──────▶ uv_metrics_info() ──────────▶ uv_metrics_t* metrics
                |                                (loop_count, events,
                +-- uv__get_loop_metrics()        events_waiting)
                +-- memcpy
                                              ──▶ 戻り値: 0
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言、uv_metrics_t の型定義 |
| uv-common.c | `src/uv-common.c` | ソース | uv_metrics_info() 実装 |
| uv-common.h | `src/uv-common.h` | ヘッダー | uv__loop_metrics_t、メトリクス更新マクロの定義 |
