# 帳票設計書 9-systat - リアルタイムシステム統計ダッシュボード

## 概要

本ドキュメントは、FreeBSDシステムにおけるリアルタイムシステム統計ダッシュボード(systat)の帳票設計書である。systatコマンドはcursesベースの全画面端末アプリケーションとして、システムの各種統計情報（TCP/IPネットワーク、ディスクI/O、仮想メモリ、プロセス、割り込み等）をリアルタイムに画面表示する。複数の表示モードをインタラクティブに切り替えることができる。

### 本帳票の処理概要

**業務上の目的・背景**：システム管理者がシステムの各種パフォーマンス指標をリアルタイムにダッシュボード形式で監視し、問題発生時に即座に状況を把握するためのツールである。

**帳票の利用シーン**：システム全体のリアルタイム監視、ネットワークトラフィックの監視、ディスクI/Oの監視、メモリ使用状況の監視、プロセスアクティビティの監視。

**主要な出力内容**：
1. TCP/IP統計ダッシュボード（tcp）
2. ディスクI/O統計（iostat）
3. 仮想メモリ統計（vmstat）
4. ネットワークインターフェース統計（ifstat）
5. ICM/ICMP6統計（icmp/icmp6）
6. IP統計（ip/ip6）
7. スワップスペース（swap）
8. 割り込み統計（zapm）
9. プロセスリスト

**帳票の出力タイミング**：コマンド実行で即座にcurses全画面表示開始。デフォルト5秒間隔で更新。

**帳票の利用者**：システム管理者、ネットワーク管理者、パフォーマンスエンジニア。

## 帳票種別

ダッシュボード（curses全画面リアルタイム統計表示）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | ターミナル/コンソール | N/A | `systat [-display] [refresh-interval]` コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | curses全画面表示 |
| 用紙サイズ | N/A（端末全画面） |
| 向き | N/A |
| ファイル名 | N/A |
| 出力方法 | curses画面更新（wnd WINDOWオブジェクト） |
| 文字コード | ロケール依存（setlocale(LC_ALL, "")） |

## 帳票レイアウト

### レイアウト概要

画面は以下の構成で構成される：

```
┌──────────────────────────────────────┐
│ ヘッダー行（ロード平均、表示モード名）  │
├──────────────────────────────────────┤
│                                      │
│ メイン表示エリア（表示モードに依存）    │
│ （wnd WINDOWオブジェクト）             │
│                                      │
├──────────────────────────────────────┤
│ コマンドライン（CMDLINE）              │
└──────────────────────────────────────┘
```

### ヘッダー部（1行ロード平均表示）

| No | 項目名 | 説明 | データ取得元 |
|----|-------|------|-------------|
| 1 | ロード平均 | 1/5/15分ロード平均 | getloadavg(avenrun, 3) |

### メイン表示エリア

表示モードに応じた統計情報が表示される。各モードは独自のlabels()/display()関数を持つ。

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 表示モード | コマンドライン引数または実行中の切り替えで指定 | No（デフォルト: vmstat相当） |
| 更新間隔 | 秒単位（小数点指定可）、デフォルト5秒 | No |

### ソート順

表示モードに依存

### 改ページ条件

curses全画面表示のため改ページなし（SIGWINCHでリサイズ対応）

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| kern.cp_time (sysctl) | CPU時間統計 | vmstat/iostatモード |
| vm.stats.* (sysctl) | VMカウンタ | vmstatモード |
| net.inet.* (sysctl) | ネットワーク統計 | tcp/ip/icmpモード |
| devstat | ディスクI/O | iostatモード |
| kern.proc.* (sysctl) | プロセスリスト | プロセス表示モード |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| hertz | clkinfo.hz | 整数 | 表示レート計算の基準 |
| 更新間隔 | delay(マイクロ秒) / 1000000.0 | 浮動小数点 | デフォルト5000000us |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[コマンド実行] --> B[setlocale LC_ALL]
    B --> C[コマンド引数解析 parse_cmd_args]
    C --> D{-displayオプション?}
    D -->|Yes| E[指定モードに切り替え]
    D -->|No| F[デフォルトモード]
    E --> G[kvm_openfiles: kvmハンドル取得]
    F --> G
    G --> H[initscr: curses初期化]
    H --> I[start_color: カラー初期化]
    I --> J[signal SIGWINCH resize]
    J --> K[メインイベントループ]
    K --> L[labels: ラベル描画]
    L --> M[display: 統計データ描画]
    M --> N[status: ステータス行更新]
    N --> O{コマンド入力?}
    O -->|Yes| P[コマンド解析・実行]
    O -->|No| Q[usleep delay]
    P --> R{終了?}
    Q --> R
    R -->|No| K
    R -->|Yes| S[endwin: curses終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| kvm_openfiles失敗 | カーネルメモリアクセス失敗 | errx(1, "kvm_openfiles: ...") | /dev/kmemの権限確認 |
| 表示モード不明 | 無効な表示モード指定 | 表示なし（無視） | 有効なモード名を指定 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 表示モードに依存 |
| 目標出力時間 | リアルタイム（デフォルト5秒間隔更新） |
| 同時出力数上限 | N/A |

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

- kvm経由のカーネルメモリアクセスにはkmemグループ権限が必要
- use_kvm=1（デフォルト）でカーネルシンボル解決を使用

## 備考

- 複数の表示モードをSLIST_HEAD(&commands)リストで管理（72-76行目）
- parse_cmd_args関数（78-123行目）でハイフン付き引数を表示モード名として解析
- SIGWINCH時のresize関数（125-137行目）でendwin→refresh→clear→labels→display→statusを実行
- 更新間隔はマイクロ秒単位で管理（58行目: unsigned int delay = 5000000）
- hertz値はkern.clockrate sysctlから取得

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | systat.h | `usr.bin/systat/systat.h` | 表示モードの構造体定義（cmdtab等）。各モードのinit/open/close/labels/display関数ポインタ |
| 1-2 | extern.h | `usr.bin/systat/extern.h` | グローバル変数とユーティリティ関数のプロトタイプ |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.c | `usr.bin/systat/main.c` | 140-150行目: main関数冒頭。ロケール設定、コマンドリスト初期化 |

**主要処理フロー**:
1. **148行目**: setlocale(LC_ALL, "")
2. **150行目**: SLIST_INIT(&commands)
3. parse_cmd_args()でコマンドライン引数解析
4. kvm_openfiles()でkvmハンドル取得
5. initscr()→start_color()でcurses初期化
6. メインループで定期的なlabels()→display()→status()

#### Step 3: 表示モードを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | vmstat.c | `usr.bin/systat/vmstat.c` | vmstat表示モードの実装例。labelvmstat/showvmstat等の関数群 |
| 3-2 | iostat.c | `usr.bin/systat/iostat.c` | iostat表示モードの実装 |
| 3-3 | tcp.c | `usr.bin/systat/tcp.c` | TCP統計表示モードの実装 |

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

```
main() [140行目]
    |
    +-- parse_cmd_args() [78行目] ... コマンド引数解析
    +-- kvm_openfiles() ... kvmハンドル取得
    +-- initscr() / start_color() ... curses初期化
    +-- signal(SIGWINCH, resize)
    +-- メインループ
           |
           +-- labels() ... 現モードのラベル描画
           +-- display() ... 現モードのデータ表示
           +-- status() ... ステータス行更新（ロード平均等）
           +-- コマンド入力処理
           |      +-- モード切替（tcp/vmstat/iostat等）
           |      +-- 更新間隔変更
           +-- usleep(delay)
    +-- resize() [125行目] ... SIGWINCH時のリサイズ処理
```

### データフロー図

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

sysctl各種 ──────────▶ 各モードのfetch関数       ──▶ curses画面
  kern.cp_time                  |                       (wnd WINDOW)
  vm.stats.*                    +-- labels(): ラベル
  net.inet.*                    +-- display(): データ
  devstat                       +-- status(): ステータス
カーネルメモリ (kvm) ──▶ kvm_read()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.c | `usr.bin/systat/main.c` | ソース | エントリーポイント、メインループ |
| systat.h | `usr.bin/systat/systat.h` | ヘッダ | 表示モード構造体定義 |
| extern.h | `usr.bin/systat/extern.h` | ヘッダ | グローバル変数・関数プロトタイプ |
| vmstat.c | `usr.bin/systat/vmstat.c` | ソース | vmstat表示モード |
| iostat.c | `usr.bin/systat/iostat.c` | ソース | iostat表示モード |
| tcp.c | `usr.bin/systat/tcp.c` | ソース | TCP統計表示モード |
| ifstat.c | `usr.bin/systat/ifstat.c` | ソース | インターフェース統計モード |
| icmp.c | `usr.bin/systat/icmp.c` | ソース | ICMP統計モード |
| ip.c | `usr.bin/systat/ip.c` | ソース | IP統計モード |
| swap.c | `usr.bin/systat/swap.c` | ソース | スワップ表示モード |
| zapm.c | `usr.bin/systat/zapm.c` | ソース | 割り込み/電力管理モード |
| fetch.c | `usr.bin/systat/fetch.c` | ソース | データ取得ユーティリティ |
| mode.c | `usr.bin/systat/mode.c` | ソース | 表示モード切替 |
