Writing the Main Script
Now you're ready to fire up your script editor and write the main portion of the script. Any functions or subroutines you've written-including the FormatLogFileName function-will need to be copied and pasted into the first pat of the script.
NOTE
You can add the function to the script at the end, if you want. It's strictly a matter of personal preference.
Log Rotation Script
With the supporting functions out of the way, you can start concentrating on the main script. Refer back to your original task list and translate it to VBScript; you might come up with something like Listing 13.2.
Listing 13.2. Log Rotation.vbs. This is the first-pass script and contains all the important program logic.
' Sample log rotation tool
'
' We'll take yesterday's log and move it to
' an archive folder. We'll delete the log file
' that's 30 days old from the archive
' ----------------------------------------------------------
'declare variables
Dim sLogPath, sService, sArchive, sLogFile
Dim oFSO
Dim d30Days, dYesterday
' ----------------------------------------------------------
' set up variables for folder locations
sLogPath = "c:\winnt\system32\logfiles\"
sService = "w3svc2\"
sArchive = "c:\winnt\LogArchive\"
' ----------------------------------------------------------
' get yesterday's date
dYesterday = DateAdd( "d", -1, Date() )
' ----------------------------------------------------------
' create a formatted log filename
' for yesterday's log file
sLogFile = FormatLogFileName(dYesterday)
' ----------------------------------------------------------
' Create a file system object
Set oFSO = WScript.CreateObject("Scripting.FileSystemObject")
' ----------------------------------------------------------
' Move the file to the archive path
oFSO.MoveFile sLogPath & sService & sLogFile, _
sArchive & sLogFile
' ----------------------------------------------------------
' get date for 30 days ago
d30Days = DateAdd( "d", -30, Date() )
' ----------------------------------------------------------
' create a formatted log filename
' for 30-day-ago log file
sLogFile = FormatLogFileName(d30Days)
' ----------------------------------------------------------
' Delete the file from the archive path
oFSO.DeleteFile sArchive & sLogFile
Obviously, this didn't include the FormatLogFileName function. Be sure to copy that into the first part of the file before you try to do anything with it. Before you can use this script, you'll need to check a few things.
Make sure the folders specified all exist. For example, if you're on Windows Server 2003, you'll need to change "Winnt" to "Windows" in many cases. Make sure you add the FormatLogFileName function to the beginning of the script, or you'll get an error message.
Log Rotation Script-Explained
One thing you'll notice about my scripts is that I like to use lots of comment lines. These allow me to document what the script is doing; if I have to make changes or figure out what the script is up to a year later, the comment lines help me remember what I was thinking when I originally wrote the script. I even use comment lines with lots of hyphens to create little separators, breaking the script into logical sections.
The first few lines in any script should explain what it does.
' Sample log rotation tool
'
' We'll take yesterday's log and move it to
' an archive folder. We'll delete the log file
' that's 30 days old from the archive
Next, I usually declare the variables I intend to use in the script.
' ----------------------------------------------------------
'declare variables
Dim sLogPath, sService, sArchive, sLogFile
Dim oFSO
Dim d30Days, dYesterday
The first thing in my task list is to define folder locations, and so that's what I do next. Notice that I've actually defined the log file folder path in two parts: the main path and the service. This will make it easier to modify the script to accommodate other Web sites later, if I want.
' ----------------------------------------------------------
' set up variables for folder locations
sLogPath = "c:\winnt\system32\logfiles\"
sService = "w3svc\"
sArchive = "c:\winnt\LogArchive\"
Now, I use VBScript's Date() and DateAdd() functions to figure out yesterday's date. VBScript doesn't have a "DateSubtract" function; instead, just add a negative number. Adding a negative is the same as subtracting.
' ----------------------------------------------------------
' get yesterday's date
dYesterday = DateAdd( "d", -1, Date() )
Now, I'll use that handy FormatLogFileName function to figure out the filename of yesterday's log file.
' ----------------------------------------------------------
' create a formatted log filename
' for yesterday's log file
sLogFile = FormatLogFileName(dYesterday)
Next, I create a reference to the FileSystemObject, which will let me manipulate the log files. I'm storing the reference in a variable named oFSO; the "o" prefix tells me that this variable contains an object reference, and not some kind of data. I also have to remember to use the Set command, because I'm assigning an object reference to the variable, and not just data.
' ----------------------------------------------------------
' Create a file system object
Set oFSO = WScript.CreateObject("Scripting.FileSystemObject")
One of the FileSystemObject's handy methods is MoveFile. It accepts two parameters: the file to move and where to move it. This accomplishes the task of moving the log file into the archive folder.
' ----------------------------------------------------------
' Move the file to the archive path
oFSO.MoveFile sLogPath & sService & sLogFile, _
sArchive & sLogFile
Having accomplished the first major task, I'm ready to delete the oldest log file. I'll need to figure out what date it was 30 days ago, which means using DateAdd() to add a negative 30 days to today's date.
' ----------------------------------------------------------
' get date for 30 days ago
d30Days = DateAdd( "d", -30, Date() )
Now I can use FormatLogFileName again to get the filename from 30 days ago.
' ----------------------------------------------------------
' create a formatted log filename
' for 30-day-ago log file
sLogFile = FormatLogFileName(d30Days)
Finally, use the FileSystemObject's DeleteFile command to delete the old log file.
' ----------------------------------------------------------
' Delete the file from the archive path
oFSO.DeleteFile sArchive & sLogFile
If everything's working well, this script should be ready to run.
Identifying Potential Errors
Re-reading the script, I can think of a few things that might go wrong. For starters, the archive folder might not exist. Also, the log file I'm trying to move might not exist if something was wrong with IIS. In addition, it's possible that someone already deleted the old log file, meaning it won't exist when I try to delete it in the script. Any of these obvious conditions could cause an error that would make my script quit running.
How can I avoid these errors?
Make sure the archive folder exists and, if it doesn't, create it. Make sure files exist before moving or deleting them.
Anticipating what can go wrong allows you to add code to your script to handle potential errors gracefully.
Modified Log Rotation Script
Listing 13.3 presents a modified log rotation script with some error-handling built in.
Listing 13.3. LogRotation2.vbs. This version of the script checks for files and folders rather than assuming they exist.
' Sample log rotation tool
'
' We'll take yesterday's log and move it to
' an archive folder. We'll delete the log file
' that's 30 days old from the archive
' ----------------------------------------------------------
'declare variables
Dim sLogPath, sService, sArchive, sLogFile
Dim oFSO
Dim d30Days, dYesterday
' ----------------------------------------------------------
' set up variables for folder locations
sLogPath = "c:\winnt\system32\logfiles\"
sService = "w3svc2\"
sArchive = "c:\winnt\LogArchive\"
' ----------------------------------------------------------
' get yesterday's date
dYesterday = DateAdd( "d", -1, Date() )
' ----------------------------------------------------------
' create a formatted log filename
' for yesterday's log file
sLogFile = FormatLogFileName(dYesterday)
' ----------------------------------------------------------
' Create a file system object
Set oFSO = WScript.CreateObject("Scripting.FileSystemObject")
' ----------------------------------------------------------
' make sure files and folders exist
' first the archive folder
If Not oFSO.FolderExists(sArchive) Then
oFSO.CreateFolder(sArchvie)
End If
' ----------------------------------------------------------
' Move the file to the archive path
If oFSO.FileExists(sLogPath & sService & sLogFile) Then
oFSO.MoveFile sLogPath & sService & sLogFile, _
sArchive & sLogFile
End If
' ----------------------------------------------------------
' get date for 30 days ago
d30Days = DateAdd( "d", -30, Date() )
' ----------------------------------------------------------
' create a formatted log filename
' for 30-day-ago log file
sLogFile = FormatLogFileName(d30Days)
' ----------------------------------------------------------
' Delete the file from the archive path
If oFSO.FileExists(sArchive & sLogFile) Then
oFSO.DeleteFile sArchive & sLogFile
End If
Can you spot what's changed in the script?
Modified Log Rotation Script-Explained
There are just three major changes to the script. First, I'm using the FileSystemObject's FolderExists() method to ensure that the archive folder exists. If it doesn't, I use the CreateFolder() method to create the folder, automatically handling the problem before it becomes a problem.
' ----------------------------------------------------------
' make sure files and folders exist
' first the archive folder
If Not oFSO.FolderExists(sArchive) Then
oFSO.CreateFolder(sArchvie)
End If
I also modified the code that moves the log file. Now, it's in an If…Then construct that uses the FileSystemObject's FileExists() method to only perform the move if the file exists to begin with.
' ----------------------------------------------------------
' Move the file to the archive path
If oFSO.FileExists(sLogPath & sService & sLogFile) Then
oFSO.MoveFile sLogPath & sService & sLogFile, _
sArchive & sLogFile
End If
Similarly, I modified the line of code that deletes the old log file to only do so if that file already exists.
' ----------------------------------------------------------
' Delete the file from the archive path
If oFSO.FileExists(sArchive & sLogFile) Then
oFSO.DeleteFile sArchive & sLogFile
End If
Now, the script is prepared to handle these anticipated potential problems. Again, be sure to paste in the FormatLogFileName function before attempting to execute this script!
|