# バッチ設計書 21-tf_env_collect.sh

## 概要

本ドキュメントは、TensorFlow実行環境の情報を収集しファイルに出力するバッチ `tf_env_collect.sh` の設計書である。GitHub Issue報告時に必要な環境情報を自動収集する目的で使用される。

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

本バッチは、TensorFlowの利用者がバグ報告やサポート依頼を行う際に、実行環境の詳細情報を自動的に収集し、テキストファイルとして出力するシェルスクリプトである。収集した情報はGitHub Issueテンプレートのフィールドに転記するために利用される。

**業務上の目的・背景**：TensorFlowのバグ報告やトラブルシューティングにおいて、ユーザーの実行環境情報（Pythonバージョン、OS情報、CUDA/cuDNNの有無、TensorFlowバージョン等）は問題の再現・診断に不可欠である。手動で各項目を確認するのは煩雑でありヒューマンエラーも発生しやすいため、本バッチにより環境情報を一括自動収集し、GitHub Issueへの正確な情報提供を支援する。

**バッチの実行タイミング**：ユーザーが手動で随時実行する。主にバグ報告やIssue作成時にトリガーされる。定期実行スケジュールは存在しない。

**主要な処理内容**：
1. Pythonバイナリの検出とPythonバージョン情報の収集
2. OSプラットフォーム情報（OS種別、カーネルバージョン、アーキテクチャ等）の収集
3. Docker環境内かどうかの判定
4. C++コンパイラのバージョン確認
5. pip経由でインストールされたTensorFlow関連パッケージの一覧取得
6. Python仮想環境の使用有無の確認
7. TensorFlowのimportテストとバージョン情報（VERSION, GIT_VERSION, COMPILER_VERSION）の取得
8. libcudnn（CUDA Deep Neural Networkライブラリ）のロード確認
9. 環境変数（LD_LIBRARY_PATH, DYLD_LIBRARY_PATH）の確認
10. nvidia-smiによるGPU情報の取得
11. CUDAライブラリ（cudart, cudnn）のファイル検索
12. tensorflow / tf_nightly のpipインストール情報の取得
13. Pythonの詳細バージョン情報（sys.version_info）の取得
14. Bazelバージョンの取得
15. 全出力からGoogle関連の行を除外し、`tf_env.txt` にリダイレクト

**前後の処理との関連**：本バッチは単独で動作するユーティリティであり、他のバッチへの依存関係はない。後続処理として、出力された `tf_env.txt` の内容をユーザーがGitHub Issueテンプレートに貼り付けて利用する。

**影響範囲**：本バッチは読み取り専用の情報収集処理であり、システムやデータに対する変更・副作用は `/tmp/loadedlibs` への一時ファイル書き込みとカレントディレクトリへの `tf_env.txt` 出力のみである。

## バッチ種別

環境情報収集 / レポート生成

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | 手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Python実行環境 | `python` または `python3` コマンドがPATH上に存在すること |
| シェル環境 | Bash互換シェルが利用可能であること |
| TensorFlow（任意） | TensorFlow情報収集セクションはTensorFlowがインストールされていなくても動作するが、情報は限定される |

### 実行可否判定

Pythonバイナリ（`python` または `python3`）がPATH上に見つからない場合、`die` 関数によりエラーメッセージを出力してexit code 1で終了する。それ以外の前提条件は各セクションでコマンドの存在を個別にチェックし、見つからない場合はそのセクションのみ "Not found" 等を出力して処理を続行する。

## 入力仕様

### 入力パラメータ

本バッチは引数を取らない。

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | コマンドライン引数は使用しない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| Pythonランタイム | コマンド出力 | `platform` モジュール、`sys` モジュールからの情報取得 |
| /proc/1/cgroup | テキストファイル | Docker環境判定のために参照（Linux環境のみ） |
| pip | コマンド出力 | インストール済みパッケージ情報 |
| nvidia-smi | コマンド出力 | GPU情報 |
| /usr ディレクトリ | ファイルシステム | CUDAライブラリファイルの検索対象 |
| bazel | コマンド出力 | Bazelのバージョン情報 |
| 環境変数 | シェル環境 | LD_LIBRARY_PATH, DYLD_LIBRARY_PATH |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| tf_env.txt | テキストファイル | 収集した環境情報の集約ファイル（カレントディレクトリに出力） |
| /tmp/loadedlibs | テキストファイル | TensorFlowがロードするライブラリの一時デバッグ出力 |
| 標準エラー出力 | テキスト | 処理進捗のヘッダー表示 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | `tf_env.txt` |
| 出力先 | カレントディレクトリ |
| 文字コード | システムデフォルト（通常UTF-8） |
| 区切り文字 | なし（セクション別のヘッダーで区切られたテキスト形式） |

出力ファイルは以下のセクションで構成される：

1. `== check python ==` - Pythonバージョン、ブランチ、ビルド、コンパイラ、実装情報
2. `== check os platform ==` - OS種別、カーネルバージョン、リリース、プラットフォーム、アーキテクチャ等
3. `== are we in docker ==` - Docker環境内かどうか（Yes/No）
4. `== c++ compiler ==` - C++コンパイラのパスとバージョン
5. `== check pips ==` - proto, numpy, tensorflow, tf_nightly関連パッケージ一覧
6. `== check for virtualenv ==` - 仮想環境の使用有無
7. `== tensorflow import ==` - TensorFlowバージョン情報とサニティチェック結果
8. `== env ==` - LD_LIBRARY_PATH, DYLD_LIBRARY_PATHの値
9. `== nvidia-smi ==` - GPU情報
10. `== cuda libs ==` - CUDAライブラリのファイルパス
11. `== tensorflow installation ==` - pip show tensorflowの出力
12. `== tf_nightly installation ==` - pip show tf_nightlyの出力
13. `== python version ==` - sys.version_infoのタプル表示
14. `== bazel version ==` - Bazelバージョン情報

なお、全出力から "google" を含む行（大文字小文字不問）が除外される。

## 処理フロー

### 処理シーケンス

```
1. 初期化処理
   └─ set -u による未定義変数チェックの有効化
   └─ OUTPUT_FILE 変数を "tf_env.txt" に設定
   └─ Python バイナリパスの検出（python -> python3 の順でフォールバック）
   └─ ヘッダー表示用の定数・関数を定義
   └─ 出力ファイルを空にする

2. Python情報収集
   └─ platform モジュールを使用して Python バージョン・ビルド・コンパイラ情報を出力

3. OSプラットフォーム情報収集
   └─ platform モジュールの各関数（system, version, release, platform, uname, architecture, machine 等）を呼び出し

4. Docker環境判定
   └─ /proc/1/cgroup 内に "docker" 文字列が存在するか検索

5. C++コンパイラ情報収集
   └─ c++ コマンドの存在確認とバージョン出力

6. pipパッケージ情報収集
   └─ pip list の結果から proto, numpy, tensorflow, tf_nightly を含む行を抽出

7. 仮想環境判定
   └─ sys.real_prefix または sys.base_prefix と sys.prefix の比較

8. TensorFlowインポートテスト
   └─ tensorflow をインポートし、VERSION, GIT_VERSION, COMPILER_VERSION を出力
   └─ tf.constant によるサニティチェック
   └─ LD_DEBUG=libs で tensorflow をインポートし、libcudnn のロード状況を確認

9. 環境変数確認
   └─ LD_LIBRARY_PATH の設定状態と値を出力
   └─ DYLD_LIBRARY_PATH の設定状態と値を出力

10. GPU情報収集
    └─ nvidia-smi の実行結果を出力

11. CUDAライブラリ検索
    └─ /usr 配下で libcud* にマッチするファイルから cudart, cudnn を含むものを検索

12. パッケージインストール情報
    └─ pip show tensorflow の実行
    └─ pip show tf_nightly の実行

13. Python詳細バージョン情報
    └─ sys.version_info のタプル出力

14. Bazelバージョン情報
    └─ bazel version の実行

15. 後処理
    └─ 全出力から "google" を含む行を除外して tf_env.txt に書き込み
    └─ ユーザーへの完了メッセージとファイル参照案内を表示
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[Pythonバイナリ検出]
    B -->|見つからない| C[die: エラー終了]
    B -->|見つかった| D[出力ファイル初期化]
    D --> E[Python情報収集]
    E --> F[OSプラットフォーム情報収集]
    F --> G[Docker環境判定]
    G --> H[C++コンパイラ情報収集]
    H --> I[pipパッケージ情報収集]
    I --> J[仮想環境判定]
    J --> K[TensorFlowインポートテスト]
    K --> L[libcudnnロード確認]
    L --> M[環境変数確認]
    M --> N[nvidia-smi実行]
    N --> O[CUDAライブラリ検索]
    O --> P[パッケージインストール情報取得]
    P --> Q[Python詳細バージョン取得]
    Q --> R[Bazelバージョン取得]
    R --> S[google行フィルタ適用]
    S --> T[tf_env.txtへ書き込み]
    T --> U[完了メッセージ表示]
    U --> V[バッチ終了]
```

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

本バッチはデータベース操作を行わない。

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| なし | - | - | データベースへのアクセスは発生しない |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| exit 1 | 致命的エラー | Pythonバイナリ（python/python3）がPATH上に存在しない | Pythonをインストールしてパスを通す |
| (継続) | 非致命的 | c++ コマンドが見つからない | "Not found" を出力して次のセクションへ進む |
| (継続) | 非致命的 | nvidia-smi が存在しない、またはGPUがない | nvidia-smi のエラー出力がそのまま記録される |
| (継続) | 非致命的 | TensorFlowがインストールされていない | ImportError等のエラーメッセージが記録される |
| (継続) | 非致命的 | tensorflow / tf_nightly が pip に登録されていない | "tensorflow not found" / "tf_nightly not found" を出力 |
| (継続) | 非致命的 | Bazelがインストールされていない | bazel version のエラー出力が記録される |
| (継続) | 非致命的 | /proc/1/cgroup が存在しない（macOS等） | grep がエラーを返し "No" 分岐に入る |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（リトライ機構は実装されていない） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

### 障害時対応

Pythonバイナリ未検出以外の障害では個別セクションが不完全な出力になるのみで、バッチ全体は正常終了する。`tf_env.txt` の内容を確認し、情報が不足しているセクションについては手動で補完する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし（データベース操作なし） |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

備考：出力ファイルへの書き込みはサブシェル内の全出力をパイプでgrepした結果を `>>` でリダイレクトする構造のため、処理途中で中断した場合は部分的な出力ファイルが残る。

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1回の実行で1件の環境情報ファイルを生成 |
| 目標処理時間 | 数秒〜数十秒（環境依存、TensorFlowのimportに最も時間がかかる） |
| メモリ使用量上限 | 特に制限なし（TensorFlowのimport時にTensorFlow自体のメモリ使用量に依存） |

## 排他制御

排他制御は実装されていない。同一ディレクトリで同時実行した場合、`tf_env.txt` および `/tmp/loadedlibs` への書き込みが競合する可能性がある。ただし、本バッチはユーザーが手動で実行するユーティリティであるため、同時実行は想定されていない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | "Collecting system information..." を標準出力に表示 |
| 進捗ログ | 各セクション処理開始時 | セクションヘッダー（例: `== check python ==`）を標準エラー出力に表示 |
| 終了ログ | バッチ終了時 | "Wrote environment to tf_env.txt..." のメッセージを標準出力に表示 |
| エラーログ | Pythonバイナリ未検出時 | "Cannot find Python binary" を標準出力に表示後、exit 1 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| なし | - | - |

本バッチはユーザーが手動で実行するユーティリティであるため、監視・アラート機能は設けられていない。

## 備考

- ソースファイルパス: `tools/tf_env_collect.sh`
- ライセンス: Apache License, Version 2.0
- `set -u` オプションにより、未定義変数の参照時にエラーが発生する。環境変数 `LD_LIBRARY_PATH` および `DYLD_LIBRARY_PATH` については `${VAR+x}` 構文で未設定を安全にチェックしている。
- 出力から "google" を含む行が除外される（`grep -v -i google`）。これはプライバシーやセキュリティ上の配慮と考えられる。
- `/proc/1/cgroup` によるDocker判定はLinux固有の手法であり、macOS等では常に "No" となるか、ファイルが存在しない場合にgrepがエラーを返す。
- 本バッチは2017年にTensorFlow Authorsにより作成されたものである。
