So I was generating a long log file that reported a success or failure each time a process ran. I needed to add a catch to see if the last line of the log was a failure and, if so, try a different process in the hopes of producing a success before moving on.
Thing is, there’s no “readline” function in VBScript that lets you start at the bottom of the file and read up. I googled around a bit and found a lot of what I thought to be convoluted scripts about counting lines and nested arrays, so I ended up cobbling together my own option.
What this does is open the file, read the whole thing, create an array out of each line, then (and here’s my apparent innovation) read the array backwards to find the last line (with text) and see if it reported a success or failure. I could then set a flag and continue with my looped processing, or try the re-processing first. Your mileage may vary.
Option Explicit
' standard constants for file manipulation
Const OverwriteExisting = True
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
' -2 = open as system default format; -1 = open as uincode; 0 = open as ASCII
Const cLogFile = "error-log.txt"
' declare variables
Dim vLogContents, aAllLines, z, vThisLn
Dim objFSO, ts, vFlag, vFindThis
' create objects
Set objFSO = CreateObject("Scripting.FileSystemObject")
' set variables
vFindThis = "phrase to find" ' case sensitive
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' read the last line of a log to check for errors
'
' read the whole error log
Set ts = objFSO.OpenTextFile(cLogFile, ForReading, TristateFalse)
vLogContents = ts.ReadAll
ts.Close
' turn each line into an array member
aAllLines = Split(vLogContents, vbCrLf)
' go backwards through the array until we find a line that isn't blank
' (we are effectively reading the log backwards)
For z = 0 to Ubound(aAllLines)
vThisLn = Ubound(aAllLines) - z
If aAllLines(vThisLn) <> "" Then ' skip blank lines
' see if the line has what we're looking for in it
If Instr(aAllLines(vThisLn),vFindThis) > 0 Then
' if so, set the flag to found
vFlag = 1
' and stop looking
z = Ubound(aAllLines)
Else
' if not, set the flag to not found
vFlag = 0
' and stop looking
z = Ubound(aAllLines)
End If
End If
Next
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If vFlag = 1 Then
' add your code here, based on the flag
MsgBox "Found: " & vFindThis
End If
If vFlag = 0 Then
' add your code here, based on the flag
MsgBox "Not found: " & vFindThis
End If
Set objFSO = Nothing




Comments
WARNING SQLSERVER:
ERROR SQLSERVER:
CRITICAL ERROR SQLSERVER:
Need a script that will check for the LAST LINE updated for the word WARNING or ERROR Or CRITICAL. Would the above link work so and what parameter to change accordingly?
' set variables
vFindThis = "phrase to find" ' case sensitive
If you need to cycle through 3 words, you could create an array and then put the code inside a loop that goes through each member of the array, somewhere around this bit:
' see if the line has what we're looking for in it
But yes, the above script will read a log file backwards. It does not check the date of the file, but then my script just has a hard-coded log file (Const cLogFile = "error-log.txt").
You could add a check for the objFSO.DateModified property on your file, though.
Also note that the output in my code above is a message box, so you'll probably have to change that (in my full script that I wrote this snippet for, the info is written to another log file).
My real purpose for this post was just the "nuts-n-bolts" of reading a file backwards.
A part of the script is what you have written to read the log from the last line.
And yes used the objFSO.DateModified property to compare the file modification.
Actually the script goes into a SCOM monitor so further alterations had to be done.
Thanks for the help.
RSS feed for comments to this post.