Reverting log files back to the default W3C fields

Recently I had to work with a customer that was trying to use a 3rd-party utility that read W3C log files and it was failing to complete processing. I had the customer send me his log files, and upon examination I discovered that the trouble was occuring because the customer had been experimenting with adding and removing the different fields from their log files and this was causing the log parsing utility to crash.

As luck would have it, IIS provides a useful logging utility object that you can read more about at the following URL:

http://www.microsoft.com/windows2000/en/server/iis/htm/asp/comp6ant.htm

I had used this logging utility object for an earlier project, so I was familiar with how it worked. With that knowledge in mind, I wrote the following script that loops through all of the log files in a folder and creates new log files in a subfolder that contain only the default W3C fields. (BTW - I sent this script to the customer and he was able to parse all of his log files successfully. ;-] )

Option Explicit
Randomize Timer

' Declare variables.

Dim objIISLog
Dim objFSO, objFolder, objFile
Dim objOutputFile, strInputFile
Dim strOutputFile, strOutputPath
Dim strLogRecord
Dim blnExists

' Create file system object.
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
' Retrieve an object For the current folder.
Set objFolder = objFSO.GetFolder(".")

' Create a subfolder with a random name.
blnExists = True
Do While blnExists = True
 strOutputPath = objFolder.Path & "\" & CreateRandomName(20)
 blnExists = objFSO.FolderExists(strOutputPath)
Loop
objFSO.CreateFolder strOutputPath

' Loop through the log files in the current folder.
For Each objFile In objFolder.Files

 ' Test for a log file.
 If Right(LCase(objFile.Name),4) = ".log" Then

  ' Format the file names/paths.
  strInputFile = objFolder.Path & "\" & objFile.Name
  strOutputFile = strOutputPath & "\" & objFile.Name

  ' Create and open an IIS logging object.
  Set objIISLog = CreateObject("MSWC.IISLog")
  ' Open the input log file.
  objIISLog.OpenLogFile strInputFile, 1, "", 0, ""  
  ' Open the output log file.
  Set objOutputFile = objFSO.CreateTextFile(strOutputFile)

  ' Read the initial record from the log file.
  objIISLog.ReadLogRecord

  ' Write the headers to the output log file.
  objOutputFile.WriteLine "#Software: Microsoft Internet Information Services 5.0"
  objOutputFile.WriteLine "#Version: 1.0"
  objOutputFile.WriteLine "#Date: " & BuildDateTime(objIISLog.DateTime)
  objOutputFile.WriteLine "#Fields: date time c-ip cs-username s-ip s-port " & _
   "cs-method cs-uri-stem cs-uri-query sc-status cs(User-Agent)"

  ' Loop through the records in the log file.
  Do While Not objIISLog.AtEndOfLog

   ' Format the log file fields.
   strLogRecord = BuildDateTime(objIISLog.DateTime)
   strLogRecord = strLogRecord & _
    " " & FormatField(objIISLog.ClientIP) & _
    " " & FormatField(objIISLog.UserName) & _
    " " & FormatField(objIISLog.ServerIP) & _
    " " & FormatField(objIISLog.ServerPort) & _
    " " & FormatField(objIISLog.Method) & _
    " " & FormatField(objIISLog.URIStem) & _
    " " & FormatField(objIISLog.URIQuery) & _
    " " & FormatField(objIISLog.ProtocolStatus) & _
    " " & FormatField(objIISLog.UserAgent)
   
   ' Write the output log file record.
   objOutputFile.WriteLine strLogRecord

   ' Read the next record from the log file.
   objIISLog.ReadLogRecord

  Loop

  ' Close the input log file.
  objIISLog.CloseLogFiles 1
  objIISLog = Null
 
 End If

Next

' Inform the user that the operation has completed.
MsgBox "Finished!"

' Format a log file field.
Function FormatField(tmpField)
 On Error Resume Next
 FormatField = "-"
 If Len(tmpField) > 0 Then FormatField = Trim(tmpField)
End Function

' Format a log file date.
Function BuildDateTime(tmpDateTime)
 On Error Resume Next
 tmpDateTime = CDate(tmpDateTime)
 BuildDateTime = Year(tmpDateTime) & "-" & _
  Right("0" & Month(tmpDateTime),2) & "-" & _
  Right("0" & Day(tmpDateTime),2) & " " & _
  Right("0" & Hour(tmpDateTime),2) & ":" & _
  Right("0" & Minute(tmpDateTime),2) & ":" & _
  Right("0" & Second(tmpDateTime),2)
End Function

' Create a random name.
Function CreateRandomName(intNameLength)
 Const strValidChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
 Dim tmpX, tmpY, tmpZ
 For tmpX = 1 To intNameLength
  tmpY = Mid(strValidChars,Int(Rnd(1)*Len(strValidChars))+1,1)
  tmpZ = tmpZ & tmpY
 Next
 CreateRandomName = tmpZ
End Function

Happy coding!

No Comments