【極限の知見】Robocopyの「失敗」を逃さない。FSOを用いたリアルタイム・ログ監視エンジンの構築術
こんにちは。現場の最前線で自動化の設計(アーキテクチャ)を担っている、あなたの先輩エンジニアです。
「マクロの記録」や「簡単なコードのコピペ」で、一通りの作業ができるようになった。そんな段階にいるあなたへ、今日は少しだけ「プロフェッショナル」の領域へ踏み出すための、特別な話をしましょう。
今日扱うテーマは、「Robocopyの実行ログを、FileSystemObject(FSO)を使ってリアルタイムに監視し、エラーが発生した瞬間だけを特定して抽出する」という高度な仕組みです。
単に「ログを取る」だけなら誰でもできます。しかし、「動いているログの中から、異常の兆候をリアルタイムで見つけ出し、即座にアクションを起こす」。これこそが、システムを安定稼働させるエンジニアに求められる「監視の力」なのです。
ここをクリアすれば、VBScriptの基本はバッチリですよ。さあ、一緒に見ていきましょう。
1. なぜ「リアルタイム監視」が必要なのか?
バックアップ作業などでよく使われる `robocopy` コマンド。非常に強力ですが、数万件のファイルをコピーしていると、ログファイルは膨大な量になります。
作業が終わってからログを全部読み直して「あ、エラーが出ていた……」と気づいても、時すでに遅し。バックアップが失敗したまま放置されるのは、運用において致命的なリスクです。
私たちが作るのは、いわば 「ログの番犬(Watchdog)」 です。
ログファイルに新しい行が書き込まれるのを待ち構え、もしそこに「ERROR」という文字を見つけたら、即座にアラート用のログへ書き出す。この「流れる情報を処理する」感覚を身につけることが、今回のゴールです。
2. 武器となる「FileSystemObject (FSO)」の構造
VBScriptでファイルを操る際、避けては通れないのが `FileSystemObject` です。
初学者の多くは「ファイルを開いて、中身を読んで、閉じる」という一連の流れを、単なる「操作」として捉えています。しかし、プロはオブジェクトのライフサイクルを意識します。
FSOによるファイル操作は、以下の3層構造で成り立っています。
1. FileSystemObject (親玉): ファイルシステム全体を管理する司令塔。
2. File (対象): 操作したい特定のファイルそのもの。
3. TextStream (窓口): ファイルの中身を「読み書き」するためのストリーム(データの流れ)。
今回の肝は、この `TextStream` を開きっぱなしにして、データの末尾を監視し続ける というテクニックにあります。
3. 実装:リアルタイム・ログ解析エンジン
それでは、実際に動作するコードを見てみましょう。
このコードは、Robocopyが書き込んでいるログファイルを監視し、エラー行を見つけたら別のファイルに「即時転送」する設計になっています。
' ==========================================================================
' リアルタイム・ログ監視エンジン (Robocopy Error Monitor)
'
' 【概要】
' 指定されたログファイルを監視し、"ERROR" という文字列が含まれる行を
' 見つけ次第、アラート用ログへ抽出出力する。
' ==========================================================================
Option Explicit
' --- 設定エリア ---
Dim strTargetLog, strAlertLog
strTargetLog = "C:\Logs\robocopy_exec.log" ' 監視対象(Robocopyの出力先)
strAlertLog = "C:\Logs\error_alerts.log" ' エラー抽出先
' --- オブジェクト宣言 ---
Dim objFSO, objFile, objStream, objAlertStream
Dim strLine, strLastRead
' 1. FileSystemObjectの生成
Set objFSO = CreateObject("Scripting.FileSystemObject")
' 監視対象ファイルの存在チェック
If Not objFSO.FileExists(strTargetLog) Then
MsgBox "監視対象のログファイルが見つかりません: " & strTargetLog, vbCritical
WScript.Quit
End If
' 2. 監視開始
' OpenTextFileの第2引数「1」は ForReading (読み取り専用) を意味します
Set objStream = objFSO.OpenTextFile(strTargetLog, 1)
' アラート出力用のファイルを開く(第8引数 True は、ファイルがなければ作成することを意味します)
' 第2引数 8 は ForAppending (追記モード) です。これが重要!
Set objAlertStream = objFSO.OpenTextFile(strAlertLog, 8, True)
WScript.Echo "監視を開始しました。終了するには Ctrl+C を押してください。"
' --- メインループ (監視の心臓部) ---
Do
' ファイルの末尾に到達しているかチェック
If objStream.AtEndOfStream Then
' 末尾に達していたら、少し待機してから再試行 (CPU負荷を抑えるための知恵)
WScript.Sleep 1000
Else
' 新しい行がある場合は読み込む
strLine = objStream.ReadLine
' 【解析ロジック】行の中に "ERROR" というキーワードが含まれているか?
' InStr関数は、文字列が見つかった位置を返します(見つからない場合は0)
If InStr(1, strLine, "ERROR", vbTextCompare) > 0 Then
' エラーを発見!アラートログに即時書き出し
objAlertStream.WriteLine "[" & Now & "] DETECTED: " & strLine
objAlertStream.Flush ' バッファを強制的に書き出し(即時反映させるための重要操作)
End If
End If
Loop
' --- 後処理 (このコードはループするため、通常は到達しません) ---
' objStream.Close
' objAlertStream.Close
' Set objFSO = Nothing
4. プロフェッショナルの視点:ここが「差」を生む
コードをただ眺めるだけでなく、なぜこう書いたのか、その「意図」を理解してください。これがエンジニアとしての成長スピードを決めます。
① `AtEndOfStream` と `WScript.Sleep` の組み合わせ
もし `WScript.Sleep` を入れずに `Do…Loop` を回すとどうなるでしょうか?
プログラムは猛烈なスピードで「ファイルは終わったか?」という問い合わせをOSに繰り返します。これはCPU使用率を100%近くまで跳ね上げ、PC全体の動作を重くする「暴走コード」になってしまいます。
1秒(1000ms)の休息を与える。これだけで、システムに優しい、エレガントなプログラムになります。
② `ForAppending` (追記モード) と `Flush`
アラートログを書き出す際、`8` (ForAppending) を指定しています。これは、既存のログを消さずに、新しいエラーを末尾に付け足していくためです。
また、`objAlertStream.Flush` は非常に重要です。通常、書き込みはメモリ上の「バッファ」に溜められ、ある程度溜まってからファイルに書き込まれます。しかし、エラー通知は「今すぐ」必要です。`Flush` を呼ぶことで、メモリから物理ディスクへ即座にデータを押し出すことができます。
③ 陥りやすいエラー:ファイルロックの罠
Robocopyがログを書き込んでいる最中に、VBScriptがそのファイルを読み取ろうとすると、稀に「書き込み権限がない」といったエラーが発生することがあります。
実務では、`On Error Resume Next` を使ってエラーをスキップするか、リトライ処理を入れるといった、「エラーが起きることを前提とした設計」が求められます。
5. まとめ:次のステップへ
お疲れ様でした。あなたは今、単なるスクリプトの使い手から、「システムを監視するエンジニア」への第一歩を踏み出しました。
今回のポイントを復習しましょう。
- FSOの構造(FSO ➔ File ➔ TextStream)を理解する。
- `AtEndOfStream` でデータの終端を判断する。
- `WScript.Sleep` でリソース消費をコントロールする。
- `Flush` でデータの即時性を確保する。
「動けばいい」というコードは誰でも書けます。しかし、「安全に、効率よく、確実に」動くコードを書けるのが、プロフェッショナルです。
次は、このログを解析して、実際にメールを飛ばす機能(CDO.Messageオブジェクト)を追加してみるのも面白いですよ。
一歩ずつ、着実に。あなたのエンジニアとしての旅を応援しています!
