# 通知設計書 11-$/setTrace

## 概要

本ドキュメントは、LSP標準通知 `$/setTrace` の設計仕様を定義する。この通知はクライアント（エディタ）からサーバー（serve-d）に送信され、サーバーのトレースレベル（ログ出力詳細度）を動的に変更する。

### 本通知の処理概要

`$/setTrace` 通知は、LSPクライアントがサーバーのログ出力レベルをランタイムで変更するために使用される通知である。受信したトレースレベルに応じて、サーバーのグローバルログレベルを `trace`（詳細）または `info`（通常）に切り替える。

**業務上の目的・背景**：LSPサーバーの動作中に問題が発生した場合、開発者はサーバーのログ出力を詳細化して原因を調査する必要がある。この通知により、サーバーを再起動することなくログレベルを動的に変更でき、デバッグ効率を大幅に向上させる。LSP仕様で標準化された通知であり、すべてのLSPクライアントが利用可能である。

**通知の送信タイミング**：クライアント側でユーザーがトレースレベル設定を変更したとき（例：VS Codeの `"serve-d.trace.server"` 設定変更時）に送信される。サーバー初期化後の任意のタイミングで送信可能である。

**通知の受信者**：serve-dサーバープロセスが受信者である。extension.d モジュールの `setTrace` 関数がハンドラとして登録されている。

**通知内容の概要**：`SetTraceParams` 構造体が送信され、`value` フィールドに `TraceValue` 列挙型（`off`、`messages`、`verbose`）の値が格納される。

**期待されるアクション**：サーバーは受信したトレースレベルに基づき、`verbose` の場合は `LogLevel.trace` に、それ以外の場合は `LogLevel.info` にグローバルログレベルを変更する。これにより、以降のログ出力の詳細度が即座に変更される。

## 通知種別

LSPプロトコル通知（JSON-RPC notification）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（JSON-RPC notification） |
| 優先度 | 低 |
| リトライ | 無し（通知のため応答なし） |

### 送信先決定ロジック

クライアントからサーバーへの一方向通知であり、送信先はLSP接続で確立されたサーバープロセスに固定される。

## 通知テンプレート

### JSON-RPC通知メッセージ

| 項目 | 内容 |
|-----|------|
| メソッド名 | `$/setTrace` |
| パラメータ型 | `SetTraceParams` |
| レスポンス | なし（通知） |

### メッセージ構造

```json
{
  "jsonrpc": "2.0",
  "method": "$/setTrace",
  "params": {
    "value": "verbose"
  }
}
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| value | トレースレベル（"off" / "messages" / "verbose"） | クライアント設定 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | クライアント側のトレース設定変更 | サーバー初期化済み | ユーザーがエディタの設定でトレースレベルを変更した場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| サーバー未初期化 | `initialize` リクエスト完了前は処理されない（processNotifyで無視） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[クライアント: トレース設定変更] --> B[JSON-RPC通知送信]
    B --> C[サーバー: processNotify受信]
    C --> D{serverInitializeCalled?}
    D -->|No| E[通知無視]
    D -->|Yes| F[setTrace関数呼び出し]
    F --> G{value == verbose?}
    G -->|Yes| H[globalLogLevel = LogLevel.trace]
    G -->|No| I[globalLogLevel = LogLevel.info]
    H --> J[終了]
    I --> J
    E --> J
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（データベースを使用しない）。

### 更新テーブル一覧

該当なし（データベースを使用しない）。インメモリのグローバル変数 `globalLogLevel` のみ更新される。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 初期化前通知 | サーバー初期化前に受信 | 通知を無視しログ出力 |
| 不正なパラメータ | SetTraceParamsのデシリアライズ失敗 | MethodExceptionがprocessNotifyでキャッチされエラーログ出力 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。サーバー稼働中の任意のタイミングで受信可能。

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

- 個人情報は含まれない
- ログレベルの変更はサーバープロセス内部の状態変更のみであり、外部への影響はない
- `verbose` モードでは詳細なログが出力されるため、ソースコードの内容などがログに記録される可能性がある

## 備考

- LSP仕様（3.17）で定義された標準通知
- `initialize` リクエストの `trace` パラメータでも初期トレースレベルが設定可能（extension.d L233-234）
- `off` と `messages` は同じ動作（`LogLevel.info`）として処理される。serve-dの実装では `verbose` のみが特別扱いされる

---

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

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

### 推奨読解順序

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

まず、通知パラメータとして使用されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protocol.d | `protocol/source/served/lsp/protocol.d` | `TraceValue` 列挙型（L4169-4174）と `SetTraceParams` 構造体（L4176-4181）の定義 |

**読解のコツ**: `@serdeEnumProxy!string` はmir.serdeライブラリのアトリビュートで、列挙型を文字列としてJSON(de)serializeすることを指示する。`@serdeFallbackStruct` はデシリアライズ時に未知フィールドを無視する。

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

通知ハンドラの登録と呼び出しの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | serverbase.d | `serverbase/source/served/serverbase.d` | `processNotify` 関数（L348-387）が通知を受け取りディスパッチする仕組み |

**主要処理フロー**:
1. **L354**: `exit` 通知か `shutdownRequested` の場合はRPCを停止
2. **L366-369**: サーバー未初期化の場合は無視
3. **L371**: ドキュメント管理に通知を渡す
4. **L373-383**: `@protocolNotification` アトリビュートに基づいてハンドラ関数を呼び出す

#### Step 3: ハンドラ実装を理解する

実際の `$/setTrace` ハンドラ実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | extension.d | `source/served/extension.d` | `setTrace` 関数（L1092-1099）の実装 |

**主要処理フロー**:
- **L1092**: `@protocolNotification("$/setTrace")` でハンドラとして登録
- **L1093**: `SetTraceParams` をパラメータとして受け取る
- **L1095-1096**: `value` が `verbose` の場合、`globalLogLevel` を `LogLevel.trace` に設定
- **L1097-1098**: それ以外の場合、`globalLogLevel` を `LogLevel.info` に設定

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

```
[JSON-RPC受信] processNotify (serverbase.d:348)
    |
    +-- documents.process (テキストドキュメント処理)
    |
    +-- eventProcessor.emitProtocol (protocolNotification dispatch)
            |
            +-- setTrace (extension.d:1093)
                    |
                    +-- globalLogLevel = LogLevel.trace / LogLevel.info
```

### データフロー図

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

SetTraceParams          setTrace()                   globalLogLevel
  .value: TraceValue --> (extension.d:1093-1099) --> (std.experimental.logger)
    "verbose"            TraceValue判定                 LogLevel.trace
    "off"/"messages"                                    LogLevel.info
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| protocol.d | `protocol/source/served/lsp/protocol.d` | ソース | SetTraceParams/TraceValue の型定義 |
| extension.d | `source/served/extension.d` | ソース | setTrace ハンドラ実装 |
| serverbase.d | `serverbase/source/served/serverbase.d` | ソース | 通知ディスパッチ（processNotify） |
