Previous Section Table of Contents Next Section

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.

graphics/arrow.gif 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?

graphics/arrow.gif 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

Polishing Your Script

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.


    Previous Section Table of Contents Next Section