# 機能設計書 51-ログ

## 概要

本ドキュメントは、VS Codeのログ出力機能に関する設計書である。アプリケーション全体のログ記録、ログレベル管理、ファイル出力、複数ロガーの管理など、デバッグや運用監視に必要なログ機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：
VS Codeは複雑なアプリケーションであり、開発者やユーザーが問題を診断・解決するためにログ機能が必要不可欠である。エラー発生時のトラブルシューティング、パフォーマンス分析、拡張機能のデバッグなど、様々な場面でログ情報が活用される。また、テレメトリと連携してユーザー体験の向上に貢献する。

**機能の利用シーン**：
- 開発者がVS Code本体や拡張機能のデバッグを行う際
- ユーザーが問題報告時にログを収集する際
- 運用チームがパフォーマンス監視や障害分析を行う際
- 拡張機能が独自のログを出力する際

**主要な処理内容**：
1. ログレベル（Trace, Debug, Info, Warning, Error, Off）に基づくログのフィルタリング
2. コンソールログ出力（色付き/色なし）
3. ファイルへのログ出力（ローテーション対応）
4. 複数ロガーの多重化出力（MultiplexLogger）
5. ロガーの登録・管理・可視性制御
6. IPC経由でのリモートログ転送

**関連システム・外部連携**：
- ファイルシステムサービス（IFileService）: ログファイルの読み書き
- 環境サービス（IEnvironmentService）: ログレベル設定の取得
- spdlog: ネイティブ高速ログライブラリ（Node.js環境）

**権限による制御**：
ログレベルは環境変数やコマンドライン引数で制御可能。拡張機能は専用のロガーチャネルを作成でき、ユーザーは出力パネルで表示/非表示を制御できる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | ステータスバー | 主機能 | 各種ステータス情報（言語、エンコード、行列番号等）の表示 |

## 機能種別

ログ出力 / インフラストラクチャ / システム監視

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| message | string | Yes | ログメッセージ | 空文字列も許容 |
| args | unknown[] | No | 追加の引数（オブジェクト、エラーなど） | 特になし |
| level | LogLevel | No | ログレベル（メソッドで決定） | 0-5の範囲 |

### 入力データソース

- プログラム内からの直接呼び出し（各サービス、拡張機能）
- コマンドライン引数（--log=レベル、--verbose）
- 設定ファイル（環境変数、ワークスペース設定）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| formattedLog | string | タイムスタンプ・レベル付きのフォーマット済みログ |
| logFile | File | ローテーション対応のログファイル |
| consoleOutput | string | コンソール出力（色付き可） |

### 出力先

- コンソール（開発者ツール、ターミナル）
- ファイル（logsフォルダ内、拡張子.log）
- 出力パネル（VS Code UI）

## 処理フロー

### 処理シーケンス

```
1. ログメソッド呼び出し（trace/debug/info/warn/error）
   └─ メッセージと引数を受け取る
2. ログレベルチェック
   └─ 現在のログレベルと比較し、出力可否を判定
3. メッセージフォーマット
   └─ 引数をJSON化、Errorオブジェクトをスタックトレースに変換
4. タイムスタンプ付加
   └─ ISO形式またはカスタム形式でタイムスタンプを追加
5. 出力先への書き込み
   └─ MultiplexLoggerの場合は各ロガーに順次出力
6. ファイルローテーション（ファイルログの場合）
   └─ 5MB超過時にバックアップファイルを作成
```

### フローチャート

```mermaid
flowchart TD
    A[ログメソッド呼び出し] --> B{ログレベルチェック}
    B -->|出力不可| C[処理終了]
    B -->|出力可| D[メッセージフォーマット]
    D --> E[タイムスタンプ付加]
    E --> F{ロガー種別}
    F -->|Console| G[コンソール出力]
    F -->|File| H[バッファに追加]
    F -->|Multiplex| I[各ロガーに転送]
    H --> J{ファイルサイズ確認}
    J -->|5MB超過| K[バックアップ作成]
    J -->|5MB以下| L[ファイル書き込み]
    K --> L
    G --> M[完了]
    L --> M
    I --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-51-01 | ログレベルフィルタリング | 設定されたログレベル以上のログのみ出力 | 常時 |
| BR-51-02 | ファイルローテーション | 5MBを超えたログファイルは自動でバックアップ | ファイルログ使用時 |
| BR-51-03 | エラーオブジェクト変換 | Errorオブジェクトはスタックトレースに変換 | error()メソッド呼び出し時 |
| BR-51-04 | デフォルトログレベル | 明示的な指定がない場合はInfoレベル | 初期化時 |

### 計算ロジック

```typescript
// ログ出力可否判定
function canLog(loggerLevel: LogLevel, messageLevel: LogLevel): boolean {
  return loggerLevel !== LogLevel.Off && loggerLevel <= messageLevel;
}

// バックアップファイル名生成（ローテーション）
function getBackupResource(): URI {
  this.backupIndex = this.backupIndex > 5 ? 1 : this.backupIndex;
  return joinPath(dirname(this.resource), `${basename(this.resource)}_${this.backupIndex++}`);
}
```

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

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

該当なし（ファイルシステムのみ使用）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FILE_MODIFIED_SINCE | ファイル競合 | ログファイル作成時に既存ファイルが変更された | エラーを無視して続行 |
| ENCRYPTION_ERROR | 暗号化エラー | ログ内容の暗号化に失敗 | エラーをログ出力し、処理継続 |
| WRITE_ERROR | 書き込みエラー | ファイルへの書き込みに失敗 | バッファに保持し、リトライ |

### リトライ仕様

ファイル書き込みは100msのスロットリングでバッファリングされ、短時間の連続書き込みを最適化する。

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

該当なし（ログ出力はベストエフォート）

## パフォーマンス要件

- ログ出力によるメインスレッドのブロッキングを最小化
- ファイル書き込みは非同期で実行
- 100msのスロットリングでI/O負荷を軽減

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

- PIIパスは自動的にマスク処理（テレメトリ連携時）
- ログファイルはユーザーのlogsフォルダに保存
- 機密情報（パスワード等）はログに出力しない設計

## 備考

- spdlogライブラリを使用する場合、ネイティブモジュールのビルドが必要
- ブラウザ環境ではコンソールログのみ利用可能

---

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

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

### 推奨読解順序

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

ログ機能の基盤となるインターフェースとEnum定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | log.ts | `src/vs/platform/log/common/log.ts` | ILogger、ILogService、LogLevel enumの定義 |

**読解のコツ**:
- LogLevel enumは0(Off)から5(Error)までの数値で定義され、数値が小さいほど詳細なログとなる
- ILoggerインターフェースはDisposableを継承しており、リソース管理が組み込まれている

**主要処理フロー**:
1. **32-39行目**: LogLevel enumの定義（Off, Trace, Debug, Info, Warning, Error）
2. **43-58行目**: ILoggerインターフェース定義（trace, debug, info, warn, errorメソッド）
3. **60-62行目**: canLog関数 - ログ出力可否判定ロジック
4. **103-105行目**: ILogServiceインターフェース（サービスブランド付き）

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

ログサービスの実装クラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | logService.ts | `src/vs/platform/log/common/logService.ts` | LogServiceクラスの実装 |

**主要処理フロー**:
1. **10-20行目**: LogServiceクラス - MultiplexLoggerを使用して複数ロガーを統合
2. **16-19行目**: コンストラクタ - primaryLoggerとotherLoggersを組み合わせ
3. **26-28行目**: setLevel - 全ロガーのレベルを一括設定

#### Step 3: 抽象ロガークラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | log.ts | `src/vs/platform/log/common/log.ts` | AbstractLogger、AbstractMessageLoggerクラス |

**主要処理フロー**:
- **256-290行目**: AbstractLogger - ログレベル管理とイベント発火の基底クラス
- **292-341行目**: AbstractMessageLogger - メッセージフォーマット処理を含む抽象クラス
- **76-96行目**: format関数 - 引数をフォーマットする共通処理

#### Step 4: 具体的なロガー実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | log.ts (ConsoleLogger) | `src/vs/platform/log/common/log.ts` | コンソール出力ロガー |
| 4-2 | fileLog.ts | `src/vs/platform/log/common/fileLog.ts` | ファイル出力ロガー |

**主要処理フロー（ConsoleLogger）**:
- **344-408行目**: ConsoleMainLogger - メインプロセス用（ANSIカラー対応）
- **410-471行目**: ConsoleLogger - ブラウザ用（CSSカラー対応）

**主要処理フロー（FileLogger）**:
- **16-103行目**: FileLogger - ファイル出力の実装
- **35-50行目**: flush() - バッファ内容をファイルに書き込み、ローテーション処理
- **62-69行目**: log() - タイムスタンプ付きでバッファに追加

#### Step 5: ロガーサービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | log.ts (AbstractLoggerService) | `src/vs/platform/log/common/log.ts` | ロガー管理サービス |

**主要処理フロー**:
- **585-737行目**: AbstractLoggerService - ロガーの登録・管理・可視性制御
- **624-649行目**: createLogger - ロガーの作成と登録
- **655-677行目**: setLogLevel - 個別/全体のログレベル設定
- **696-706行目**: registerLogger - ロガーの登録とイベント発火

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

```
LogService (サービスエントリポイント)
    │
    ├─ MultiplexLogger (複数ロガー統合)
    │      │
    │      ├─ ConsoleMainLogger (メインプロセス)
    │      │      └─ console.log/warn/error
    │      │
    │      ├─ ConsoleLogger (ブラウザ)
    │      │      └─ console.log/warn/error
    │      │
    │      └─ FileLogger (ファイル出力)
    │             │
    │             ├─ ThrottledDelayer (バッファリング)
    │             └─ IFileService (ファイル書き込み)
    │
    └─ AbstractLoggerService (ロガー管理)
           │
           ├─ ResourceMap (ロガー登録管理)
           └─ Emitter (イベント通知)
```

### データフロー図

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

ログメソッド呼び出し
    │
    ↓
┌───────────────┐
│ LogService    │
│  .info()      │
│  .error()     │
└───────────────┘
    │
    ↓
┌───────────────┐
│MultiplexLogger│──────┐
└───────────────┘      │
    │                  │
    ├──────────────────┼──────────────────┐
    ↓                  ↓                  ↓
┌──────────┐    ┌──────────┐    ┌──────────┐
│Console   │    │Console   │    │File      │
│MainLogger│    │Logger    │    │Logger    │
└──────────┘    └──────────┘    └──────────┘
    │                │                │
    ↓                ↓                ↓
[コンソール]    [ブラウザ        [ログファイル]
 (ANSI色)      コンソール]       (5MB制限)
               (CSS色)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| log.ts | `src/vs/platform/log/common/log.ts` | ソース | 主要インターフェース・クラス定義 |
| logService.ts | `src/vs/platform/log/common/logService.ts` | ソース | LogServiceの実装 |
| fileLog.ts | `src/vs/platform/log/common/fileLog.ts` | ソース | ファイルログ実装 |
| bufferLog.ts | `src/vs/platform/log/common/bufferLog.ts` | ソース | バッファリングロガー |
| logIpc.ts | `src/vs/platform/log/common/logIpc.ts` | ソース | IPC経由のログ転送 |
| spdlogLog.ts | `src/vs/platform/log/node/spdlogLog.ts` | ソース | spdlogネイティブライブラリ連携 |
| loggerService.ts | `src/vs/platform/log/node/loggerService.ts` | ソース | Node.js用ロガーサービス |
| log.ts | `src/vs/platform/log/browser/log.ts` | ソース | ブラウザ用ログ実装 |
