If anyone has ever used any of the Log4N loggers, that is loosely what I bassed this class on. It will let you instantiate a logger object that will hopefully safely handle things like file opening and closing in a smart error free fashion. It let's you select one of 5 log levels: SEVERE, WARN, INFO, DEBUG, NOLOG. For the selscted level, any logline that is called with that level or higher importance will be logged. NOLOG is a special case in that if you set the log level to NOLOG, then nothing will ever be written to the log file. You can also set the indentation level and the character that is used for indentation. This allows for rudimentary formatting of the log. In our environment, we implement this as a wsc file and register it as a com object. Please provide any feedback that you feel is appropriate.
Class Logger
'=====================================================================================
'
' Class: Logger
' Author: ###
'
' Public Properties:
' LogLoc - Log file path and file name - Default:c:\temp\<ScriptName>.Log
' AppendMode - Whether or not to append to an existing log file. This defaults
' to True. If you want it to be False, it must be set before
' LogLoc is set.
' FilterLevel - There are currently three valid filter levels. They are
' "NOLOG", "SEVERE", "WARNING", "INFO", and "DEBUG". If a logline is sent to
' the logger it will only be logged if its level is greater than or
' equal to FilterLevel. Thus if FilterLevel is set to WARNING, only
' lines with "WARNING" or "SEVERE" level will actually be logged.
'
' Public Methods:
' LogLine(strLvl, strMsg) - Logs strMsg to the log file at LogLoc if strLvl is
' greater than FilterLevel.
' LogBlankLine - Places a blank line in the log file.
' LogNoStamp(strLvl, strMsg) - Logs to the file according to the same level rules as
' LogLine.
'
' To Do:
' - Allow AppendMode to be set anytime before the first LogLine call
' - Allow the use of an xml based config file
' - Allow for adding STDOUT in addition to logging
'
' Revision History:
' 7/21/04 - RMD - Initial creation
' 7/22/04 - RMD - Changed the default location to use the script name
' 7/22/04 - RMD - Added SmartFileOpen to allow the construction of the path
' to the log file dynamically.
' 1/19/05 - RMD - Added the VerboseMode property to cause output to got to STDOUT as it is
' looged if VerboseMode is set to True.
' 3/11/05 - RMD - Added the NOLOG filter to give a means for turning off logging
' 7/29/05 - RMD - Changed the date/time stamp format to YYYY-MM-DD-hh:mm:ss
' 7/29/05 - RMD - Added the IndentLevel property to control the level of indentation
' 7/29/05 - RMD - Added the IndentChar property to set the character used to indent
' default is vbTab
'
'======================================================================================
Private strLogFile 'This is the internal var for the path and name of the Log
Private bAppend 'Internal bool to control whether the log appends or Not
Private nFilterLevel 'Controls what level of messages are shown
Private dAllowableFilters 'Dictionary to hold the allowable logging levels
Private nAppendMode 'Integer to set the append mode when the file is actually opened
Private bFirstWrite 'Used to track the first time a message is logged for append
Private bVerbose 'Determines if info is output to STDOUT as it is logged default is False
Private nIndentLevel 'Set the indentation level
Private strIndentChar 'Character used for Indentation defaults to vbTab
'======================================================================================
'
' Class constructor
' Notes:
' Sets default values for log file name, append mode, and log level. Also builds
' the dictionary of allowable logging levels.
'
'======================================================================================
Private Sub Class_Initialize
strLogFile = Replace(WScript.ScriptFullName, WScript.ScriptName, "") _
& Split(WScript.ScriptName, ".")(0) & ".log"
bAppend = True
nAppendMode = 8
Set dAllowableFilters = CreateObject("Scripting.Dictionary")
dAllowableFilters.Add "NOLOG", 4
dAllowableFilters.Add "SEVERE", 3
dAllowableFilters.Add "WARNING", 2
dAllowableFilters.Add "INFO", 1
dAllowableFilters.Add "DEBUG", 0
nFilterLevel = dAllowableFilters("DEBUG")
bFirstWrite = False
bVerbose = False
nIndentLevel = 0
strIndentChar = vbTab
End Sub
'======================================================================================
'
' IndentLevel Getter and Setter
' Notes:
' Set the level of indentation
'
'======================================================================================
Public Property Let IndentLevel(nLvl)
nIndentLevel = nlvl
End Property
Public Property Get IndentLevel
IndentLevel = nIndentLevel
End Property
'======================================================================================
'
' IndentChar Getter and Setter
' Notes:
' Set the character used for indentation default is vbTab
'
'======================================================================================
Public Property Let IndentChar(strChar)
strIndentChar = strChar
End Property
Public Property Get IndentChar
IndentChar = strIndentChar
End Property
'======================================================================================
'
' VerboseMode Getter and Setter
' Notes:
' Control the log path and filename
'
'======================================================================================
Public Property Let VerboseMode(bMode)
If UCase(CStr(bMode)) = "TRUE" Or UCase(CStr(bMode)) = "FALSE" Then bVerbose = bMode
End Property
Public Property Get VerboseMode
VerboseMode = bVerbose
End Property
'======================================================================================
'
' LogLoc Getter and Setter
' Notes:
' Control the log path and filename
'
'======================================================================================
Public Property Let LogLoc(strName)
Dim oFSO, oFile
' Open the log file create it if it does not exist
strLogFile = strName
End Property
Public Property Get LogLoc
LogLoc = strLogFile
End Property
'======================================================================================
'
' AppendMode Getter and Setter
' Notes:
' Control the append behavior for the log
'
'======================================================================================
Public Property Let AppendMode(bMode)
bAppend = bMode
If bAppend Then
nAppendMode = 8
Else
nAppendMode = 2
End If
End Property
Public Property Get AppendMode
AppendMode = bAppend
End Property
'======================================================================================
'
' FilterLevel
' Notes:
' Controls the level of logging to write to the log
'
'======================================================================================
Public Property Let FilterLevel(strLvl)
nFilterLevel = dAllowableFilters("DEBUG")
If dAllowableFilters.Exists(UCase(strLvl)) Then
nFilterLevel = dAllowableFilters(UCase(strLvl))
End If
End Property
Public Property Get FilterLevel
Dim strLevel
For Each strLevel In dAllowableFilters.Keys()
If nFilterLevel = dAllowableFilters(strLevel) Then
FilterLevel = strLevel
Exit Property
End If
Next
FilterLevel = "UNKNOWN"
End Property
'======================================================================================
'
' RotateLog
' Notes:
' Rotates the log file based on file size. The size in MB is passed to the
' function. If the log file is bigger than this, the log file will be renamed
' to the current name prepended with BU-. If this file already exists, the
' existing one will be deleted.
'
'======================================================================================
Public Sub RotateLog(dblMB)
Dim oFSO
Dim oFile
Dim strBUFile
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.GetFile(strLogFile)
'Check for an existing bu file and delete if there
'See if the current logfile is over the limit
If (oFile.Size/(2^20)) < dblMB Then
'WScript.Echo "File Size = " & oFile.Size/(2^20) & " which is smaller than " & dblMB
Set oFile = Nothing
Set oFSO = Nothing
Exit Sub
End If
LogLine INF, "Rotating the logfile. The cureent log is greater than " & dblMB & "Mb"
strBUFile = oFile.ParentFolder & "\BU-" & oFile.Name
'WScript.Echo strBUFile
If oFSO.FileExists(strBUFile) Then
LogLine INF, "There is an existing backup log named " & strBUFile & ". It will be deleted"
oFSO.DeleteFile strBUFile, True
End If
'Rename the existing log
LogLine INF, "Renaming the current log to " & strBUFile
oFSO.MoveFile oFile.Path, strBUFile
Set oFile = Nothing
Set oFSO = Nothing
'Log to the new Log
LogLine INF, "Starting new logfile after log rotation. The backup log is named " & strBUFile
End Sub
'======================================================================================
'
' LogBlankLine
' Notes:
' Logs a blank line with no timestamp. This is really redundant because it Is
' the same as .LogNoStamp ""
'
'======================================================================================
Public Sub LogBlankLine
Dim oFSO, oFile
If Not nFilterLevel = 4 THen
If strLogFile = "" Then
strLogFile = "C:\Temp\" & Split(WScript.ScriptName, ".")(0) & ".log"
End If
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = SmartOpenFile(strLogFile, nAppendMode, True)
If bVerbose Then WScript.Echo ""
oFile.WriteLine ""
Set oFSO = Nothing
oFile.Close
Set oFile = Nothing
If bFirstWrite = False Then
'bAppend = True
nAppendMode = 8
End If
End If
End Sub
'======================================================================================
'
' LogNoStamp
' Notes:
' Logs a line without prepending a date time stamp. Useful for multiline output
' of a single chunk of information.
'
'======================================================================================
Public Sub LogNoStamp(strLvl, strMsg)
Dim oFSO, oFile
If strLogFile = "" Then
strLogFile = "C:\Temp\" & Split(WScript.ScriptName, ".")(0) & ".log"
End If
If Not dAllowableFilters.Exists(UCase(strLvl)) Then
strLvl = "DEBUG"
End If
If dAllowableFilters(UCase(strLvl)) >= nFilterLevel Then
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = SmartOpenFile(strLogFile, nAppendMode, True)
strMsg = String(nIndentLevel, strIndentChar) & strMsg
If bVerbose Then WScript.Echo strMsg
oFile.WriteLine strMsg
Set oFSO = Nothing
oFile.Close
Set oFile = Nothing
If bFirstWrite = False Then
'bAppend = True
nAppendMode = 8
End If
End If
End Sub
'======================================================================================
'
' LogLine
' Notes:
' Logs a line of text prepending a date/time stamp and the severity level of the
' message.
'
'======================================================================================
Public Sub LogLine (strLvl, strMsg)
Dim oFSO, oFile
If strLogFile = "" Then
strLogFile = "C:\Temp\" & Split(WScript.ScriptName, ".")(0) & ".log"
End If
If Not dAllowableFilters.Exists(UCase(strLvl)) Then
strLvl = "DEBUG"
End If
If dAllowableFilters(UCase(strLvl)) >= nFilterLevel Then
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = SmartOpenFile(strLogFile, nAppendMode, True)
strMsg = GetLogTime & "[" & UCase(strLvl) & "] - " _
& String(nIndentLevel, strIndentChar) & strMsg
If bVerbose Then WScript.Echo strMsg
oFile.WriteLine strMsg
Set oFSO = Nothing
oFile.Close
Set oFile = Nothing
If bFirstWrite = False Then
'bAppend = True
nAppendMode = 8
End If
End If
End Sub
'======================================================================================
'
' GetLogTime
' Notes:
' Returns a date/time stamp in the format YYYYMMddmmss
'
'======================================================================================
Private Function GetLogTime()
Dim strNow
strNow = Now()
GetLogTime = Year(strNow) & "-" & Pad(Month(strNow), 2, "0", True) & "-" _
& Pad(Day(strNow), 2, "0", True) & "-" & Pad(Hour(strNow), 2, "0", True) _
& ":" & Pad(Minute(strNow), 2, "0", True) _
& ":" & Pad(Second(strNow), 2, "0", True)
End Function 'GetLogTime()
'======================================================================================
'
' Pad
' Notes:
' Pads a string to a specified length using the specified character by appending
' or prepending.
'
'======================================================================================
Private Function Pad(strText, nLen, strChar, bFront)
Dim nStartLen
If strChar = "" Then
strChar = "0"
End If
nStartLen = Len(strText)
If Len(strText) >= nLen Then
Pad = strText
Else
If bFront Then
Pad = String(nLen - Len(strText), strChar) & strText
Else
Pad = strText & String(nLen - Len(strText), strChar)
End If
End If
End Function
'======================================================================================
'
' SmartOpenFile
' Notes:
' Opens a file building any directory structure that is required.
'
'======================================================================================
Private Function SmartOpenFile(strPath, nMode, bCreate)
'Creates the path to the file if bCreate = True
Dim arrPath, i, oFSO, nErr, strErr
Set oFSO = CreateObject("Scripting.FileSystemObject")
arrPath = Split(strPath, "\")
If UBound(arrPath) < 1 Then
'Invalid path
Set SmartOpenFile = Null
Exit Function
End If
If bCreate Then
strPath = arrPath(0)
For i = 1 To UBound(arrPath) - 1
strPath = strPath & "\" & arrPath(i)
On Error Resume Next
oFSO.CreateFolder(strPath)
nErr = Err.Number : strErr = Err.Description
LogLine "DEBUG", "In SmartOpenFile creating " & strPath & " " & nErr _
& ") - " & strErr
On Error Goto 0
Next
End If
strPath = Join(arrPath, "\")
On Error Resume Next
Set SmartOpenFile = oFSO.OpenTextFile(strPath, nMode, bCreate)
On Error Goto 0
End Function
End Class
<message edited by ebgreen on Monday, August 15, 2005 7:47 AM>