VBScriptを掌握せよ:FSOとRegExpで挑む、超高速ログ解析の極意
VBScriptは「レガシー」などという言葉で片付けられる存在ではない。Windowsの心臓部で、今なお黙々とタスクを完遂し続ける、最も枯れていて、最も信頼できるツールだ。
君たちが今日直面している「数ギガバイトに及ぶログの解析」という課題。これを安易にGUIツールで開こうなどと考えるな。メモリを食いつぶし、OSを瀕死に追い込むのが関の山だ。真のエンジニアは、FSO(FileSystemObject)とRegExp(正規表現)を武器に、ストリーム処理で解を導き出す。
今回は、メモリ効率と実行速度を極限まで高めた、実務レベルのログ解析バッチの設計思想を伝授する。
—
1. 巨大ログを殺さないための「ストリーム読み込み」戦略
FSOの`ReadAll`メソッド? 巨大なログファイルを扱う現場でそれを使うのは、プロとしては失格だ。メモリ上に全データを展開するなど、OSに対する冒涜に等しい。
我々が採用すべきは、`OpenTextFile`による逐次読み込みである。行単位でメモリに載せ、処理が終われば即座に捨てる。この「フロー制御」こそが、数百万行のログを数秒で捌くための唯一の道だ。
2. 実装:時間帯別エラー集計スクリプト
以下は、ログファイルから正規表現でタイムスタンプとステータスを抽出し、Dictionaryオブジェクトで集計するコードだ。
Option Explicit
‘ 伝説的な処理速度を実現するための設計
Dim fso, logFile, regEx, match, dict
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set regEx = New RegExp
Set dict = CreateObject(“Scripting.Dictionary”)
‘ 正規表現:[YYYY-MM-DD HH:MM:SS] [LEVEL] 形式を想定
regEx.Pattern = “(\d{2}):\d{2}:\d{2}.?(ERROR|CRITICAL)”
regEx.IgnoreCase = True
regEx.Global = False
‘ ログファイルを読み取り専用で開く
Set logFile = fso.OpenTextFile(“C:\Logs\app_server.log”, 1)
Do Until logFile.AtEndOfStream
Dim line, tsHour
line = logFile.ReadLine
If regEx.Test(line) Then
Set match = regEx.Execute(line)
‘ 時間帯(HH)をキーにして集計
tsHour = match(0).SubMatches(0)
If Not dict.Exists(tsHour) Then
dict.Add tsHour, 1
Else
dict(tsHour) = dict(tsHour) + 1
End If
End If
Loop
‘ 結果出力
Dim key
For Each key In dict.Keys
WScript.Echo “時間帯: ” & key & “時 – エラー件数: ” & dict(key)
Next
‘ オブジェクトの明示的解放:これがメモリリークを防ぐ唯一の作法
logFile.Close
Set logFile = Nothing
Set regEx = Nothing
Set dict = Nothing
Set fso = Nothing
—
3. シニアが意識すべき「メモリの呼吸」
コードを見て気づいただろうか。なぜ`Set = Nothing`を徹底するのか。
VBScriptのガベージコレクションを信用してはいけない。特にCOMコンポーネントを多用する環境では、参照カウントが残ったままスクリプトがループし続けると、プロセスが徐々に肥大化する。「使ったオブジェクトは、そのスコープの出口で確実に破棄する」。この規律こそが、24時間365日稼働するバッチサーバーの安定性を支えるのだ。
4. 応用:Windows APIとの連携という選択肢
もし、ログが巨大すぎてスクリプトの実行時間がボトルネックになるなら、VBScriptの中から `WScript.Shell` を介して `PowerShell` を呼び出すのではなく、`ADODB.Stream` を活用してバイナリレベルでの高速読み込みを検討せよ。
また、特定のファイルが書き込み中であるというロックの問題に直面した場合は、`CreateObject(“Shell.Application”)` で権限を昇格させるか、APIの `OpenFile` 系の呼び出しを `Dynwrap.dll` 等でラッパーして制御する。これらは「標準機能」の範疇を超えているように見えるかもしれないが、現場のトラブルを解決するためには、これくらいの越境が不可欠だ。
終わりに:ツールに支配されるな
VBScriptは、シンプルであるがゆえに書き手の技量が露骨に出る言語だ。
コードの行数ではなく、「いかにOSのリソースを汚さずに、目的のデータのみを抽出するか」。その哲学を忘れてはならない。
君たちが書くそのスクリプトは、単なるテキストではない。業務を自動化し、深夜の呼び出しからエンジニアを救い出す「沈黙の守護者」であるべきだ。
さあ、エディタを開け。無駄な処理を削ぎ落とし、最短最速のロジックを刻み込め。
