As you advance in your abilities to work with WSH you will find yourself writing more detailed and intricate code. Many of these scripts will be system administration scripts designed to run in the background. Thus, it can be very useful for your script to generate an event log.
Logging can be a highly detailed process. You may want to log the events that occur as your script runs; you may also want to log any errors that are encountered. These topics stretch far beyond the scope of a single article or series so I’ll only be giving you some basic techniques. It will be up to you to develop them for use in your own situation and for your own scripting style.
The most common method of logging is to a plain text file so we will be concentrating on that. The techniques would be similar if you wanted to log to a different type of file or even to a database. For lack of space, I’m not going into detail on how to manage the log file. Please take the time to read my “Reading Text Files in WSH” and “Writing Text Files in WSH” articles for more information.
The code samples in this article use predefined subroutines that I have created and made available for download. You can use or modify these scripts any way you like. Once you modify them to your liking, I suggest packaging them as a class so that you can reuse them in all of your scripts.
Basically, we need to accomplish a few basic steps in our script:
Identify an action taking place.
Determine if that action results in an error. If so,
Make an entry for that error in our log file.
Each event will appear on its own line in our log file. A simple logging script might look like this:
Const logfile = "C:log.txt"
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objLog = objFso.CreateTextFile(logfile, True)
objLog.WriteLine "Logging Started "
objLog.WriteLine "Logging Ended "
In this example, all we’ve done is created a text file and written a few lines to it. This isn’t doing much good at this point. Trust me, it will all come together. The log.txt will look something like this.
Logging Started
Logging Ended
Okay, so this log file is a bit vague. We need to add some more information to this log if it’s going to be at all useful.
Administrators often run many different scripts. It would be useful to have the script identify itself in the log so you could tell easily which script log you were looking at. You may also be running the same script on many different machines, so we should record the machine name in our log file as well. WSH provides a way for us to do both.
object.ScriptFullname
object.ScriptName
object.ComputerName
The WshNetwork object’s ScriptFullName property returns the full path and file name of the currently running script. Its ScriptName property returns the file name by itself. The Wscript object has a ComputerName property that returns the computer name of the current machine.
Const logfile = "C:log.txt"
Set WshNetwork = CreateObject("Wscript.Network")
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objLog = objFso.CreateTextFile(logfile, True)
objLog.WriteLine "Executing " & Wscript.ScriptFullName & " on " _
& WshNetwork.ComputerName
objLog.WriteLine "Execution of " & Wscript.ScriptName _
& " has completed."
Our log file is beginning to come together, but there are still a couple of important things we should take into consideration. First, we may not look at a log file for days or even weeks later so we should time stamp every event we write to it so that we can tell when the events occurred. Second, if we want to track this script every time it executes, we should append new data to our log file rather than overwriting it or creating a new one each time.
Const logfile = "C:log.txt"
Set WshNetwork = CreateObject("Wscript.Network")
Set objFso = CreateObject("Scripting.FileSystemObject")
& Wscript.ScriptFullName & " on " & WshNetwork.ComputerName
objLog.WriteLine Time() & " Execution of " & Wscript.ScriptName _
& " has completed." & vbCrLf & vbCrLf
Here we’ve added an If statement to check and see if our log file exists. If it does we simply append new information to the existing file. If it doesn’t, we create a new one. Our last line has some added line feeds to be sure that each instance in our log file has some space between them for readability. Now our logging script produces this:
5:03:46 PM 2/12/2007 Executing C:logtest.vbs on DEVELOPE-J06OPO
5:03:46 PM Execution of logtext.vbs has completed.
I’ve used VBScript’s Date and Time functions to provide the appropriate time stamps. I’ve also take the time to make our messages a little prettier.
Now is a good time to package our code up nicely into subroutines so it can be reused easily throughout our script. The example subroutines you’ll be seeing here have some extra functionality added. For the sake of time and space I won’t be going into detail for all of them. You should have no problem seeing how they work.
Const logfile = "C:log.txt"
Dim startTime, startDate
Set objFso = CreateObject("Scripting.FileSystemObject")
writeLog(Date() & " Execution started at " & startTime & " on " _
& startDate & " has completed" & vbCrLf & vbCrLf)
End Sub
Sub writeLog(strEvent)
If objFso.FileExists(logfile) Then
Set objLog = objFso.OpenTextFile(logfile, 8)
Else
Set objLog = objFso.CreateTextFile(logfile, True)
End If
objLog.WriteLine Time() & " " & strEvent
objLog.Close
End Sub
Here’s what our subroutines should look like. Our first subroutine is the startLogging subroutine. This subroutine writes the first line of our log file. We can call this sub whenever we are ready to start logging data. The stopLogging sub writes the final line of our log session and then closes the file to save changes.
I’ve also created a writeLog subroutine to actually perform the writing operation on the log file. It accepts a single attribute in the form of a string to write to the file. Running the script now produces the following log.
5:12:12 PM 2/12/2007 Executing C:logging.vbs on DEVELOPE-J06OPO
5:12:12 PM 2/12/2007 Execution started at 5:12:12 PM on 2/12/2007 has completed
I’ve shown you all of the basics you need to incorporate logging into your scripts. Be sure to check out the second part of this series, “Error Trapping and Capturing Third-Party Output” to learn how to make your log files more effective.
Be sure to download the code source for this article. In it you will find a complete logging script with ready to use subroutines. You can use them as is or customize them to your liking. Either way they should provide you with a good foundation for adding logging to your scripts.
In the second part of this article you will learn how to effectively trap execution errors in your code with VBScript’s Err object, how to log information to the system’s Application Event Log, and how to capture the output of third-party programs executed by your script.
My hope is that this series will aid you in becoming better code writers. Proper error-handling and logging are two of the techniques that make your code much more useful and more professional. You should try to incorporate this into all of your scripts. Stick around for part two. Until next time, keep coding!