# バッチ設計書 13-310.accounting

## 概要

本ドキュメントは、FreeBSDのperiodicフレームワークにおけるdailyバッチ `310.accounting` の設計仕様を記述する。本バッチはプロセスアカウンティングログのローテーションと統計情報の収集を行う。

### 本バッチの処理概要

本バッチは、FreeBSDのプロセスアカウンティング機能によって記録されるログファイル (`/var/account/acct`) のローテーション（世代管理）と、`sa(8)` コマンドを用いた統計情報の収集を行う。

**業務上の目的・背景**：プロセスアカウンティングは、システム上で実行された全プロセスの実行履歴を記録する機能であり、セキュリティ監査やリソース使用量の分析に不可欠である。ログファイルは継続的に肥大化するため、日次でのローテーションと統計収集が必要となる。本バッチにより、ログの肥大化を防ぎつつ、過去の実行履歴を世代管理で保持する。

**バッチの実行タイミング**：日次（daily periodic）で実行される。デフォルトで有効（daily_accounting_enable=YES）。

**主要な処理内容**：
1. プロセスアカウンティングの有効性を確認（ファイル存在・カーネル設定・保存世代数設定）
2. 保存世代数を超過した古いアカウンティングログを削除
3. 既存のログファイルを世代番号を繰り上げてリネーム
4. `/etc/rc.d/accounting onerotate_log` でログをローテーション
5. `sa -s` コマンドで統計情報を収集
6. オプションでローテーション済みログをgzip圧縮

**前後の処理との関連**：dailyカテゴリのアカウンティング系バッチである。プロセスアカウンティングがカーネルレベルで有効化（`kern.acct_configured`）されている必要がある。

**影響範囲**：`/var/account/` ディレクトリ配下のアカウンティングログファイル（acct, acct.0, acct.1, ...）に影響する。

## バッチ種別

データクレンジング / ログローテーション / 集計処理

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 日次 |
| 実行時刻 | periodicフレームワークの日次実行時刻（デフォルト: 3:01） |
| 実行曜日 | 毎日 |
| 実行日 | 毎日 |
| トリガー | cron経由のperiodicフレームワーク |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| daily_accounting_enable | "YES"に設定されていること（デフォルト: YES） |
| /var/account/acct | アカウンティングログファイルが存在すること |
| kern.acct_configured | カーネルでプロセスアカウンティングが有効であること（sysctl値が非0） |
| daily_accounting_save | 保存世代数が設定されていること（デフォルト: 3） |

### 実行可否判定

1. `daily_accounting_enable` が "YES" でない場合、rc=0でスキップ
2. `/var/account/acct` が存在しない場合、エラーメッセージを出力しrc=2で終了
3. `kern.acct_configured` が0の場合、プロセスアカウンティング未有効としてrc=2で終了
4. `daily_accounting_save` が空の場合、設定不足としてrc=2で終了

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| daily_accounting_enable | 文字列 | Yes | YES | バッチの有効/無効フラグ |
| daily_accounting_save | 整数 | Yes | 3 | ログの保存世代数 |
| daily_accounting_compress | 文字列 | No | NO | ローテーション済みログのgzip圧縮フラグ |
| daily_accounting_flags | 文字列 | No | -q | sa(8)コマンドへのフラグ |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| /var/account/acct | バイナリ | 現在のプロセスアカウンティングログ |
| /var/account/acct.N | バイナリ | 過去のアカウンティングログ（N=0,1,2,...） |
| /var/account/acct.N.gz | gzip圧縮バイナリ | 圧縮済み過去ログ |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| /var/account/acct.0 | バイナリ | ローテーション後の直前ログ |
| /var/account/acct.0.gz | gzip圧縮バイナリ | 圧縮有効時のローテーション済みログ |
| /var/account/savacct | バイナリ | sa(8)による統計サマリファイル |
| /var/account/usracct | バイナリ | sa(8)によるユーザ別統計ファイル |
| 標準出力 | テキスト | "Rotating accounting logs and gathering statistics:" |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | acct.N（N=0,1,...,daily_accounting_save-1） |
| 出力先 | /var/account/ |
| 文字コード | バイナリ形式（アカウンティングレコード） |
| 区切り文字 | N/A（バイナリ） |

## 処理フロー

### 処理シーケンス

```
1. periodic.confの読み込み
   └─ /etc/defaults/periodic.confとローカル設定を読み込む
2. daily_accounting_enable判定
   └─ YESでない場合、rc=0で終了
3. 前提条件チェック
   ├─ /var/account/acctの存在確認
   ├─ kern.acct_configuredの確認
   └─ daily_accounting_saveの設定確認
4. 古いログの削除
   └─ 世代番号 >= (daily_accounting_save - 1) のファイルを削除
5. ログファイルのリネーム（世代繰り上げ）
   └─ acct.N → acct.(N+1) を逆順で実行
6. /etc/rc.d/accounting onerotate_log実行
   └─ 現在のacctをacct.0にローテーション
7. acct.0をacct.mergeにコピー
8. sa -s実行（統計収集）
   └─ acct.mergeから統計情報を抽出
9. acct.mergeの削除
10. 圧縮オプション判定
    └─ daily_accounting_compress=YES時、acct.0をgzip圧縮
11. 終了コード(rc)を返却して終了
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[periodic.conf読み込み]
    B --> C{daily_accounting_enable=YES?}
    C -->|No| D[スキップ rc=0]
    C -->|Yes| E{/var/account/acct存在?}
    E -->|No| F[エラー rc=2]
    E -->|Yes| G{kern.acct_configured!=0?}
    G -->|No| H[エラー rc=2]
    G -->|Yes| I{daily_accounting_save設定あり?}
    I -->|No| J[エラー rc=2]
    I -->|Yes| K[古いログ削除]
    K --> L[ログファイル世代繰り上げ]
    L --> M[onerotate_log実行]
    M --> N[acct.0→acct.mergeコピー]
    N --> O[sa -s 統計収集]
    O --> P[acct.merge削除]
    P --> Q{daily_accounting_compress=YES?}
    Q -->|Yes| R[acct.0をgzip圧縮]
    Q -->|No| S[終了]
    R --> S
    D --> T[exit rc]
    F --> T
    H --> T
    J --> T
    S --> T
```

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

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

本バッチはデータベース操作を行わない。ファイルシステム上のアカウンティングログのみを操作する。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| rc=2 | 前提条件エラー | /var/account/acctが存在しない | プロセスアカウンティングを有効化するか、バッチを無効化する |
| rc=2 | 前提条件エラー | kern.acct_configuredが0 | カーネルでaccounting機能を有効化する |
| rc=2 | 設定不足 | daily_accounting_saveが未設定 | periodic.confでdaily_accounting_saveを設定する |
| rc=3 | 処理エラー | ファイル操作（rm, mv, gzip等）が失敗 | ディスク容量・パーミッションを確認する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（リトライ機構なし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

ローテーション処理中の失敗はrc=3として報告されるが、処理は継続される。障害時は/var/account/配下の状態を確認し、必要に応じて手動でファイルをリネーム・削除する。acct.mergeが残存している場合は手動で削除する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 全体（ただしアトミックではない） |
| コミットタイミング | 各ファイル操作完了時 |
| ロールバック条件 | なし（失敗時もrc=3を設定し処理続行） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 保存世代数分のファイル操作 |
| 目標処理時間 | 通常数秒以内 |
| メモリ使用量上限 | シェルスクリプトのため最小限。sa(8)コマンドの使用量に依存 |

## 排他制御

`/etc/rc.d/accounting onerotate_log` によるログローテーション時、カーネルのアカウンティング機能が一時的に切り替わる。periodicフレームワークにより日次で1回のみ実行されることが想定されている。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | "Rotating accounting logs and gathering statistics:" |
| エラーログ | 前提条件不足時 | 各種エラーメッセージ（acctファイル不在等） |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | rc!=0 | periodicフレームワーク経由のメール通知 |
| アカウンティング未有効 | rc=2 | periodicフレームワーク経由のメール通知 |

## 備考

- デフォルトで有効（daily_accounting_enable=YES）であり、プロセスアカウンティングが設定済みの環境では自動的に動作する
- sa(8)コマンドの-sフラグにより、統計情報が/var/account/savacctおよび/var/account/usracctに保存される
- daily_accounting_flagsのデフォルトは"-q"（quiet mode）
- 圧縮オプション（daily_accounting_compress）はデフォルトでNO
- ソースファイル: `usr.sbin/periodic/etc/daily/310.accounting`
