# 機能設計書 28-console

## 概要

本ドキュメントは、Node.jsのconsoleモジュールの機能設計について記述する。consoleモジュールは、標準出力（stdout）と標準エラー出力（stderr）への出力機能を提供し、デバッグやロギングのための基本的なコンソール操作を実現する。WHATWG Console Standardに準拠した実装となっている。

### 本機能の処理概要

**業務上の目的・背景**：consoleモジュールは、アプリケーションのデバッグ、ロギング、パフォーマンス計測のための標準的な出力機能を提供する。ブラウザのconsole APIとの互換性を持ちながら、Node.js固有の拡張機能も提供する。

**機能の利用シーン**：
- アプリケーションのデバッグ出力を行う際
- ログメッセージを出力する際
- 処理時間を計測する際
- オブジェクトの内容を検査する際
- テーブル形式でデータを表示する際
- アサーションによる検証を行う際

**主要な処理内容**：
1. `console.log(...args)` - 標準出力にメッセージを出力
2. `console.error(...args)` / `console.warn(...args)` - 標準エラー出力にメッセージを出力
3. `console.info(...args)` / `console.debug(...args)` - 標準出力にメッセージを出力
4. `console.dir(obj, options)` - オブジェクトを検査して出力
5. `console.time(label)` / `console.timeEnd(label)` / `console.timeLog(label)` - 時間計測
6. `console.count(label)` / `console.countReset(label)` - カウンター
7. `console.group()` / `console.groupEnd()` - グループ化とインデント
8. `console.table(data, properties)` - テーブル形式での出力
9. `console.trace(...args)` - スタックトレースの出力
10. `console.assert(expression, ...args)` - アサーション
11. `console.clear()` - コンソールのクリア
12. `new Console(options)` - カスタムコンソールインスタンスの作成

**関連システム・外部連携**：
- internal/console/constructor - Consoleクラスの実装
- internal/console/global - グローバルconsoleオブジェクト
- internal/util/inspect - オブジェクト検査
- diagnostics_channel - console.log等のイベント購読

**権限による制御**：特になし。すべての機能は任意のユーザーコードから利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本モジュールはAPI機能であり、関連する画面はありません |

## 機能種別

デバッグ支援 / ロギング / 開発者ツール

## 入力仕様

### 入力パラメータ

#### console.log / console.error / console.warn / console.info / console.debug

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ...args | any[] | No | 出力するメッセージまたは値 | - |

#### console.dir

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| object | any | Yes | 検査するオブジェクト | - |
| options | Object | No | inspectオプション | validateObject |

#### console.time / console.timeEnd / console.timeLog

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | string | No | タイマーラベル（デフォルト: 'default'） | - |

#### console.count / console.countReset

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| label | string | No | カウンターラベル（デフォルト: 'default'） | 文字列に変換 |

#### console.table

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tabularData | Object/Array | Yes | 表形式で表示するデータ | - |
| properties | string[] | No | 表示するプロパティの配列 | validateArray |

#### console.assert

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| expression | any | Yes | 評価する式 | - |
| ...args | any[] | No | 失敗時のメッセージ | - |

#### new Console(options)

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| stdout | WritableStream | Yes | 標準出力ストリーム | write関数の存在確認 |
| stderr | WritableStream | No | 標準エラー出力ストリーム（デフォルト: stdout） | write関数の存在確認 |
| ignoreErrors | boolean | No | エラーを無視するか（デフォルト: true） | - |
| colorMode | 'auto' \| true \| false | No | カラー出力モード（デフォルト: 'auto'） | validateOneOf |
| inspectOptions | Object | No | inspect関数のオプション | validateObject |
| groupIndentation | number | No | グループインデント幅（デフォルト: 2） | validateInteger(0-1000) |

### 入力データソース

プログラムコードからの直接呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| console.log等の出力 | string | フォーマットされた文字列 + 改行 |
| console.time系の出力 | string | 「label: Xms」形式 |
| console.count出力 | string | 「label: N」形式 |
| console.table出力 | string | テーブル形式の文字列 |

### 出力先

- stdout: log, info, debug, dir, table, time系, count系, group
- stderr: error, warn, trace, assert

## 処理フロー

### 処理シーケンス

```
1. メソッド呼び出し
   └─ diagnostics_channel通知（購読者がいる場合）
2. 引数のフォーマット
   └─ formatWithOptionsで文字列化
3. グループインデントの適用
   └─ 改行を含む場合は各行にインデント追加
4. ストリームへの書き込み
   └─ ignoreErrorsに応じたエラー処理
```

### フローチャート

```mermaid
flowchart TD
    A[console.logなど呼び出し] --> B{購読者あり?}
    B -->|はい| C[diagnostics_channel通知]
    B -->|いいえ| D[引数フォーマット]
    C --> D
    D --> E[kFormatForStdout/Stderr]
    E --> F[kWriteToConsole]
    F --> G{グループインデントあり?}
    G -->|はい| H[インデント適用]
    G -->|いいえ| I[改行追加]
    H --> I
    I --> J{ignoreErrors?}
    J -->|true| K[エラーを無視して書き込み]
    J -->|false| L[通常書き込み]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | カラー自動判定 | colorMode='auto'時はストリームがTTYかで判定 | colorMode='auto' |
| BR-002 | エラー無視 | ignoreErrors=trueでストリームエラーを無視 | デフォルト |
| BR-003 | グループインデント | group()でインデント追加、groupEnd()で削除 | group系メソッド |
| BR-004 | タイマーラベル | 未定義のラベルでtimeEnd/timeLogを呼ぶと警告 | time系メソッド |
| BR-005 | カウンターラベル | 未定義のラベルでcountResetを呼ぶと警告 | countReset |
| BR-006 | clear動作条件 | stdoutがTTYでTERM!='dumb'の場合のみ動作 | clear() |

### 計算ロジック

#### フォーマット処理（kFormatForStdout/kFormatForStderr）
1. 単一の文字列引数の場合は高速パス（フォーマット処理をスキップ）
2. inspectOptionsを取得
3. formatWithOptionsで引数をフォーマット

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

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

本モジュールはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_CONSOLE_WRITABLE_STREAM | TypeError | stdout/stderrがwritable streamでない | write関数を持つストリームを渡す |
| ERR_INCOMPATIBLE_OPTION_PAIR | TypeError | inspectOptions.colorsとcolorModeの両方指定 | どちらか一方のみ指定 |
| 警告（process.emitWarning） | Warning | 未定義のカウンターラベルをリセット | count()で先にカウントを開始 |
| 警告（process.emitWarning） | Warning | 未定義のタイマーラベルでtimeEnd/timeLog | time()で先にタイマーを開始 |

### リトライ仕様

リトライ処理は行わない。ignoreErrors=trueの場合、書き込みエラーは無視される。

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

トランザクション処理は行わない。

## パフォーマンス要件

- cliTable（console.table用）は遅延ロード
- utilColorsは遅延ロード
- 単一文字列引数の場合は高速パス処理

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

特になし。標準出力への出力機能のため。

## 備考

- グローバルconsoleはprocess.stdout/process.stderrを遅延バインド
- diagnostics_channelで'console.log'、'console.warn'等を購読可能
- dirxmlはlogのエイリアス
- groupCollapsedはgroupのエイリアス
- console.ConsoleでConsoleコンストラクタにアクセス可能（後方互換性）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | console.js | `lib/console.js` | モジュールエントリーポイント（24行目） |
| 1-2 | global.js | `lib/internal/console/global.js` | グローバルconsoleの生成（27-51行目） |

**読解のコツ**: console.jsはinternal/console/globalをre-exportするだけ。global.jsでグローバルconsoleオブジェクトを生成し、Console.prototypeのメソッドをバインドしている。

#### Step 2: Consoleクラスのコンストラクタを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | constructor.js | `lib/internal/console/constructor.js` | Consoleコンストラクタ（102-174行目） |

**主要処理フロー**:
- **106-108行目**: new.target判定でコンストラクタとして呼び出し
- **110-116行目**: 旧シグネチャ（stdout, stderr, ignoreErrors）への対応
- **118-125行目**: オプションの分割代入
- **127-132行目**: stdout/stderrのバリデーション
- **134行目**: colorModeのバリデーション
- **136-139行目**: groupIndentationのバリデーション（0-1000）
- **141-158行目**: inspectOptionsの処理
- **160-170行目**: prototypeメソッドのバインド
- **172-173行目**: ストリームとプロパティのバインド

#### Step 3: 出力メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | constructor.js | `lib/internal/console/constructor.js` | consoleMethods（411-666行目） |

**主要処理フロー**:
- **412-417行目**: log() - diagnostics_channel通知、kFormatForStdout、kWriteToConsole
- **433-438行目**: warn() - stderrへ出力
- **440-445行目**: error() - stderrへ出力
- **447-453行目**: dir() - inspectでオブジェクト検査

#### Step 4: 時間計測メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | constructor.js | `lib/internal/console/constructor.js` | time/timeEnd/timeLog（455-465行目） |

**主要処理フロー**:
- **455-457行目**: time() - internal/util/debuglogのtime関数を使用
- **459-461行目**: timeEnd() - timeLogImpl経由で結果を出力
- **463-465行目**: timeLog() - 追加データ付きで経過時間を出力

#### Step 5: カウンター・グループメソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | constructor.js | `lib/internal/console/constructor.js` | count/countReset（506-530行目） |
| 5-2 | constructor.js | `lib/internal/console/constructor.js` | group/groupEnd（532-551行目） |

**主要処理フロー**:
- **506-519行目**: count() - kCountsマップでカウント管理、trace_events記録
- **522-530行目**: countReset() - 存在しないラベルは警告
- **532-540行目**: group() - kGroupIndentationStringにスペース追加
- **542-551行目**: groupEnd() - インデント文字列を削除

#### Step 6: テーブル出力を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | constructor.js | `lib/internal/console/constructor.js` | table（554-665行目） |

**主要処理フロー**:
- **558-559行目**: null/非オブジェクトはlogで出力
- **561行目**: cliTableの遅延ロード
- **580-628行目**: Map/Set/Iteratorの処理
- **630-664行目**: 通常オブジェクト/配列の処理

#### Step 7: 内部ヘルパーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 7-1 | constructor.js | `lib/internal/console/constructor.js` | kWriteToConsole（282-324行目） |
| 7-2 | constructor.js | `lib/internal/console/constructor.js` | kFormatForStdout/kFormatForStderr（346-379行目） |
| 7-3 | constructor.js | `lib/internal/console/constructor.js` | kGetInspectOptions（325-345行目） |

**主要処理フロー**:
- **282-324行目**: kWriteToConsole - グループインデント適用、エラーハンドリング
- **346-361行目**: kFormatForStdout - 単一文字列の高速パス、formatWithOptions呼び出し
- **325-345行目**: kGetInspectOptions - カラーモード判定、inspectOptions取得

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

```
lib/console.js
    │
    └─ require('internal/console/global') [24行目]
           │
           └─ lib/internal/console/global.js
                  │
                  ├─ require('internal/console/constructor') [22-25行目]
                  │
                  ├─ globalConsole生成 [27行目]
                  │
                  ├─ Console.prototypeメソッドをバインド [34-43行目]
                  │
                  └─ kBindProperties呼び出し [45行目]

lib/internal/console/constructor.js
    │
    ├─ Console コンストラクタ [102-174行目]
    │      ├─ kBindStreamsEager [172行目]
    │      └─ kBindProperties [173行目]
    │
    ├─ consoleMethods [411-666行目]
    │      ├─ log() [412-417行目]
    │      │      ├─ diagnostics_channel publish
    │      │      ├─ kFormatForStdout [346-361行目]
    │      │      └─ kWriteToConsole [282-324行目]
    │      │
    │      ├─ warn()/error() [433-445行目]
    │      │      ├─ diagnostics_channel publish
    │      │      ├─ kFormatForStderr [363-379行目]
    │      │      └─ kWriteToConsole (stderr)
    │      │
    │      ├─ dir() [447-453行目]
    │      │      └─ inspect (internal/util/inspect)
    │      │
    │      ├─ time/timeEnd/timeLog [455-465行目]
    │      │      └─ internal/util/debuglog
    │      │
    │      ├─ count/countReset [506-530行目]
    │      │      └─ trace (internalBinding)
    │      │
    │      ├─ group/groupEnd [532-551行目]
    │      │
    │      └─ table [554-665行目]
    │             └─ internal/cli_table
    │
    └─ module.exports [714-719行目]
           ├─ Console
           ├─ kBindStreamsLazy
           ├─ kBindProperties
           └─ initializeGlobalConsole
```

### データフロー図

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

args ───▶ console.log ───▶ stdout
                │
                ├── diagnostics_channel通知
                ├── kFormatForStdout (フォーマット)
                └── kWriteToConsole (グループインデント適用)

args ───▶ console.error ───▶ stderr
                │
                ├── diagnostics_channel通知
                ├── kFormatForStderr
                └── kWriteToConsole

label ───▶ console.time ───▶ _times Map (タイマー開始)
label ───▶ console.timeEnd ───▶ stdout (経過時間)
label ───▶ console.count ───▶ stdout (カウント値)
                │
                └── kCounts Map (カウント管理)

tabularData ───▶ console.table ───▶ stdout (テーブル形式)
                       │
                       └── internal/cli_table
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| console.js | `lib/console.js` | ソース | モジュールエントリーポイント |
| global.js | `lib/internal/console/global.js` | ソース | グローバルconsoleオブジェクト |
| constructor.js | `lib/internal/console/constructor.js` | ソース | Consoleクラス実装 |
| inspect.js | `lib/internal/util/inspect.js` | ソース | オブジェクト検査 |
| debuglog.js | `lib/internal/util/debuglog.js` | ソース | time/timeEnd/timeLog実装 |
| cli_table.js | `lib/internal/cli_table.js` | ソース | テーブル形式出力 |
| colors.js | `lib/internal/util/colors.js` | ソース | カラー判定 |
| validators.js | `lib/internal/validators.js` | ソース | バリデーション |
