# 画面設計書 129-Windowsログ

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるWindowsイベントログ取得機能の設計仕様を定義する。SQL Serverエラーログファイルをファイルシステムから直接読み取り、構造化されたエラー情報を取得して分析・トラブルシューティングを支援する。

### 本画面の処理概要

**業務上の目的・背景**：SQL Serverの問題分析、コンプライアンスレポート、プロアクティブな監視には、エラーログへのプログラマティックなアクセスが不可欠である。手動でのログファイルレビューは時間がかかり、大量のログエントリから必要な情報を抽出することは困難である。本機能は、Windowsアプリケーションイベントログ（イベントID 17111）を照会してSQL Serverエラーログファイルの場所を特定し、正規表現を使用してログファイルを解析して、タイムスタンプ、SPID、エラー番号、重大度レベル、メッセージなどの構造化された情報を提供する。

**画面へのアクセス方法**：PowerShellコンソールまたはスクリプトから以下のコマンドレットを実行してアクセスする。
```powershell
Get-DbaWindowsLog -SqlInstance <インスタンス名>
```

**主要な操作・処理内容**：
1. Windows Application Event Log（イベントID 17111）からSQL Serverエラーログパスを取得
2. エラーログファイル一覧を取得（時間範囲でフィルタ）
3. Runspaceを使用して並列にログファイルを解析
4. 正規表現でエラーログエントリをパース
5. PSCustomObjectとして構造化された結果を出力

**画面遷移**：本機能はCLIコマンドであり、GUI画面遷移は存在しない。関連コマンドとしてGet-DbaErrorLogでSQL Server経由のエラーログ取得が可能。

**権限による表示制御**：
- SQL Serverホストへのファイルシステムアクセス権限が必要
- リモートコンピュータの操作にはPowerShellリモーティング権限が必要

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 153 | Get-DbaWindowsLog | 主機能 | Windowsイベントログの取得 |

## 画面種別

CLI（コマンドラインインターフェース） - 単一コマンドレット

## URL/ルーティング

PowerShellコマンドレット:
- `Get-DbaWindowsLog`

## 入出力項目

### Get-DbaWindowsLog パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| SqlInstance | DbaInstanceParameter[] | No | $env:COMPUTERNAME | SQL Serverインスタンス |
| Start | DateTime | No | 1970/1/1 00:00:00 | 開始日時フィルタ |
| End | DateTime | No | (現在日時) | 終了日時フィルタ |
| Credential | PSCredential | No | - | Windows資格情報 |
| MaxThreads | int | No | 0（無制限） | ローカル並列スレッド最大数 |
| MaxRemoteThreads | int | No | 2 | リモート並列スレッド最大数 |
| EnableException | switch | No | $false | 例外を有効化 |

## 表示項目

### Get-DbaWindowsLog 出力プロパティ

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| InstanceName | string | SQL Serverインスタンス名 |
| Timestamp | DateTime | ログエントリの日時 |
| Spid | string | SQL Serverプロセス ID（s, sa, sr等のシステムプロセス） |
| Severity | int | 重大度レベル（0-25） |
| ErrorNumber | int | SQL Serverエラー番号（0は情報メッセージ） |
| State | int | エラー状態番号 |
| Message | string | ログメッセージ全文 |

## イベント仕様

### 1-Windowsイベントログ取得（Get-DbaWindowsLog）

SQL Serverエラーログをファイルシステムから取得・解析する。

**処理フロー**:
1. **Runspace初期化**: RunspacePoolを作成し、MaxThreadsで並列実行数を制御
2. **processブロック**: 各SqlInstanceに対してStart-Runspaceを呼び出し
3. **リモート実行スクリプト（scriptBlock_ParallelRemoting）**:
   - Invoke-Commandでリモートコンピュータ上で実行
   - InstanceNameプロパティを追加してSelect-Object
4. **リモートスクリプト（scriptBlock_RemoteExecution）**:
   - インスタンス名からイベントソース名を決定（MSSQLSERVERまたはMSSQL$インスタンス名）
   - `Get-WinEvent -FilterHashtable @{LogName="Application";ID=17111}`でエラーログパスを取得
   - `Split-Path`でパスとファイル名を分離
   - `Get-ChildItem`でログファイル一覧を取得（時間範囲でフィルタ）
   - 各ファイルに対してRunspaceを作成して並列処理
5. **ファイル処理スクリプト（scriptBlock）**:
   - FileStreamとStreamReaderでログファイルを読み込み
   - Convert-ErrorRecord関数で各行を解析
6. **Convert-ErrorRecord関数**:
   - 正規表現 `^([\d- :]+.\d\d) (\w+)[ ]+Error: (\d+), Severity: (\d+), State: (\d+)` でエラー情報を抽出
   - 2行にまたがるエラーエントリを処理
   - Timestamp、Spid、ErrorNumber、Severity、State、Messageを含むPSObjectを作成
7. **endブロック**: すべてのRunspaceを待機・受信してクリーンアップ

## データベース更新仕様

本機能はSQL Serverデータベースには直接アクセスしない。ファイルシステムとWindowsイベントログを読み取る。

### 操作別影響一覧

| 操作（イベント） | 対象リソース | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Get-DbaWindowsLog | Windows Application Event Log | READ | イベントID 17111の読み取り |
| Get-DbaWindowsLog | SQL Server Error Log Files | READ | エラーログファイルの読み取り |

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 発生条件 |
|-------------|------|---------|---------|
| - | Verbose | "Launching remote runspace against $instance" | Runspace起動時 |
| - | Verbose | "Receiving results from $($Run.Instance)" | Runspace結果受信時 |
| - | VeryVerbose | "Processing $instance" | インスタンス処理開始時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| イベントログが見つからない | 処理をスキップ（returnで終了） |
| ファイル読み取りエラー | try-catchで捕捉し黙って続行 |
| Runspace実行エラー | EndInvokeで例外を受け取り |

## 備考

- イベントID 17111はSQL Serverの起動イベントであり、このイベントからエラーログファイルのパスが取得される
- デフォルトインスタンスのイベントソースは"MSSQLSERVER"、名前付きインスタンスは"MSSQL$インスタンス名"
- ログ解析は正規表現を使用し、パターンに一致しないエントリは黙ってスキップされる
- 2行にまたがるエラーエントリ（Error/Severity/State行とメッセージ行）を正しく処理
- Runspaceを使用した並列処理により、複数インスタンス・複数ログファイルの処理を高速化
- MaxRemoteThreadsのデフォルト値2は、本番サーバーへの負荷を抑えるため

---

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

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

### 推奨読解順序

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

出力オブジェクトのプロパティ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 行160-167のNew-Object PSObjectで出力構造を確認 |
| 1-2 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 行287のSelect-Objectで最終出力プロパティを確認 |

**読解のコツ**: 出力は2段階で構築される。Convert-ErrorRecord関数で基本プロパティを作成し、Invoke-Command結果にInstanceNameを追加。

#### Step 2: 全体アーキテクチャを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 行97-303のbeginブロックでRunspace設定を確認 |
| 2-2 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 行306-312のprocessブロック |
| 2-3 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 行314-319のendブロック |

**主要処理フロー**:
1. **101-106行**: Start-Runspace関数（Runspace起動）
2. **108-128行**: Receive-Runspace関数（結果受信）
3. **132-174行**: Convert-ErrorRecord関数（ログ解析）
4. **177-194行**: ファイル処理スクリプトブロック
5. **197-215行**: エラーログファイル一覧取得
6. **217-256行**: 並列処理でファイル解析
7. **259-288行**: リモート実行スクリプトブロック
8. **291-303行**: Runspaceプール初期化

#### Step 3: ログ解析ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | 行148-173のConvert-ErrorRecord関数 |

**解析ロジック**:
1. **157行**: 正規表現でError/Severity/State行を解析
2. **158行**: 正規表現でメッセージ行を解析
3. **160-167行**: PSObjectを構築
4. **170-172行**: 2行にまたがるエントリを処理（codesAndStuff変数で状態保持）

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

```
Get-DbaWindowsLog
    |
    +-- [beginブロック]
    |      +-- RunspacePool作成
    |      +-- Start-Runspace関数定義
    |      +-- Receive-Runspace関数定義
    |      +-- scriptBlock_RemoteExecution定義
    |      +-- scriptBlock_ParallelRemoting定義
    |
    +-- [processブロック]
    |      +-- foreach (SqlInstance)
    |             +-- Start-Runspace
    |             |      +-- scriptBlock_ParallelRemoting実行
    |             |             +-- Invoke-Command
    |             |                    +-- scriptBlock_RemoteExecution
    |             |                           +-- Get-WinEvent (EventID 17111)
    |             |                           +-- Get-ChildItem (errorlog files)
    |             |                           +-- RunspacePool (ファイル並列処理)
    |             |                                  +-- FileStream/StreamReader
    |             |                                  +-- Convert-ErrorRecord
    |             |                                         +-- 正規表現解析
    |             |                                         +-- PSObject作成
    |             +-- Receive-Runspace
    |
    +-- [endブロック]
           +-- Receive-Runspace -Wait
           +-- RunspacePool.Close()
           +-- RunspacePool.Dispose()
```

### データフロー図

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

SqlInstance ───────────> RunspacePool作成 ───────────────────>
                                |
                                v
                        Start-Runspace ──────────────────────>
                        (scriptBlock_ParallelRemoting)
                                |
                                v
                        Invoke-Command ──────────────────────>
                        (リモートコンピュータ上)
                                |
                                v
                        Get-WinEvent ────────────────────────>
                        (EventID 17111)
                                |
                                v
                        Split-Path ──────────────────────────> ErrorLogPath
                                |
                                v
Start/End ─────────────> Get-ChildItem ──────────────────────> ErrorLogFiles
                        (時間範囲フィルタ)
                                |
                                v
MaxRemoteThreads ──────> RunspacePool ───────────────────────>
                        (並列ファイル処理)
                                |
                                v
                        FileStream/StreamReader ─────────────>
                                |
                                v
                        Convert-ErrorRecord ─────────────────>
                        (正規表現解析)
                                |
                                v
                        PSObject ────────────────────────────>
                                |
                                v
                        Select-Object ───────────────────────> 出力
                        (+ InstanceName)

[出力オブジェクト]
    InstanceName, Timestamp, Spid, Severity, ErrorNumber, State, Message
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaWindowsLog.ps1 | `public/Get-DbaWindowsLog.ps1` | ソース | Windowsログ取得 |
