# 帳票設計書 2-sa - システムアカウンティング統計レポート

## 概要

本ドキュメントは、FreeBSDシステムにおけるシステムアカウンティング統計レポート(sa)の帳票設計書である。saコマンドはプロセスアカウンティングファイル(/var/account/acct)を読み取り、プロセスごとのCPU時間、メモリ使用量、I/O操作を集計し、統計レポートとして標準出力に出力する。

### 本帳票の処理概要

**業務上の目的・背景**：システム管理者がプロセスの実行履歴とリソース消費状況を分析し、システムリソースの最適化やコスト配分の根拠データを得るために必要なレポートである。どのコマンドがどの程度のCPU時間やメモリを消費しているかを把握できる。

**帳票の利用シーン**：定期的なシステムリソース利用分析、プロセスのCPU/メモリ消費傾向の把握、ユーザーごとのリソース利用量集計、アカウンティングデータのサマリーデータベース更新。

**主要な出力内容**：
1. コマンド名ごとのCPU時間（ユーザー+システム）、呼び出し回数、I/O操作数、メモリ使用量
2. ユーザーごとのプロセス実行回数と時間（-mオプション）
3. 個別プロセスのUID、CPU時間、メモリ、I/O（-uオプション）

**帳票の出力タイミング**：システム管理者がコマンドラインからsaコマンドを実行した時点で即時出力。-sオプションでサマリーデータベースへの集約も可能。

**帳票の利用者**：システム管理者、キャパシティプランニング担当者。

## 帳票種別

集計表（テキスト形式のプロセスアカウンティング統計レポート）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | ターミナル/コンソール | N/A | `sa [-abcdDfijkKlmnqrstu] [-P file] [-U file] [-v cutoff] [file ...]` コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（標準出力） |
| 用紙サイズ | N/A（コンソール出力） |
| 向き | N/A |
| ファイル名 | N/A（標準出力）。-sオプションでサマリーDBファイル（/var/account/savacct, /var/account/usracct）を更新 |
| 出力方法 | 標準出力への直接出力 |
| 文字コード | ASCII |

## 帳票レイアウト

### レイアウト概要

コマンド別集計モード（デフォルト）とユーザー別集計モード（-m）、個別出力モード（-u）の3種類のレイアウトがある。

```
┌─────────────────────────────────────┐
│  コマンド別またはユーザー別の集計行   │
│  （ソート順はオプションにより変更可）  │
└─────────────────────────────────────┘
```

### 明細部（-uオプション: 個別プロセスモード）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | UID | プロセス実行ユーザーID | acctv3.ac_uid | 整数 | 6桁 |
| 2 | CPU時間 | ユーザー+システム時間（秒） | (ac_utime + ac_stime) / 1000000 | 小数点3桁 | 12桁 |
| 3 | メモリ | CPU時間メモリ積分値 | ac_mem | 整数(k) | 12桁 |
| 4 | I/O | I/O操作数 | ac_io | 整数 | 12桁 |
| 5 | コマンド名 | 実行コマンド名 | ac_comm | 文字列 | 可変 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| カットオフ値（-v） | 指定回数以下のコマンドを"***other"に集約 | No |
| ファイル指定 | アカウンティングファイルのパス | No（デフォルト: /var/account/acct） |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | ユーザー+システム時間（デフォルト） | 降順（-rで逆転） |
| 2 | オプション指定(-b: 平均時間, -d: 平均I/O, -D: I/O合計, -k: 平均メモリ, -K: メモリ積分, -n: 呼び出し回数) | 降順 |

### 改ページ条件

改ページ機能なし

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| /var/account/acct | プロセスアカウンティングレコード | 順次読み取り |
| /var/account/savacct | プロセス別サマリーDB | -sオプション時に読み書き |
| /var/account/usracct | ユーザー別サマリーDB | -sオプション時に読み書き |

### テーブル別参照項目詳細

#### アカウンティングレコード（struct acctv3）

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| ac_comm | コマンド名 | 全レコード | 非ASCII/制御文字は'?'に置換 |
| ac_utime | ユーザーCPU時間 | 全レコード | マイクロ秒単位 |
| ac_stime | システムCPU時間 | 全レコード | マイクロ秒単位 |
| ac_etime | 経過時間 | 全レコード | マイクロ秒単位 |
| ac_uid | ユーザーID | 全レコード | -uモードで表示 |
| ac_mem | メモリ使用量 | 全レコード | CPU時間メモリ積分値 |
| ac_io | I/O操作数 | 全レコード | ディスクI/O操作カウント |
| ac_flagx | フラグ | 全レコード | AFORKフラグで'*'付与 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| CPU時間（秒） | (ci_utime + ci_stime) / 1000000 | 小数点3桁 | マイクロ秒→秒変換 |
| 平均CPU時間 | (utime + stime) / calls | 浮動小数点 | -bオプション時のソートキー |
| 平均I/O | io / calls | 浮動小数点 | -dオプション時のソートキー |
| 平均メモリ | mem / (utime + stime) | 浮動小数点 | -kオプション時のソートキー |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[コマンド実行] --> B[オプション解析]
    B --> C[サマリーDB初期化]
    C --> D[アカウンティングファイル読み取り acct_load]
    D --> E{-uオプション?}
    E -->|Yes| F[個別レコード出力]
    E -->|No| G[pacct_add/usracct_addでDB蓄積]
    G --> H{-sオプション?}
    H -->|Yes| I[ファイル切り詰め・DB更新]
    H -->|No| J[集計結果出力]
    I --> J
    J --> K{-mオプション?}
    K -->|Yes| L[usracct_print: ユーザー別出力]
    K -->|No| M[pacct_print: コマンド別出力]
    L --> N[終了]
    M --> N
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| ファイルオープン失敗 | アカウンティングファイルが存在しない | warn("open %s ...") | ファイルの存在確認、accton有効化確認 |
| DB初期化失敗 | サマリーDBの初期化に失敗 | errx(1, "... initialization failed") | DBファイルのパーミッション確認 |
| ファイル切り詰め失敗 | -sオプション時のtruncate失敗 | warn("couldn't truncate %s") | ファイルの書き込み権限確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | アカウンティングファイルサイズに依存 |
| 目標出力時間 | ファイルサイズに比例 |
| 同時出力数上限 | N/A |

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

- アカウンティングファイルへの読み取り権限（通常root）が必要
- -sオプション使用時はファイルの書き込み権限も必要
- シグナルマスクによるDB更新中の割り込み保護を実施（main.c 222-233行目）

## 備考

- -fと-vの組み合わせでインタラクティブな閾値比較を抑制
- AFORKフラグ付きコマンド名には'*'が付与される（main.c 346行目）
- 非ASCII/制御文字はコマンド名で'?'に置換される（main.c 339行目）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | extern.h | `usr.sbin/sa/extern.h` | cmdinfo構造体とDBT型の定義。ci_comm, ci_utime, ci_stime等のフィールド |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.c | `usr.sbin/sa/main.c` | 75-292行目: main関数。多数のフラグ解析、DB初期化、ファイル処理ループ |

**主要処理フロー**:
1. **84行目**: getoptで22種類のオプション解析
2. **191-197行目**: pacct_init/usracct_initでサマリーDB初期化
3. **205-273行目**: 各アカウンティングファイルの処理ループ
4. **275-281行目**: 集計結果の出力

#### Step 3: データ読み取り処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | main.c | `usr.sbin/sa/main.c` | 302-371行目: acct_load関数。acctv3レコードの読み取りとcmdinfo構造体への変換 |

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

```
main() [75行目]
    |
    +-- pacct_init() ... プロセスDB初期化
    +-- usracct_init() ... ユーザーDB初期化
    +-- acct_load() [302行目]
    |      |
    |      +-- readrec_forward() ... レコード読み取り
    |      +-- pacct_add() ... プロセスDB追加
    |      +-- usracct_add() ... ユーザーDB追加
    |
    +-- pacct_update() / usracct_update() ... -s時DB更新
    +-- pacct_print() / usracct_print() ... 集計結果出力
    +-- pacct_destroy() / usracct_destroy() ... DB解放
```

### データフロー図

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

/var/account/acct ───▶ acct_load(): レコード読み取り  ──▶ 標準出力
                         |                                 (テキスト)
/var/account/savacct ◀─▶ pacct_*(): プロセス別集計
/var/account/usracct ◀─▶ usracct_*(): ユーザー別集計
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.c | `usr.sbin/sa/main.c` | ソース | メインプログラム、オプション解析、ファイル読み取り |
| extern.h | `usr.sbin/sa/extern.h` | ヘッダ | 構造体定義、関数プロトタイプ |
| pathnames.h | `usr.sbin/sa/pathnames.h` | ヘッダ | デフォルトファイルパス定義 |
| pdb.c | `usr.sbin/sa/pdb.c` | ソース | プロセスアカウンティングDB操作 |
| usrdb.c | `usr.sbin/sa/usrdb.c` | ソース | ユーザーアカウンティングDB操作 |
