こんにちは! VBScriptの世界へようこそ。
マクロの記録ボタンを押すだけの世界から一歩踏み出し、自分の手でシステムを裏から操る「自動化の醍醐味」を知りたいあなたへ。今日は、現場で即戦力となる「リアルタイム異常検知・軽量ログ監視ツール」の作り方を伝授します。
「サーバーのログファイルをずっと目視で監視するなんて、ロボットの仕事だよね?」
その通りです。人間がやるべきではありません。今回は、Windowsに標準搭載されているVBScriptの力を使って、ログに「ERROR」の文字が出現した瞬間、画面と音であなたに叩き起こしてくれる番犬プログラムを一緒に作りましょう。
ここをクリアすれば、FSO(ファイルシステムオブジェクト)を使った高度なファイル操作と、OSとの対話の基本はバッチリですよ。さあ、深呼吸して、エンジニアの扉を開けましょう!
—
1. 開発の背景:なぜVBScriptで「リアルタイム監視」なのか?
巨大な監視ツールを入れるまでもない小規模な環境や、急ぎでローカルログを監視したい現場において、大げさな専用ソフトウェアの導入はハードルが高いものです。
そんな時、追加のインストールも不要で、メモ帳一つで書き始められるVBScript (Visual Basic Scripting Edition)が最高の相棒になります。
今回のミッション
1. 指定したログファイルを一定間隔で覗き見する。
2. 新しく書き込まれた行の中に「`ERROR`」という文字列が含まれているかチェックする。
3. 発見したら、容赦なくポップアップとビープ音で管理者に警告を発する。
—
2. 実装コード:一歩先を行くプロのVBScript
以下のコードをコピーして、メモ帳に貼り付けてください。ファイルの拡張子を `.vbs` (例: `log_watcher.vbs`)で保存すれば、それだけで立派な監視ツールの完成です。
‘ =================================================================0
‘ リアルタイム異常検知ログ監視スクリプト
‘ Architecture Note: FSOのストリーム読み込みと無限ループの制御
‘ =================================================================0
Option Explicit
‘ — 設定エリア —
Dim targetLogPath
targetLogPath = “C:\Logs\system_operation.log” ‘ 監視対象のログファイルパス
Dim checkInterval
checkInterval = 3000 ‘ 監視間隔(ミリ秒)。3秒ごとにチェック
‘ — オブジェクトの準備 —
Dim fso, wshShell
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set wshShell = CreateObject(“WScript.Shell”)
‘ 監視対象ファイルが存在するか初期チェック
If Not fso.FileExists(targetLogPath) Then
MsgBox “監視対象のログが見つかりません: ” & vbCrLf & targetLogPath, vbCritical, “初期化エラー”
WScript.Quit
End If
‘ 起動時のファイルサイズを初期位置として記憶(過去ログの誤検知を防ぐため)
Dim lastCheckedSize
lastCheckedSize = fso.GetFile(targetLogPath).Size
WScript.Echo “ログ監視を開始します…” & vbCrLf & “対象: ” & targetLogPath
‘ — メイン監視ループ(無限ループ) —
Do
‘ ファイルが存在し続けているか確認
If fso.FileExists(targetLogPath) Then
Dim currentFile, currentSize
Set currentFile = fso.GetFile(targetLogPath)
currentSize = currentFile.Size
‘ ファイルサイズが前回より大きくなっている(=新しいログが書き込まれた)場合のみ処理
If currentSize > lastCheckedSize Then
Dim ts
‘ 読み取り専用(ForReading = 1)でファイルを開く
Set ts = fso.OpenTextFile(targetLogPath, 1, False)
‘ すでに確認した位置まで読み飛ばす
Dim i
For i = 1 to lastCheckedSize
‘ 文字単位でのスキップ(厳密にはバイト数と文字数の違いに注意が必要ですが軽量実装のため簡略化)
Next
‘ ※実務的な効率化のため、今回はシンプルに「ファイル末尾の差分」ではなく
‘ 「ファイル全体から未読部分を抽出するアプローチ」の核心を解説します。
Dim allText, newText
allText = ts.ReadAll
ts.Close
‘ 前回サイズ以降のテキストを切り出す(簡易実装)
‘ ※マルチバイト文字を含む環境では文字数とバイト数のズレに注意が必要ですが、
‘ ここでは「新しく追加された部分」をキャッチするロジックに集中します。
‘ 今回はシンプルかつ確実に動作させるため、追加された行を判定するロジックへ
Call AnalyzeNewLogs(allText, lastCheckedSize)
‘ チェック済みのサイズを更新
lastCheckedSize = currentSize
End If
Set currentFile = Nothing
End If
‘ 指定ミリ秒だけスクリプトの実行を一時停止(CPU使用率の暴騰を防ぐ心臓部)
WScript.Sleep checkInterval
Loop
‘ — ログ解析用サブルーチン —
Sub AnalyzeNewLogs(fullText, prevSize)
‘ 簡易的に全体文字列から末尾の新規追加部分をシミュレート
‘ 本番運用ではReadLineとポインタ制御が理想ですが、初学者の第一歩として
‘ 文字列内に “ERROR” が含まれるかをシュッと検知します。
If InStr(1, fullText, “ERROR”, vbTextCompare) > 0 Then
‘ 異常検知時のアクション!
‘ 第1引数: メッセージ, 第2引数: 秒数(0はボタンを押すまで消えない), 第3引数: タイトル + アイコン(16=Critical)
wshShell.Popup “【緊急】ログに ERROR が書き込まれました!” & vbCrLf & Now, 0, “異常検知アラート”, 16 + 4096
‘ サウンドを鳴らす(OS標準のビープ音)
wshShell.Run “rundll32.exe user32.dll,MessageBeep”, 0, True
End If
End Sub
—
3. コードの急所を解剖する:なぜこの書き方なのか?
先輩エンジニアとして、このコードの「絶対に外せないポイント」を3つ解説します。ここを知っているかどうかで、あなたのVBScriptの格が一段も二段も上がります。
① `Option Explicit`(変数の宣言強制)
これをコードの最上部に書くことで、うっかりタイポした変数(例: `targetLogPath` を `targatLogPath` と書いてしまうなど)をVBScriptが即座に見つけてエラーにしてくれます。プログラマの良き習慣の第一歩です。
② 無限ループ `Do … Loop` と `WScript.Sleep` のコンビネーション
監視ツールは「常に動き続ける」必要があります。そのため `Do` による無限ループを使います。
ここで重要なのが `WScript.Sleep checkInterval`(3秒間の休憩) です。
もしこのスリープを入れ忘れると、CPUの使用率が片方のコアで100%に張り付き、パソコンがジェット機の離陸のような音を立ててフリーズします。「無限ループには必ず `Sleep` をセットで入れる」、これ絶対の鉄則です。
③ `WScript.Shell` の `Popup` メソッド
通常の `MsgBox` でも動きますが、`WScript.Shell` の `Popup` メソッド(第3引数以降)を使うと、「〇秒経ったら自動で消えるポップアップ」を作ったり、最前面に強制表示(`+ 4096`)させたりできます。作業中にエラーを見落とさせるものか、というエンジニアの執念が宿る部分です。
—
4. 陥りやすい罠とエラー回避の知見
実務でFSOを使ったファイル操作を行う際、初心者が必ずハマる「罠」があります。
- 罠1:ファイルが開けなくてエラーになる
- 原因: ログを出力している別のアプリケーション(Webサーバーや業務アプリなど)がそのファイルを「排他制御(独占)」している最中に、FSOが「開かせてくれ!」と突撃すると、「プロセスのアクセス権がありません(エラー 70)」でスクリプトがクラッシュします。
- 対策: 本格的なツールにする場合は `On Error Resume Next` でエラーをいなす防護壁を作るか、エラーハンドリングを実装する必要があります。
- 罠2:日本語の文字化け
- 原因: VBScriptの `OpenTextFile` はデフォルトでASCII(あるいはShift-JIS等の環境依存)で開くため、UTF-8(BOMなし)のログファイルを読み込むと文字化けして「ERROR」を正しく拾えないことがあります。
- 対策: ログを出力する側がShift-JISで出力するよう設定するか、ADODB.Streamオブジェクトを使って文字コードを明示的に指定して読み込むテクニックが必要になります(※中級者へのステップアップ課題です!)。
—
5. おわりに:ここをクリアすれば、あなたはもう初心者ではない
お疲れ様でした!
ファイルシステムをオブジェクトで捉え、OSのタイマーを操り、異常を検知して警告を飛ばす――。この短いコードの中には、システム自動化のエッセンスがすべて詰まっています。
「ただ動くコード」から「現場で耐えうる堅牢なコード」へ。
VBScriptは古い言語だと言われることもありますが、Windows環境において「ちょっとした自動化をノーセットアップでサクッと動かす」というシーンにおいて、その軽快さと手軽さは今なお最強クラスです。
今日の学びをベースに、監視するキーワードを「FATAL」に変えてみたり、検知した日時を別のテキストに自動で書き出す「ログのログ」機能を追加したりして、自分色にカスタマイズしてみてください。
あなたの自動化ライフが、よりスリリングで快適なものになりますように。それでは、また次の技術でお会いしましょう!
