# 機能設計書 52-テレメトリ

## 概要

本ドキュメントは、VS Codeのテレメトリ（使用状況収集）機能に関する設計書である。製品改善のための使用状況データ、エラー情報、クラッシュレポートの収集・送信を行い、ユーザーのプライバシーを保護しながら製品品質向上に貢献する。

### 本機能の処理概要

**業務上の目的・背景**：
VS Codeの品質向上と機能改善のため、使用状況データの収集が必要である。どの機能がよく使われているか、どのようなエラーが発生しているか、パフォーマンスの問題はないかなど、実際のユーザー環境からのフィードバックを収集することで、開発チームが効果的な改善を行うことができる。GDPRを含むプライバシー規制に準拠した設計となっている。

**機能の利用シーン**：
- 機能の使用頻度を分析して優先順位を決定する際
- エラー発生パターンを特定してバグ修正を行う際
- パフォーマンス問題を検出して最適化を行う際
- A/Bテストの実験結果を収集する際
- クラッシュレポートを収集してクリティカルな問題を特定する際

**主要な処理内容**：
1. テレメトリイベントの記録（publicLog、publicLog2）
2. エラーテレメトリの送信（publicLogError、publicLogError2）
3. テレメトリレベルの管理（Off, Crash, Error, Usage）
4. PII（個人識別情報）の自動削除・マスク処理
5. 共通プロパティ（マシンID、セッションIDなど）の付与
6. 実験プロパティのバッファリングと遅延送信

**関連システム・外部連携**：
- 1DS（One Data Strategy）: Microsoftのテレメトリバックエンド
- Application Insights: エラー・クラッシュ収集サービス
- 設定サービス（IConfigurationService）: テレメトリレベル設定

**権限による制御**：
ユーザーは設定画面またはsettings.jsonでテレメトリレベルを制御可能。組織ポリシーによる一括制御もサポートされている。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 設定エディタ | 参照画面 | telemetry.telemetryLevel設定の編集 |

## 機能種別

データ連携 / 外部送信 / プライバシー管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| eventName | string | Yes | テレメトリイベント名 | 空文字列不可 |
| data | ITelemetryData | No | イベントに付随するデータ | PII除去処理適用 |
| endpoint | ITelemetryEndpoint | No | カスタムエンドポイント | aiKey必須 |

### 入力データソース

- アプリケーションコードからの直接呼び出し
- 拡張機能からのAPI経由呼び出し
- エラーハンドラからの自動送信
- 設定ファイル（telemetry.telemetryLevel）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| telemetryEvent | object | 共通プロパティ付きのテレメトリイベント |
| sessionId | string | セッション識別子 |
| machineId | string | マシン識別子（ハッシュ化） |
| sqmId | string | SQM識別子 |

### 出力先

- 1DS（One Data Strategy）バックエンド
- Application Insights
- ログアペンダー（デバッグ用）

## 処理フロー

### 処理シーケンス

```
1. テレメトリメソッド呼び出し（publicLog/publicLogError）
   └─ イベント名とデータを受け取る
2. テレメトリレベルチェック
   └─ 現在の設定レベルと比較し、送信可否を判定
3. 実験プロパティ待機（設定時）
   └─ 最大10秒間バッファリング
4. PIIクリーンアップ
   └─ ファイルパス、ユーザー名等を削除
5. 共通プロパティ付与
   └─ machineId、sessionId等を追加
6. アペンダーへの送信
   └─ 設定されたすべてのアペンダーにログ送信
```

### フローチャート

```mermaid
flowchart TD
    A[publicLog呼び出し] --> B{テレメトリレベルチェック}
    B -->|レベル不足| C[処理終了]
    B -->|レベルOK| D{実験プロパティ設定済み?}
    D -->|No| E[バッファに追加]
    D -->|Yes| F[PIIクリーンアップ]
    E --> G{10秒経過 or 設定完了?}
    G -->|No| E
    G -->|Yes| F
    F --> H[共通プロパティ付与]
    H --> I[アペンダーに送信]
    I --> J[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-01 | テレメトリレベル制御 | 設定されたレベル以上のイベントのみ送信 | 常時 |
| BR-52-02 | PII自動削除 | ファイルパス等の個人情報を自動削除 | データ送信前 |
| BR-52-03 | バッファリング | 実験プロパティ設定まで最大10秒バッファ | waitForExperimentProperties有効時 |
| BR-52-04 | バッファ上限 | 最大1000イベントまでバッファリング | バッファリング時 |
| BR-52-05 | エラーテレメトリ制御 | sendErrorTelemetryフラグで制御 | publicLogError呼び出し時 |

### 計算ロジック

```typescript
// テレメトリレベル判定
function telemetryLevelEnabled(service: ITelemetryService, level: TelemetryLevel): boolean {
  return service.telemetryLevel >= level;
}

// テレメトリレベル定義
enum TelemetryLevel {
  NONE = 0,   // オフ
  CRASH = 1,  // クラッシュレポートのみ
  ERROR = 2,  // エラー + クラッシュ
  USAGE = 3   // すべて（使用状況 + エラー + クラッシュ）
}
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| セッション日付保存 | storage | INSERT/UPDATE | firstSessionDate、lastSessionDateの保存 |
| マシンID保存 | storage | INSERT/UPDATE | machineId、sqmIdの永続化 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NETWORK_ERROR | ネットワークエラー | テレメトリ送信失敗 | サイレントに失敗（ユーザー通知なし） |
| ENCRYPTION_ERROR | 暗号化エラー | PII暗号化失敗 | イベントを破棄 |

### リトライ仕様

テレメトリ送信は「ベストエフォート」であり、失敗時のリトライは行わない。

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

該当なし（非同期送信）

## パフォーマンス要件

- テレメトリ送信によるUIブロッキングの防止
- バッファリングによる送信の最適化
- 10秒のタイムアウトで実験プロパティ待機を打ち切り

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

- GDPRに準拠したデータ収集
- PII（個人識別情報）の自動削除
- ファイルパスの匿名化（vscode-file://パターンの削除）
- ユーザーによるオプトアウト可能
- 組織ポリシーによる一括制御

## 備考

- 非推奨のtelemetry.enableTelemetry設定もまだサポート
- 拡張機能のテレメトリは拡張機能ごとに制御可能
- サードパーティ拡張機能はこの設定を尊重しない場合がある

---

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

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

### 推奨読解順序

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

テレメトリのインターフェースと型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | telemetry.ts | `src/vs/platform/telemetry/common/telemetry.ts` | ITelemetryService、TelemetryLevel定義 |
| 1-2 | gdprTypings.ts | `src/vs/platform/telemetry/common/gdprTypings.ts` | GDPR型定義（ClassifiedEvent等） |

**読解のコツ**:
- TelemetryLevelは数値enumで、NONE(0) < CRASH(1) < ERROR(2) < USAGE(3)の順序
- publicLog2/publicLogError2はTypeScript型安全なGDPR対応メソッド

**主要処理フロー**:
1. **17-54行目**: ITelemetryServiceインターフェース定義
2. **56-58行目**: telemetryLevelEnabled関数
3. **89-94行目**: TelemetryLevel enum定義
4. **96-101行目**: TelemetryConfiguration enum（設定値）

#### Step 2: テレメトリサービスの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | telemetryService.ts | `src/vs/platform/telemetry/common/telemetryService.ts` | TelemetryServiceの完全実装 |

**主要処理フロー**:
1. **39-119行目**: TelemetryServiceクラスのコンストラクタとプロパティ
2. **121-128行目**: setExperimentProperty - 実験プロパティ設定とバッファフラッシュ
3. **130-147行目**: _flushPendingEvents - バッファされたイベントの一括送信
4. **149-161行目**: _updateTelemetryLevel - 設定変更時のレベル更新
5. **177-192行目**: _log - 内部ログ処理（バッファリング制御）
6. **194-206行目**: _doLog - 実際のログ送信処理

#### Step 3: データクリーンアップを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | telemetryUtils.ts | `src/vs/platform/telemetry/common/telemetryUtils.ts` | cleanData、getTelemetryLevel関数 |

**読解のコツ**:
- cleanData関数は正規表現パターンでPIIを除去
- vscode-file://パスは自動的に削除される

#### Step 4: アペンダーの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | 1dsAppender.ts | `src/vs/platform/telemetry/common/1dsAppender.ts` | 1DS送信アペンダー |
| 4-2 | telemetryLogAppender.ts | `src/vs/platform/telemetry/common/telemetryLogAppender.ts` | ログ出力アペンダー |

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

```
TelemetryService (サービスエントリポイント)
    │
    ├─ publicLog() / publicLog2()
    │      │
    │      └─ _log()
    │             │
    │             ├─ (バッファリング判定)
    │             │      └─ _pendingEvents.push()
    │             │
    │             └─ _doLog()
    │                    │
    │                    ├─ mixin(experimentProperties)
    │                    ├─ cleanData(piiPatterns)
    │                    ├─ mixin(commonProperties)
    │                    │
    │                    └─ appender.log()
    │                           │
    │                           ├─ 1dsAppender (1DS送信)
    │                           └─ TelemetryLogAppender (ログ出力)
    │
    ├─ publicLogError() / publicLogError2()
    │      └─ (同上、ERROR レベルで送信)
    │
    └─ setExperimentProperty()
           └─ _flushPendingEvents()
```

### データフロー図

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

publicLog()
    │
    ↓
┌───────────────┐
│TelemetryLevel │
│   チェック    │──────→ 送信不可 → 終了
└───────────────┘
    │OK
    ↓
┌───────────────┐
│ バッファリング │←─── waitForExperimentProperties
└───────────────┘
    │
    ↓
┌───────────────┐
│ PIIクリーンアップ│
│ (cleanData)    │
└───────────────┘
    │
    ↓
┌───────────────┐
│共通プロパティ  │
│  付与(mixin)   │
└───────────────┘
    │
    ├──────────────────┐
    ↓                  ↓
┌──────────┐    ┌──────────┐
│1dsAppender│    │LogAppender│
└──────────┘    └──────────┘
    │                │
    ↓                ↓
[1DSバックエンド] [ローカルログ]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| telemetry.ts | `src/vs/platform/telemetry/common/telemetry.ts` | ソース | インターフェース定義 |
| telemetryService.ts | `src/vs/platform/telemetry/common/telemetryService.ts` | ソース | サービス実装・設定登録 |
| telemetryUtils.ts | `src/vs/platform/telemetry/common/telemetryUtils.ts` | ソース | ユーティリティ関数 |
| gdprTypings.ts | `src/vs/platform/telemetry/common/gdprTypings.ts` | ソース | GDPR型定義 |
| 1dsAppender.ts | `src/vs/platform/telemetry/common/1dsAppender.ts` | ソース | 1DS送信アペンダー |
| telemetryLogAppender.ts | `src/vs/platform/telemetry/common/telemetryLogAppender.ts` | ソース | ログアペンダー |
| commonProperties.ts | `src/vs/platform/telemetry/common/commonProperties.ts` | ソース | 共通プロパティ定義 |
| errorTelemetry.ts | `src/vs/platform/telemetry/common/errorTelemetry.ts` | ソース | エラーテレメトリ |
