# 帳票設計書 22-アップタイム

## 概要

システムの稼働時間（アップタイム）を秒単位のdouble値として取得する帳票（API出力）の設計書である。`uv_uptime()`関数により、システム起動からの経過時間をプラットフォーム非依存なインターフェースで提供する。

### 本帳票の処理概要

本帳票は、OSが起動してからの経過時間を秒単位で出力する機能を提供する。プラットフォームごとに異なるシステムAPIを内部で呼び出し、統一的なインターフェースを通じて稼働時間を返却する。

**業務上の目的・背景**：システム監視、稼働統計、SLA管理などの場面でシステムの連続稼働時間を把握するために必要である。サーバーの再起動検出、プロセスの健全性チェック、パフォーマンス監視ツールのベースライン情報として活用される。クロスプラットフォームなアプリケーションにおいて、OS固有のAPI差異を吸収する重要な抽象化レイヤーである。

**帳票の利用シーン**：サーバー監視ダッシュボードでの稼働時間表示、ヘルスチェックAPIのレスポンス生成、システム情報収集ツールでの稼働時間レポート、ログ分析時のシステム再起動タイミング特定などに利用される。

**主要な出力内容**：
1. システム稼働時間（秒単位、double型）

**帳票の出力タイミング**：任意のタイミングで`uv_uptime()`関数を呼び出すことにより出力される。同期関数であり、即座に結果が返却される。

**帳票の利用者**：システム管理者、運用監視ツール開発者、libuvを利用するアプリケーション開発者、Node.jsランタイム。

## 帳票種別

情報取得（システム稼働時間出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | CLIまたはAPI呼び出し | N/A（C言語API） | `uv_uptime()` 関数呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | メモリ上の数値（double*） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（ポインタ経由で返却） |
| 出力方法 | 引数ポインタへの書き込み |
| 文字コード | N/A（数値） |

### 出力データ仕様

| 項目 | 型 | 単位 | 説明 |
|-----|-----|------|------|
| uptime | double | 秒 | システム起動からの経過時間 |
| 戻り値 | int | N/A | 0=成功、負値=エラーコード |

## 帳票レイアウト

### レイアウト概要

本帳票は単一のdouble値として出力される。

```
┌─────────────────────────────────────┐
│  稼働時間（秒）                        │
│  double uptime                      │
└─────────────────────────────────────┘
```

### 出力項目

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | システム稼働時間 | OS起動からの経過秒数 | プラットフォーム固有API | double（秒単位） |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| なし | パラメータとしてdouble*ポインタのみ必要 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| N/A | N/A | N/A |

### 改ページ条件

N/A（単一値出力のため改ページなし）

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

### 参照テーブル一覧

本帳票はデータベースを参照しない。OSカーネルからシステム情報を取得する。

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| N/A | N/A | N/A |

### プラットフォーム別データ取得元

| プラットフォーム | ファイル | 取得方法 | 備考 |
|---------------|---------|---------|------|
| Linux | `src/unix/linux.c` | /proc/uptime の読み取り（優先）、または clock_gettime(CLOCK_BOOTTIME) | コンテナ環境では /proc/uptime が正確な値を返す |
| macOS/Darwin | `src/unix/darwin.c` | sysctl(CTL_KERN, KERN_BOOTTIME) + time(NULL) | ブート時刻と現在時刻の差分で計算 |
| Windows | `src/win/util.c` | GetTickCount64() / 1000.0 | ミリ秒からの秒変換 |
| FreeBSD | `src/unix/freebsd.c` | プラットフォーム固有実装 | - |
| その他Unix | 各プラットフォームファイル | プラットフォーム固有実装 | - |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| uptime (macOS) | time(NULL) - boot_time.tv_sec | なし（整数差分） | sysctl で取得した KERN_BOOTTIME からの経過時間 |
| uptime (Windows) | GetTickCount64() / 1000.0 | なし（浮動小数点除算） | ミリ秒を秒に変換 |
| uptime (Linux) | /proc/uptime の先頭フィールド、または clock_gettime の tv_sec | なし | /proc/uptime を優先し、失敗時は clock_gettime にフォールバック |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[uv_uptime 呼び出し] --> B{プラットフォーム判定}
    B -->|Linux| C[/proc/uptime を読み取り]
    C --> D{読み取り成功?}
    D -->|Yes| E[sscanf でパース]
    D -->|No| F[clock_gettime CLOCK_BOOTTIME]
    E --> G{パース成功?}
    G -->|Yes| H[uptime に値を設定]
    G -->|No| F
    F --> I{clock_gettime 成功?}
    I -->|Yes| H
    I -->|No| J[エラー返却]
    B -->|macOS| K[sysctl KERN_BOOTTIME]
    K --> L[time - boottime を計算]
    L --> H
    B -->|Windows| M[GetTickCount64 / 1000.0]
    M --> H
    H --> N[0 を返却]
    J --> O[UV__ERR errno を返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| システムコール失敗 | sysctl / clock_gettime 等のOS API呼び出しが失敗した場合 | UV__ERR(errno) | エラーコードに応じた対処。通常は権限不足やカーネル設定の問題 |
| NULLポインタ | uptime 引数が NULL の場合（一部プラットフォーム） | 未定義動作 | 呼び出し側でNULLチェックを行う |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1件（単一値） |
| 目標出力時間 | マイクロ秒オーダー（システムコール1回分） |
| 同時出力数上限 | 制限なし（読み取りのみ、スレッドセーフ） |

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

- システム稼働時間は一般にセンシティブな情報ではないが、攻撃者がパッチ適用頻度を推測する材料になりうる
- 特段のアクセス制御は実装されていない

## 備考

- Linux環境ではコンテナ環境（OpenVZ等）での精度を考慮し、/proc/uptimeを優先的に参照する設計となっている
- Windowsでは GetTickCount64 の精度制限（約10-16ms）があるが、秒単位のuptime取得には十分
- macOSでは起動時刻と現在時刻の差分で計算するため、NTP時刻同期の影響を受ける可能性がある

---

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

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

### 推奨読解順序

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

uv_uptime() は構造体ではなく、double ポインタに値を書き込む単純なインターフェースである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_uptime() の宣言（行1287）: `int uv_uptime(double* uptime)` |

**読解のコツ**: 戻り値は int 型のエラーコード（0=成功）。実際のuptime値は引数ポインタに書き込まれる。

#### Step 2: エントリーポイントを理解する（プラットフォーム別）

uv_uptime() はプラットフォームごとに異なるファイルで実装されている。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | linux.c | `src/unix/linux.c` | Linux実装（行1675-1691）: /proc/uptimeを優先し、失敗時はCLOCK_BOOTTIMEにフォールバック |
| 2-2 | darwin.c | `src/unix/darwin.c` | macOS実装（行175-188）: sysctl KERN_BOOTTIME で起動時刻を取得し、現在時刻との差分を計算 |
| 2-3 | util.c | `src/win/util.c` | Windows実装（行502-505）: GetTickCount64() のミリ秒値を1000.0で除算 |

**主要処理フロー（Linux）**:
1. **行1683**: `/proc/uptime` の内容を `uv__slurp()` で読み取り
2. **行1684**: `sscanf()` で先頭のdouble値をパース
3. **行1687-1688**: 上記が失敗した場合、`clock_gettime(CLOCK_BOOTTIME)` にフォールバック
4. **行1690**: `now.tv_sec` をuptimeとして設定

**主要処理フロー（macOS/Darwin）**:
1. **行179**: `sysctl(CTL_KERN, KERN_BOOTTIME)` でブート時刻（timeval構造体）を取得
2. **行184**: `time(NULL)` で現在のUNIXタイムスタンプを取得
3. **行185**: `now - info.tv_sec` でブートからの経過秒数を算出

**主要処理フロー（Windows）**:
1. **行503**: `GetTickCount64()` でシステム起動からのミリ秒数を取得
2. **行503**: `/ 1000.0` で秒単位に変換して `*uptime` に設定

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

```
uv_uptime(double* uptime)
    |
    +-- [Linux] src/unix/linux.c:1675
    |       |
    |       +-- uv__slurp("/proc/uptime", ...)
    |       |       +-- ファイル読み取り
    |       +-- sscanf(buf, "%lf", uptime)
    |       +-- [フォールバック] clock_gettime(CLOCK_BOOTTIME, &now)
    |
    +-- [macOS] src/unix/darwin.c:175
    |       |
    |       +-- sysctl({CTL_KERN, KERN_BOOTTIME}, ...)
    |       +-- time(NULL)
    |       +-- now - info.tv_sec
    |
    +-- [Windows] src/win/util.c:502
            |
            +-- GetTickCount64() / 1000.0
```

### データフロー図

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

double* uptime ───> プラットフォーム固有      ───> *uptime = 経過秒数
                    システムコール                  戻り値 = 0 (成功)
                    (sysctl / /proc /                    または負値 (エラー)
                     GetTickCount64)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダ | uv_uptime() のAPI宣言 |
| linux.c | `src/unix/linux.c` | ソース | Linux向け uv_uptime() 実装 |
| darwin.c | `src/unix/darwin.c` | ソース | macOS向け uv_uptime() 実装 |
| util.c | `src/win/util.c` | ソース | Windows向け uv_uptime() 実装 |
| freebsd.c | `src/unix/freebsd.c` | ソース | FreeBSD向け uv_uptime() 実装 |
| openbsd.c | `src/unix/openbsd.c` | ソース | OpenBSD向け uv_uptime() 実装 |
| netbsd.c | `src/unix/netbsd.c` | ソース | NetBSD向け uv_uptime() 実装 |
| sunos.c | `src/unix/sunos.c` | ソース | Solaris向け uv_uptime() 実装 |
| aix.c | `src/unix/aix.c` | ソース | AIX向け uv_uptime() 実装 |
| test-platform-output.c | `test/test-platform-output.c` | テスト | uv_uptime() のテスト |
