# 画面設計書 64-JVMクラッシュログ一覧

## 概要

本ドキュメントは、Jenkins CI/CDサーバーの「JVMクラッシュログ一覧」画面の設計書です。

### 本画面の処理概要

JVMがクラッシュした際に生成されるhs_err_pidファイルの一覧を表示し、ダウンロードや削除が可能な診断画面です。

**業務上の目的・背景**：JVMのクラッシュは深刻な問題であり、その原因分析にはhs_err_pidファイル（クラッシュダンプ）が不可欠です。この画面は、管理者がサーバーにSSHでアクセスすることなく、WebブラウザからJVMクラッシュログを確認・取得できるようにすることを目的としています。クラッシュダンプには、スタックトレース、ロードされたライブラリ、メモリ情報などが含まれており、問題の原因究明に役立ちます。

**画面へのアクセス方法**：Jenkins管理画面に警告バナーとして表示されます（クラッシュログが存在する場合）。または `/administrativeMonitor/hsErrPid/` からアクセスします。

**主要な操作・処理内容**：
1. hs_err_pidファイルの一覧表示
2. 各ファイルのパス、最終更新日時、経過時間の確認
3. ファイルのダウンロード
4. 不要なファイルの削除

**画面遷移**：Jenkins管理画面の警告バナーから遷移、ダウンロード/削除後は同画面に戻ります

**権限による表示制御**：ADMINISTER権限を持つ管理者のみがアクセス・操作可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 50 | ログ管理 | 主機能 | JVMクラッシュログの一覧表示 |
| 47 | 管理モニター | 補助機能 | 警告バナーとしての表示 |

## 画面種別

一覧 / 診断

## URL/ルーティング

- URL: `/administrativeMonitor/hsErrPid/`
- ルーティング: `HsErrPidList` クラスが AdministrativeMonitor として登録され、Staplerにより URLにバインドされます

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| - | - | - | - | この画面には入力項目はありません |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| タイトル | 見出し | "Java VM Crash Reports" |
| 説明文 | テキスト | hs_err_pidファイルについての説明 |
| ファイル一覧テーブル | テーブル | クラッシュログファイルの一覧 |

### ファイル一覧テーブル詳細

| カラム名 | 型 | 説明 | ソート可 |
|---------|-----|------|---------|
| Name | リンク | ファイルパス（ダウンロードリンク） | Yes |
| Date | 日時 | 最終更新日時 + 経過時間 | Yes |
| (操作) | ボタン | 削除ボタン | No |

## イベント仕様

### 1-ファイルダウンロード

ファイル名リンクをクリックした際の処理です。

**URL**: `files/{index}/download/{fileName}`

**処理フロー**：
1. ADMINISTER権限のチェック
2. 指定されたインデックスのファイルを取得
3. ファイルをHTTPレスポンスとしてストリーミング

### 2-ファイル削除

削除ボタンを押下した際の処理です。

**URL**: `files/{index}/delete` (POST)

**処理フロー**：
1. ADMINISTER権限のチェック
2. 指定されたインデックスのファイルを削除
3. filesリストからファイルを除去
4. `../..` へリダイレクト（一覧画面に戻る）

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ファイル削除 | なし | ファイル削除 | hs_err_pidファイルをファイルシステムから削除 |

### ファイル操作詳細

| 操作 | 対象 | 説明 |
|------|------|------|
| DELETE | hs_err_pid*.log | Files.deleteIfExists()で削除 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| Java VM Crash Reports | 見出し | Java VM Crash Reports | 常時表示 |
| blurb | 説明 | hs_err_pidファイルについての説明 | 常時表示 |
| Name | カラムヘッダー | Name | 常時表示 |
| Date | カラムヘッダー | Date | 常時表示 |
| ago | テキスト | {0} ago | 経過時間表示（{0}は経過時間文字列） |
| Delete | ボタン | Delete | 各行に表示 |

## 例外処理

| 例外条件 | 対応 | 表示内容 |
|---------|------|---------|
| 権限不足 | 403エラー | アクセス拒否画面へリダイレクト |
| ファイルが見つからない | 404エラー | ファイルが存在しない旨のエラー |
| IOException | 500エラー | ファイル操作エラーのメッセージ |

## 備考

- hs_err_pidファイルは、JVMがネイティブコードでクラッシュした場合に生成されます
- ファイルの検出は、以下の場所で行われます：
  - カレントディレクトリ: `./hs_err_pid*.log`
  - Windowsの場合: 一時ディレクトリ
  - Unix系の場合: `/tmp/hs_err_pid*.log`
  - JVMオプション `-XX:ErrorFile=` で指定された場所
- Jenkinsに属するファイルのみが表示されます（secret.keyファイルのパスがファイル内に含まれているかで判定）
- この画面は AdministrativeMonitor として実装されており、クラッシュログが存在する場合に警告バナーが表示されます

---

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

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

### 推奨読解順序

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

まず、hs_err_pidファイルの管理構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | HsErrPidList.java | `core/src/main/java/jenkins/diagnosis/HsErrPidList.java` | ファイルリストの管理、AdministrativeMonitor継承を理解 |
| 1-2 | HsErrPidFile.java | `core/src/main/java/jenkins/diagnosis/HsErrPidFile.java` | 個別ファイルの操作（ダウンロード/削除）を理解 |

**読解のコツ**: `HsErrPidList` はファイル一覧を管理し、`HsErrPidFile` は個々のファイル操作を担当します。

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

画面表示の起点となるファイルを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.jelly | `core/src/main/resources/jenkins/diagnosis/HsErrPidList/index.jelly` | 画面構造、テーブル表示、アクションURLを理解 |

**主要処理フロー**:
1. **行27**: レイアウトとタイトルの設定
2. **行28**: サイドパネルの表示
3. **行34**: テーブル（ソート可能）の開始
4. **行43-61**: ファイル行のループ表示
5. **行47-49**: ファイルダウンロードリンク
6. **行51-54**: 日時と経過時間の表示
7. **行56-59**: 削除フォーム

#### Step 3: ファイル検出ロジックを理解する

hs_err_pidファイルの検出処理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HsErrPidList.java | `core/src/main/java/jenkins/diagnosis/HsErrPidList.java` | コンストラクタのscan()メソッド呼び出しを理解 |

**主要処理フロー**:
- **行37-38**: `@Extension @Symbol("hsErrPid")` でJenkins起動時に自動登録
- **行49-83**: コンストラクタでファイルスキャン実行
- **行60-68**: 検索パターンの設定（OS別）
- **行72-77**: JVMオプション `-XX:ErrorFile=` の解析
- **行99-122**: `scan()` メソッドでGLOBパターンによるファイル検索
- **行124-148**: `scanFile()` メソッドでファイル検証（secret.keyの存在確認）

#### Step 4: ファイル操作を理解する

個別ファイルの操作処理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | HsErrPidFile.java | `core/src/main/java/jenkins/diagnosis/HsErrPidFile.java` | doDownload(), doDelete()を理解 |

**主要処理フロー**:
- **行47-49**: `doDownload()` でファイルをダウンロード
- **行52-58**: `doDelete()` でファイル削除とリスト更新

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

```
HsErrPidList (コンストラクタ) [Jenkins起動時]
    │
    ├─ scan("./hs_err_pid%p.log")
    │      │
    │      ├─ GlobパターンでFileSet作成
    │      │
    │      └─ scanFile(file)
    │             │
    │             ├─ findHeader(reader) ─── JVMクラッシュファイル確認
    │             │
    │             └─ secret.key パス検索 ─── このJenkinsに属するか確認
    │                    │
    │                    └─ files.add(new HsErrPidFile(...))
    │
    ├─ scan("/tmp/hs_err_pid%p.log")  [Unix]
    │
    └─ scan("-XX:ErrorFile=..." の値)  [JVMオプション]

index.jelly (画面表示)
    │
    ├─ ${it.files} ─── ファイル一覧取得
    │
    ├─ files/{idx}/download/{name} ─── ダウンロードリンク
    │      │
    │      └─ HsErrPidFile.doDownload()
    │             └─ HttpResponses.staticResource(file)
    │
    └─ files/{idx}/delete (POST) ─── 削除フォーム
           │
           └─ HsErrPidFile.doDelete()
                  ├─ Files.deleteIfExists(file)
                  └─ owner.files.remove(this)
```

### データフロー図

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

Jenkins起動 ──────────▶ HsErrPidList() ─────────────▶ files リスト
                              │
                              ▼
                    scan() × 複数パターン
                              │
                              ▼
                    scanFile() ─────────────────▶ HsErrPidFile
                              │
                              ▼
                    findHeader() + secret.key検索


画面アクセス ─────────▶ index.jelly ─────────────▶ HTML一覧画面
                              │
                              ▼
                        ${it.files}


ダウンロードリンク ───▶ doDownload() ─────────────▶ ファイル内容
                              │
                              ▼
                   HttpResponses.staticResource()


削除ボタン ───────────▶ doDelete() ───────────────▶ リダイレクト
                              │
                              ├─ Files.deleteIfExists()
                              │
                              └─ files.remove()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| HsErrPidList.java | `core/src/main/java/jenkins/diagnosis/HsErrPidList.java` | ソース | ファイル一覧管理の主クラス |
| HsErrPidFile.java | `core/src/main/java/jenkins/diagnosis/HsErrPidFile.java` | ソース | 個別ファイル操作クラス |
| index.jelly | `core/src/main/resources/jenkins/diagnosis/HsErrPidList/index.jelly` | テンプレート | 画面表示用Jellyテンプレート |
| AdministrativeMonitor.java | `core/src/main/java/hudson/model/AdministrativeMonitor.java` | ソース | 管理モニターの基底クラス |
| JavaVMArguments.java | `core/src/main/java/jenkins/util/JavaVMArguments.java` | ソース | JVMオプションの取得 |
