Testing the Script
You're ready to test your script. Just to make sure you're on the same page, Listing 13.4 lists the entire log rotation script, including the FormatLogFileName function.
Listing 13.4. LogRotation3.vbs. Here's the entire script, ready to run.
' 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
Function FormatLogFileName(dDate)
Dim sFileName
sFileName = "ex"
Dim sYear
sYear = DatePart("yyyy",dDate)
sYear = Right(sYear,2)
sFileName = sFileName & sYear
Dim sMonth
sMonth = DatePart("m",dDate)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sFileName = sFileName & sMonth
Dim sDay
sDay = DatePart("d",dDate)
If Len(sDay) = 1 Then
sDay = "0" & sDay
End If
sFileName = sFileName & sDay
sFileName = ".log" & sFileName
FormatLogFileName = sFileName
End Function
' ----------------------------------------------------------
'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
Save the script to a .VBS file and double-click to execute it. To make sure it has something to do, make sure you have a log file in the appropriate folder with yesterday's date.
Analyzing the Results
What happens when you run the script? If you type it carefully, or copy it from this book's accompanying CD-ROM, either it doesn't do anything or it gives you an error. That's because the code contains two logic errors.
Logic errors are especially difficult to track down, because VBScript doesn't usually complain about them. As far as VBScript is concerned, everything is just fine. You're the one with the problem, because your script runs, but doesn't do what you want it to do.
There are a couple of ways to catch these errors. Because the errors aren't ones that VBScript cares about, you can't rely on the Script Debugger or other fancy tools. The easiest way to track down the problem is to add debug code.
Adding Debug Code
Debug code is usually as straightforward as a bunch of MsgBox statements that tell you what your script is doing. For example:
sLogFile = FormatLogFileName(d30Days)
MsgBox sLogFile
The boldfaced line of code tells you what the FormatLogFileName function did, by displaying its results. You can use that to double-check what's going on in your code, and find out where things are going wrong.
Log Rotation Script with Debug Code
Listing 13.5 shows the complete log rotation script with debug code added. I've highlighted the debug code in bold so that you can spot it more easily.
Listing 13.5. LogRotation4.vbs. I've added MsgBox statements as a debugging aid.
' 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
Function FormatLogFileName(dDate)
Dim sFileName
sFileName = "ex"
Dim sYear
sYear = DatePart("yyyy",dDate)
sYear = Right(sYear,2)
sFileName = sFileName & sYear
Dim sMonth
sMonth = DatePart("m",dDate)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sFileName = sFileName & sMonth
Dim sDay
sDay = DatePart("d",dDate)
If Len(sDay) = 1 Then
sDay = "0" & sDay
End If
sFileName = sFileName & sDay
sFileName = ".log" & sFileName
FormatLogFileName = sFileName
End Function
' ----------------------------------------------------------
'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() )
MsgBox "Yesterday was " & dYesterday
' ----------------------------------------------------------
' create a formatted log filename
' for yesterday's log file
sLogFile = FormatLogFileName(dYesterday)
MsgBox "Yesterday's log filename is " & sLogFile
' ----------------------------------------------------------
' 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)
MsgBox "Created Folder"
Else
MsgBox "Didn't Create Folder"
End If
' ----------------------------------------------------------
' Move the file to the archive path
If oFSO.FileExists(sLogPath & sService & sLogFile) Then
oFSO.MoveFile sLogPath & sService & sLogFile, _
sArchive & sLogFile
MsgBox "Moved File"
Else
MsgBox "Didn't Move File"
End If
' ----------------------------------------------------------
' get date for 30 days ago
d30Days = DateAdd( "d", -30, Date() )
MsgBox "30 days ago was " & d30Days
' ----------------------------------------------------------
' create a formatted log filename
' for 30-day-ago log file
sLogFile = FormatLogFileName(d30Days)
MsgBox "Log file from 30 days ago was " & sLogFile
' ----------------------------------------------------------
' Delete the file from the archive path
If oFSO.FileExists(sArchive & sLogFile) Then
oFSO.DeleteFile sArchive & sLogFile
MsgBox "Deleted file."
Else
MsgBox "Didn't delete file."
End If
Run the script again and see what happens. Are you surprised by the results?
Log Rotation Script with Debug Code-Explained
Some of the code I added displays the results of operations by tacking a variable onto the MsgBox statement, like this one.
' ----------------------------------------------------------
' create a formatted log filename
' for 30-day-ago log file
sLogFile = FormatLogFileName(d30Days)
MsgBox "Log file from 30 days ago was " & sLogFile
Other sections of code added an If…Then construct. This ensures some kind of feedback on the script's progress, no matter how the If…Then condition turned out.
' ----------------------------------------------------------
' Delete the file from the archive path
If oFSO.FileExists(sArchive & sLogFile) Then
oFSO.DeleteFile sArchive & sLogFile
MsgBox "Deleted file."
Else
MsgBox "Didn't delete file."
End If
Modifying the Script
If you're getting the same results I am, you've probably spotted the logic errors. Here's the first one, in the FormatLogFileName function.
Dim sDay
sDay = DatePart("d",dDate)
If Len(sDay) = 1 Then
sDay = "0" & sDay
End If
sFileName = sFileName & sDay
sFileName = ".log" & sFileName
FormatLogFileName = sFileName
End Function
The problem is in boldface, and the code is actually backward. It's prepending ".log" to the filename that's been built, rather than appending it. The result is that every filename coming out of the function is wrong. You would have noticed this with the debug version of the script because the messages, "Didn't move file" and "Didn't delete file" were displayed. You saw those messages because no file with the incorrect filename existed. Correct this line of code to read
sFileName = sFileName & sDay
sFileName = sFileName & ".log"
FormatLogFileName = sFileName
The next error is a simple typo.
' ----------------------------------------------------------
' make sure files and folders exist
' first the archive folder
If Not oFSO.FolderExists(sArchive) Then
oFSO.CreateFolder(sArchvie)
MsgBox "Created Folder"
Else
MsgBox "Didn't Create Folder"
End If
The result of this code is to see if the archive folder exists, If it doesn't, VBScript attempts to create the folder…except that the wrong variable name is listed. The variable given, sArchive, is empty, and so VBScript tries to create an empty folder. Depending upon how your system is configured, you might have received an error message on this line of code. Correct it to read
' ----------------------------------------------------------
' make sure files and folders exist
' first the archive folder
If Not oFSO.FolderExists(sArchive) Then
oFSO.CreateFolder(sArchive)
MsgBox "Created Folder"
Else
MsgBox "Didn't Create Folder"
End If
By the way, this problem could have been caught earlier if you'd included Option Explicit as the first line of your script. With that option, VBScript requires you to declare all variables; when it spotted the undeclared sArchvie variable, it would have given an immediate error.
You can refresh your memory on Option Explicit by referring to "Declaring Variables" in Chapter 5.
Completing the Script
Listing 13.6 shows the completed, corrected script, with debug code removed. It's ready to use! Note that I've added the Option Explicit statement to help catch any other variable name typos.
Listing 13.6. LogRotation5.vbs. Here's the entire script, ready to run.
Option Explicit
' 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
Function FormatLogFileName(dDate)
Dim sFileName
sFileName = "ex"
Dim sYear
sYear = DatePart("yyyy",dDate)
sYear = Right(sYear,2)
sFileName = sFileName & sYear
Dim sMonth
sMonth = DatePart("m",dDate)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sFileName = sFileName & sMonth
Dim sDay
sDay = DatePart("d",dDate)
If Len(sDay) = 1 Then
sDay = "0" & sDay
End If
sFileName = sFileName & sDay
sFileName = sFileName & ".log"
FormatLogFileName = sFileName
End Function
' ----------------------------------------------------------
'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(sArchive)
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
You can make this script more effective with a little work. For example, as written, the script only works with the first Web site on the server, which uses the W3CSvc folder. You could modify the script to work with multiple folders by including a For…Next construct or some other kind of loop.
Also, the script requires that you remember to run it each day for the best effect. However, you could use the Windows Task Scheduler to automatically run the script each morning at 1 A.M. or some other convenient time. You simply tell Task Scheduler to run Wscript.exe scriptname, where scriptname is the complete path and filename to your log rotation script.
You could even write the script to run against multiple Web servers. That way, it could execute from a single central server and rotate the log files for an entire Web farm. The beauty of scripting is that you're in complete control, so you can have the script do anything you like to suit your environment and meet your particular administrative needs. |
|