# バッチ設計書 2-logfilescript.ps1

## 概要

本ドキュメントは、dbatoolsモジュールのログファイル出力を管理するバックグラウンドRunspaceスクリプト「logfilescript.ps1」の設計仕様を記載したものである。

### 本バッチの処理概要

本スクリプトは、dbatoolsモジュールで生成されるエラーログとメッセージログを非同期でファイルに出力するバックグラウンドRunspaceを管理する。メインスレッドからキューに投入されたログエントリを監視し、XMLファイル（エラー）およびCSV形式のログファイル（メッセージ）として永続化する。また、ログファイルのローテーションとクリーンアップ処理も担当する。

**業務上の目的・背景**：dbatoolsモジュールは多数のSQL Server管理コマンドを提供しており、デバッグやトラブルシューティングのためにログの永続化が重要である。しかし、ログのファイル書き込みをメインスレッドで同期的に行うと、パフォーマンスに悪影響を与える可能性がある。本スクリプトは、ログ出力を非同期で行うことでメインスレッドのレスポンスを維持しながら、確実なログ永続化を実現する。また、ディスク容量の枯渇を防ぐため、ログファイルのサイズとファイル数を制御するクリーンアップ機能を提供する。

**バッチの実行タイミング**：dbatoolsモジュールのインポート時に自動的に開始され、モジュールがアンロードされるまで継続的に実行される。5秒間隔でログキューを監視する。

**主要な処理内容**：
1. ログ出力先ディレクトリの存在確認・作成
2. エラーキュー（OutQueueError）からエラーレコードを取得し、XMLファイルとしてエクスポート
3. メッセージキュー（OutQueueLog）からログエントリを取得し、CSV形式でログファイルに追記
4. エラーXMLファイルのサイズ制限に基づくクリーンアップ（Clean-ErrorXml）
5. メッセージログファイルの個数制限に基づくクリーンアップ（Clean-MessageLog）
6. 古いログファイルの削除と全体フォルダサイズの制限（Clean-GlobalLog）

**前後の処理との関連**：本スクリプトはモジュール初期化時にdbatools.psm1から呼び出される。Write-Messageコマンドレットやエラー発生時にキューにログが投入され、本スクリプトがそれを処理する。dbatools-maintenanceやdbatools-teppasyncacheなど他のバックグラウンドRunspaceと並行して動作する。

**影響範囲**：dbatoolsモジュールの全ログ出力機能に影響する。ログファイルはLoggingPathで指定されたディレクトリに出力される。

## バッチ種別

バックグラウンドログ出力 / ファイルローテーション

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 継続的（5秒間隔でキュー監視） |
| 実行時刻 | モジュールインポート時に開始 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | dbatoolsモジュールのインポート |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| dbatoolsモジュールのロード | dbatools.psm1が正常にインポートされていること |
| .NET Frameworkランタイム | Dataplat.Dbatools.dllが利用可能であること |
| ログ出力ディレクトリへの書き込み権限 | LoggingPathで指定されたパスへの書き込みが可能であること |

### 実行可否判定

Runspaceの状態が"Running"である限り継続実行される。状態が"Running"以外になった場合、ループを抜けて終了処理を行う。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 本スクリプトは直接パラメータを受け取らない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| LogHost.OutQueueError | ConcurrentQueue | エラーレコードのキュー |
| LogHost.OutQueueLog | ConcurrentQueue | メッセージログエントリのキュー |
| LogHost.LoggingPath | 文字列 | ログファイル出力先ディレクトリパス |
| LogHost.MaxErrorFileBytes | int | エラーXMLファイルの最大合計サイズ |
| LogHost.MaxMessagefileCount | int | メッセージログファイルの最大数 |
| LogHost.MaxMessagefileBytes | int | 1メッセージログファイルの最大サイズ |
| LogHost.MaxTotalFolderSize | int | ログフォルダ全体の最大サイズ |
| LogHost.MaxLogFileAge | TimeSpan | ログファイルの最大保持期間 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| dbatools_{pid}_error_{num}.xml | XML (CLIXML) | エラーレコードのシリアライズ出力 |
| dbatools_{pid}_message_{num}.log | CSV | メッセージログエントリ |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| エラーファイル名 | dbatools_{ProcessId}_error_{連番}.xml |
| メッセージファイル名 | dbatools_{ProcessId}_message_{連番}.log |
| 出力先 | LogHost.LoggingPath |
| 文字コード | UTF-8（CLIXMLデフォルト） |
| 区切り文字 | CSV形式（カンマ区切り） |

## 処理フロー

### 処理シーケンス

```
1. ヘルパー関数の定義
   ├─ Clean-ErrorXml: エラーXMLファイルのクリーンアップ
   ├─ Clean-MessageLog: メッセージログファイルのクリーンアップ
   └─ Clean-GlobalLog: 全体ログフォルダのクリーンアップ
2. メインループ開始
   └─ while($true)で無限ループ
3. Runspace状態チェック
   └─ 状態が"Running"以外なら終了
4. ログディレクトリの確認・作成
   └─ Test-Path/New-Itemでディレクトリ確保
5. 既存ファイル番号の取得
   └─ 正規表現で最新のファイル番号を抽出
6. エラーキュー処理
   ├─ TryDequeueでエラーレコード取得
   ├─ Export-Clixmlでファイル出力
   └─ Clean-ErrorXmlでクリーンアップ
7. メッセージキュー処理
   ├─ ファイルサイズチェック・ローテーション
   ├─ TryDequeueでログエントリ取得
   └─ Add-ContentでCSV追記
8. クリーンアップ処理
   ├─ Clean-MessageLog実行
   └─ Clean-GlobalLog実行
9. スリープ
   └─ 5秒間待機後、次のサイクルへ
10. 終了処理
    └─ SignalStopped()でRunspaceの停止を通知
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[ヘルパー関数定義]
    B --> C{Runspace状態確認}
    C -->|Running| D[ログディレクトリ確認/作成]
    C -->|停止要求| L[終了処理]
    D --> E[既存ファイル番号取得]
    E --> F{エラーキューに項目あり?}
    F -->|あり| G[エラー出力・クリーンアップ]
    G --> F
    F -->|なし| H{メッセージキューに項目あり?}
    H -->|あり| I[メッセージ出力・ローテーション]
    I --> H
    H -->|なし| J[全体クリーンアップ]
    J --> K[5秒スリープ]
    K --> C
    L --> M[SignalStopped]
    M --> N[バッチ終了]
```

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

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

本スクリプトはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ディレクトリ作成エラー | LoggingPathへの書き込み権限がない | ErrorAction Stopで例外発生、Runspace停止 |
| - | ファイル書き込みエラー | ディスク容量不足等 | 空のcatchブロックで無視、次サイクルで再試行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 明示的なリトライなし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 次回ポーリングサイクルで自動的に再試行 |

### 障害時対応

ほとんどのエラーは空のcatchブロックで無視され、処理が継続される。致命的なエラー（ディレクトリ作成失敗等）が発生した場合はfinallyブロックでSignalStopped()が呼び出され、Runspaceの停止が通知される。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし（ファイルシステム操作のみ） |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | キュー内のログエントリ数に依存 |
| 目標処理時間 | 5秒間隔のサイクル内で完了 |
| メモリ使用量上限 | Runspace単位で数MB程度 |

## 排他制御

Runspaceは単一インスタンスで動作する。ConcurrentQueueのTryDequeueメソッドにより、スレッドセーフなキュー操作が行われる。ファイル書き込みは同一Runspace内で逐次処理される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| エラーログ | エラーキュー処理時 | エラーレコードのCLIXML形式 |
| メッセージログ | メッセージキュー処理時 | ログエントリのCSV形式 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| Runspace状態 | Running以外 | 自動終了処理 |
| ログフォルダサイズ | MaxTotalFolderSize | 自動クリーンアップ |

## 備考

- 本スクリプトはprivate/scripts/配下に配置されている
- Clean-ErrorXml, Clean-MessageLog, Clean-GlobalLogの3つのヘルパー関数を含む
- プロセスID（$pid）を含むファイル名により、複数PowerShellセッションでの競合を回避
- Export-Clixmlの-Depth 3により、エラーオブジェクトの深いネストを制限
