# 機能設計書 50-ログ管理

## 概要

本ドキュメントは、JenkinsのLog Recorder Manager（ログ管理）機能の設計を記載する。

### 本機能の処理概要

ログ管理は、Jenkinsのシステムログとカスタムログレコーダーを管理する機能を提供する。特定のパッケージやクラスのログレベルを動的に変更し、トラブルシューティングのためのログ収集を行うことができる。

**業務上の目的・背景**：CI/CD環境の運用において、問題のトラブルシューティングには詳細なログ情報が必要である。ログ管理機能により、必要な時に必要なログのみを収集し、問題解析を効率化できる。

**機能の利用シーン**：
- プラグインの問題調査時に特定のログレベルを一時的にDEBUGに変更
- セキュリティ監査のためのログ収集
- パフォーマンス問題の調査
- 特定機能のデバッグ

**主要な処理内容**：
1. システムログの表示
2. カスタムログレコーダーの作成・編集・削除
3. ログレベルの動的変更
4. ログのRSSフィード提供
5. エージェント上のログ収集

**関連システム・外部連携**：java.util.loggingフレームワークと連携。エージェントにもログレベル設定を伝播。

**権限による制御**：ログ管理にはJenkins.ADMINISTERまたはJenkins.SYSTEM_READ権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 52 | システムログ | 主画面 | システムログの表示、ログレコーダーの管理 |

## 機能種別

ログ管理 / トラブルシューティング

## 入力仕様

### 入力パラメータ

#### ログレコーダー作成

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | ログレコーダー名 | 空文字不可、Jenkins.checkGoodName() |

#### ログターゲット設定

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loggers | List<Target> | Yes | ログターゲットのリスト | - |
| loggers[].name | String | No | ロガー名（パッケージ/クラス名） | 空文字でルートロガー |
| loggers[].level | Level | Yes | ログレベル | 有効なjava.util.logging.Level |

#### ログレベル変更（configLogger）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | ロガー名 | 既存のロガー名 |
| level | String | Yes | ログレベル（inherit/ALL/FINEST/FINER/FINE/CONFIG/INFO/WARNING/SEVERE/OFF） | 有効なレベル名 |

### 入力データソース

- Web UIからのフォーム入力
- $JENKINS_HOME/log/{name}.xmlからのロード

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ログレコード | List<LogRecord> | 収集されたログエントリ |
| ログレコーダー一覧 | List<LogRecorder> | 設定されたログレコーダー |

### 出力先

- Web UI（ログ表示画面）
- RSSフィード
- $JENKINS_HOME/log/{name}.xml（設定ファイル）

## 処理フロー

### 処理シーケンス

#### ログレコーダー作成

```
1. 権限チェック（Jenkins.ADMINISTER）
2. 名前バリデーション
3. LogRecorderオブジェクト生成
4. recorderリストに追加
5. 設定画面にリダイレクト
```

#### ログ収集

```
1. LogRecorder初期化時
   └─ WeakLogHandlerを登録
2. ログ発生時
   └─ RingBufferLogHandler.publish()
   └─ 各Targetとのマッチング
   └─ マッチすればバッファに追加
3. 表示時
   └─ handler.getView()でログ取得
```

#### ログレベル変更（configLogger）

```
1. 権限チェック（Jenkins.ADMINISTER）
2. レベルパース（「inherit」の場合はnull）
3. ロガー存在チェック
4. Logger.setLevel()でレベル設定
5. /levelsにリダイレクト
```

### フローチャート

```mermaid
flowchart TD
    A[ログ発生] --> B[RingBufferLogHandler.publish]
    B --> C[orderedTargets取得]
    C --> D[各Targetをループ]
    D --> E{ドメインマッチ?}
    E -->|No| F[次のTarget]
    E -->|null| F
    E -->|Yes| G{レベルマッチ?}
    G -->|Yes| H[バッファに追加]
    G -->|No| I[スキップ]
    F --> D
    H --> J[終了]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-50-01 | ターゲット優先度 | より具体的なロガー名（長い名前）が優先的にマッチング | ログ収集時 |
| BR-50-02 | 空名前ルートロガー | ターゲット名が空の場合はルートロガーとして全てのログにマッチ | ログ収集時 |
| BR-50-03 | エージェント伝播 | ログレベル設定はエージェントにも伝播される | ログレベル変更時 |
| BR-50-04 | バッファサイズ | RingBufferLogHandlerは固定サイズのリングバッファを使用 | ログ収集時 |
| BR-50-05 | 重複ロガー無視 | 同名のログレコーダーが複数存在する場合は最初のものを使用 | 設定ロード時 |

### ログレベル定義

| レベル | 数値 | 説明 |
|--------|-----|------|
| ALL | Integer.MIN_VALUE | 全てのログを収集 |
| FINEST | 300 | 最も詳細なトレースメッセージ |
| FINER | 400 | より詳細なトレースメッセージ |
| FINE | 500 | 詳細なトレースメッセージ |
| CONFIG | 700 | 設定関連メッセージ |
| INFO | 800 | 情報メッセージ（デフォルト） |
| WARNING | 900 | 警告メッセージ |
| SEVERE | 1000 | エラーメッセージ |
| OFF | Integer.MAX_VALUE | ログを収集しない |

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

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

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 保存 | $JENKINS_HOME/log/{name}.xml | WRITE | ログレコーダー設定の永続化 |
| ロード | $JENKINS_HOME/log/{name}.xml | READ | 起動時の設定読み込み |
| 削除 | $JENKINS_HOME/log/{name}.xml | DELETE | ログレコーダー削除時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Failure | ロガー不存在 | configLoggerで指定ロガーが存在しない | 有効なロガー名を指定 |
| FormException | 名前不正 | 不正なログレコーダー名 | 有効な名前を指定 |

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

XMLファイルへの保存は原子的ではないが、XmlFileクラスが一時ファイルを経由したアトミック書き込みを実装。

## パフォーマンス要件

- ログ表示: 1秒以内（バッファサイズに依存）
- ログレベル変更: 即時反映

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

- ログ表示/管理にはJenkins.ADMINISTERまたはJenkins.SYSTEM_READ権限が必要
- ログに機密情報が含まれる可能性があるため、アクセス制限が重要
- SKIP_PERMISSION_CHECKでエスケープハッチあり（スクリプトコンソール用）

## 備考

- システムログはJenkins.logRecordsで管理されるメインログ
- カスタムログレコーダーは特定のパッケージ/クラスのログを収集
- ログ名の自動補完機能あり

---

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

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

### 推奨読解順序

#### Step 1: LogRecorderManagerを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LogRecorderManager.java | `core/src/main/java/hudson/logging/LogRecorderManager.java` | ログ管理の親クラス |
| 1-2 | LogRecorder.java | `core/src/main/java/hudson/logging/LogRecorder.java` | 個別ログレコーダー |

**主要処理フロー（LogRecorderManager）**:
- **84行目**: ModelObjectWithChildrenとStaplerProxyを実装
- **96-98行目**: recorderリストの定義
- **105-123行目**: setRecorders() - 重複チェック付きのレコーダー設定
- **139-141行目**: getLogRecorder() - 名前でレコーダー取得
- **150-162行目**: load() - 設定ファイルからロード
- **167-177行目**: doNewLogRecorder() - 新規レコーダー作成
- **206-226行目**: doConfigLogger() - ログレベル変更
- **288-291行目**: init() - Jenkins起動時の初期化

**主要処理フロー（LogRecorder）**:
- **102行目**: LogableとSaveableを実装
- **109-114行目**: コンストラクタ（WeakLogHandler登録）
- **217-236行目**: RingBufferLogHandler - ログ収集ロジック
- **242-338行目**: Target内部クラス - ログターゲット定義
- **301-314行目**: matches() - ログレコードとのマッチング
- **326-330行目**: enable() - ログレベル設定とエージェント伝播
- **350-382行目**: SetLevel - エージェントへのログレベル伝播
- **416-440行目**: doConfigSubmit() - 設定保存処理

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

```
/log （ログ管理URL）
    │
    ├─ LogRecorderManager
    │      ├─ load() - 起動時ロード
    │      │      └─ 各.xmlファイルをLogRecorderとしてロード
    │      │
    │      ├─ doNewLogRecorder() - 新規作成
    │      │      └─ LogRecorder生成
    │      │
    │      ├─ doConfigLogger() - レベル変更
    │      │      └─ Logger.setLevel()
    │      │
    │      └─ doRss() - RSSフィード
    │
    └─ LogRecorder（各レコーダー）
           ├─ WeakLogHandler登録
           │      └─ RingBufferLogHandler
           │             └─ publish() - ログ収集
           │
           ├─ Target.enable()
           │      └─ SetLevel.broadcast() - エージェント伝播
           │
           └─ save() - 設定保存
                  └─ XmlFile.write()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LogRecorderManager.java | `core/src/main/java/hudson/logging/LogRecorderManager.java` | ソース | ログ管理親クラス |
| LogRecorder.java | `core/src/main/java/hudson/logging/LogRecorder.java` | ソース | 個別ログレコーダー |
| WeakLogHandler.java | `core/src/main/java/hudson/logging/WeakLogHandler.java` | ソース | 弱参照ログハンドラ |
| RingBufferLogHandler.java | `core/src/main/java/hudson/util/RingBufferLogHandler.java` | ソース | リングバッファ |
| SystemLogLink.java | `core/src/main/java/jenkins/management/SystemLogLink.java` | ソース | 管理リンク |
