# 機能設計書 153-Get-DbaWindowsLog

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける `Get-DbaWindowsLog` コマンドレットの機能設計を記述する。本機能は、SQL Serverエラーログファイルをファイルシステムから直接読み取り、解析してトラブルシューティングや分析に使用できる構造化されたデータとして出力する機能である。

### 本機能の処理概要

SQL Serverエラーログファイルをファイルシステムから直接読み取り、正規表現を使用して解析し、タイムスタンプ、SPID、エラー番号、重大度、状態、メッセージなどの構造化された情報を抽出する機能である。

**業務上の目的・背景**：SQL Serverのトラブルシューティングや問題分析において、エラーログの確認は不可欠である。通常のSSMS経由での確認は手動作業が多く、複数サーバーの監視や自動化されたログ分析には適さない。本機能は、プログラマティックにエラーログにアクセスし、検索・フィルタリング可能な形式で情報を取得することで、効率的なトラブルシューティングとプロアクティブな監視を可能にする。

**機能の利用シーン**：
- SQL Server障害発生時のエラーログ解析
- 特定のエラー番号（例：18456認証エラー）の検出と集計
- コンプライアンスレポート用のログ抽出
- 複数サーバーにわたる一括ログ収集
- 定期的な自動監視スクリプトでの使用

**主要な処理内容**：
1. Windowsアプリケーションイベントログからエラーログファイルパスを特定
2. 並列処理（Runspace）を使用したログファイルの効率的な読み取り
3. 正規表現によるログエントリの解析と構造化
4. 時間範囲によるフィルタリング

**関連システム・外部連携**：Windowsイベントログ、ファイルシステム、PowerShell Remoting（リモートサーバー時）

**権限による制御**：対象サーバーのファイルシステムへのアクセス権限、リモートサーバーの場合はPowerShell Remoting権限が必要。

## 関連画面

本機能はコマンドライン機能であり、直接的な関連画面は存在しない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

データ取得・解析処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象のSQL Serverインスタンス（デフォルト: ローカル） | 有効なインスタンス名形式 |
| Start | DateTime | No | ログ取得開始日時（デフォルト: 1970/1/1） | 有効な日時 |
| End | DateTime | No | ログ取得終了日時（デフォルト: 現在日時） | 有効な日時 |
| Credential | PSCredential | No | リモートサーバー接続用Windows資格情報 | 有効なPSCredentialオブジェクト |
| MaxThreads | int | No | ローカル並列処理の最大スレッド数（デフォルト: 0=無制限） | 0以上の整数 |
| MaxRemoteThreads | int | No | リモートサーバーでの最大スレッド数（デフォルト: 2） | 整数値 |
| EnableException | switch | No | 例外を直接スローするかどうか | - |

### 入力データソース

- ユーザー入力（コマンドラインパラメータ）
- パイプライン入力（SqlInstance）
- Windowsイベントログ（Event ID 17111）
- SQL Serverエラーログファイル（ファイルシステム）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| InstanceName | string | SQL Serverインスタンス名（ComputerName\InstanceName形式） |
| Timestamp | DateTime | エラーログエントリの記録日時 |
| Spid | string | SQL Serverプロセス ID（"s", "sa", "sr"などシステムプロセスの場合もあり） |
| Severity | int | エラーの重大度（0-25） |
| ErrorNumber | int | SQL Serverエラー番号（0は情報メッセージ） |
| State | int | エラー状態番号 |
| Message | string | エラーメッセージ全文 |

### 出力先

- PowerShellパイプライン（PSCustomObject）
- コンソール出力

## 処理フロー

### 処理シーケンス

```
1. Runspaceプールの初期化
   └─ 並列処理用のRunspace環境を準備

2. インスタンスごとの処理ループ
   └─ 各SqlInstanceに対してRunspaceを起動

3. リモートスクリプトの実行
   └─ Invoke-Commandでリモートサーバーでスクリプト実行

4. エラーログファイルパスの特定
   └─ Windowsイベントログ(Event ID 17111)からパスを取得

5. ログファイルの列挙
   └─ 時間範囲に該当するログファイルを特定

6. 並列ファイル処理
   └─ 各ログファイルをRunspaceで並列読み取り

7. 正規表現解析
   └─ ログエントリを構造化データに変換

8. 結果の集約と出力
   └─ 全Runspace完了後に結果を出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Runspaceプール初期化]
    B --> C{SqlInstanceループ}
    C --> D[Start-Runspace]
    D --> E[Invoke-Command リモート実行]
    E --> F[Get-WinEvent ID 17111]
    F --> G{イベント取得成功?}
    G -->|No| H[return空]
    G -->|Yes| I[エラーログパス抽出]
    I --> J[Get-ChildItem ログファイル列挙]
    J --> K[ファイル処理Runspace起動]
    K --> L[FileStream読み取り]
    L --> M[正規表現解析]
    M --> N{時間範囲内?}
    N -->|Yes| O[結果出力]
    N -->|No| P[スキップ]
    O --> Q{次のファイル?}
    P --> Q
    Q -->|Yes| K
    Q -->|No| R[Runspace完了]
    H --> C
    R --> C
    C -->|完了| S[Receive-Runspace Wait]
    S --> T[Runspaceプール終了]
    T --> U[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | イベントログからパス取得 | Event ID 17111からエラーログパスを特定 | 常時 |
| BR-002 | 時間範囲フィルタリング | Start/Endパラメータで時間範囲を制限 | 常時 |
| BR-003 | 並列処理制限 | MaxRemoteThreadsでCPU負荷を制御 | リモートサーバー時 |
| BR-004 | パターン不一致スキップ | 正規表現にマッチしないエントリは無視 | 常時 |

### 計算ロジック

- **エラーログ解析正規表現**: `^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d[\w ]+((\w+): (\d+)[,\.]\s?){3}`
- **タイムスタンプ解析**: `yyyy-MM-dd HH:mm:ss.ff` 形式

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

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

本機能はデータベースに直接アクセスせず、ファイルシステムからエラーログを読み取る。

| 操作 | 対象 | 操作種別 | 概要 |
|-----|------|---------|------|
| エラーログファイル読み取り | ファイルシステム | 読み取り | エラーログファイルを直接読み取り |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | イベントログ取得失敗 | Event ID 17111が見つからない | 空結果を返して処理継続 |
| - | ファイルアクセスエラー | ログファイルへのアクセス権限不足 | 例外をキャッチして次のファイルへ |

### リトライ仕様

リトライは実装されていない。エラー発生時は当該ファイル/インスタンスをスキップして処理を継続。

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

本機能は読み取り専用操作のため、トランザクション管理は不要。

## パフォーマンス要件

- 並列処理により複数ファイル/インスタンスを効率的に処理
- MaxRemoteThreadsで本番サーバーへの負荷を制御可能（デフォルト2スレッド）
- 大容量ログファイルの場合は処理時間が増加

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

- ファイルシステムへのアクセス権限が必要
- リモートサーバーの場合はPowerShell Remoting権限が必要
- Credentialパラメータで別途Windows認証情報を指定可能

## 備考

- 名前と異なりWindowsイベントログではなくSQL Serverエラーログを読み取る機能
- Get-DbaErrorLogとの違い: こちらはファイルシステムから直接読み取り

---

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

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

### 推奨読解順序

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

本機能は複雑な並列処理構造を持つ。出力は正規表現解析によって生成されるPSCustomObjectである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 160-167行目のConvert-ErrorRecord関数内出力構造 |

**読解のコツ**: 正規表現グループからプロパティを抽出する仕組みを理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 73-95行目のパラメータ定義 |
| 2-2 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 291-304行目のRunspace初期化 |

**主要処理フロー**:
1. **73-95行目**: パラメータ定義
2. **97-129行目**: beginブロック内のヘルパー関数定義
3. **291-298行目**: Runspaceプールの初期化
4. **306-311行目**: processブロックでのRunspace起動

#### Step 3: リモート実行スクリプトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 132-257行目のscriptBlock_RemoteExecution |

**主要処理フロー**:
- **148-173行目**: Convert-ErrorRecord関数（正規表現解析）
- **198-207行目**: Get-WinEventでエラーログパス取得
- **214行目**: Get-ChildItemでログファイル列挙
- **230-256行目**: ファイル並列処理ループ

#### Step 4: 並列処理制御を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 101-128行目のStart-Runspace, Receive-Runspace関数 |

**主要処理フロー**:
- **101-106行目**: Start-Runspace関数でRunspace起動
- **108-128行目**: Receive-Runspace関数で結果取得
- **314-318行目**: endブロックでRunspaceプール終了

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

```
Get-DbaWindowsLog
    │
    ├─ [begin] Runspaceプール初期化
    │      └─ RunspaceFactory.CreateRunspacePool
    │
    ├─ [process] Start-Runspace (インスタンスごと)
    │      │
    │      └─ scriptBlock_ParallelRemoting
    │             │
    │             └─ Invoke-Command
    │                    │
    │                    └─ scriptBlock_RemoteExecution
    │                           │
    │                           ├─ Get-WinEvent (ID 17111)
    │                           │
    │                           ├─ Get-ChildItem (ログファイル)
    │                           │
    │                           └─ [並列] ファイル処理
    │                                  │
    │                                  ├─ FileStream読み取り
    │                                  │
    │                                  └─ Convert-ErrorRecord
    │                                         └─ 正規表現解析
    │
    └─ [end] Receive-Runspace -Wait
           └─ Runspaceプール終了
```

### データフロー図

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

SqlInstance ───▶ Runspace起動
                         │
Credential ──────────────┤
                         │
Start/End ───────────────┤
                         ▼
              Invoke-Command (リモート)
                         │
                         ▼
              Get-WinEvent ID 17111
                         │
                         ▼
              エラーログパス取得
                         │
                         ▼
              Get-ChildItem (時間範囲フィルタ)
                         │
                         ▼
              [並列] FileStream読み取り
                         │
                         ▼
              正規表現解析 (Convert-ErrorRecord)
                         │
                         ▼
              PSCustomObject ───▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | ソース | メイン機能実装（並列処理含む） |
| Stop-Function.ps1 | `private/functions/Stop-Function.ps1` | ソース | エラー処理ユーティリティ |
| Write-Message.ps1 | `private/functions/Write-Message.ps1` | ソース | ログ出力ユーティリティ |
