Some years ago I worked with a team and we discovered that a major issue at a customer site was simply because logging used up all of the available disk space.
Recently I wrote a small service. I wanted to log any errors, but needed to make sure the log file didn't grow forever.
I came up with the following code:
Expand|Select|Wrap|Line Numbers
- Private Sub Logit(ByVal Message As String, Optional MaxEntries As Integer = 99)
- Static LogLines As New List(Of String)
- Static LogFile As New FileInfo(My.Application.Info.DirectoryPath & "\Sandbox.log")
- If LogLines.Count = 0 Then
- If LogFile.Exists Then
- Try
- LogLines = IO.File.ReadAllLines(LogFile.FullName).ToList
- Catch ex As Exception
- Exit Sub 'there's nothing we can do really...
- End Try
- End If
- End If
- 'clean up the message
- If Message.EndsWith(Environment.NewLine) Then
- Message = Message.Substring(0, Message.Length - 2)
- End If
- Message = System.DateTime.Now & " " & Message
- LogLines.Add(Message)
- 'make sure we keep only MaxEntries entries
- Do While LogLines.Count > Me.MaxLogLines
- LogLines.RemoveAt(0)
- Loop
- Try
- IO.File.WriteAllLines(LogFile.FullName, LogLines)
- Catch ex As Exception
- 'There's no where to log it so just ignore error
- End Try
- End Sub
When using this routine I recommend you do not use a "magic" number each time it is called (e.g. Logit(MyMessage, 150)). Instead use a const (e.g. Logit(MyMessage, MY_MAX_LOG_ENTRIES)).
Calling the routine with different numbers could cause very confusing results. I also don't like how the log file name is created in the sub. But for small programs this is simple and straight-forward.
A better way to do this would be to create a class that forces you to initialize it to the max entries and filename - that would be cleaner and would look like this:
Expand|Select|Wrap|Line Numbers
- Imports System.IO
- Public Class LimitLog
- Sub New(ByVal MaxLogLines As Integer, LogFileName As String)
- Me.MaxLogLines = MaxLogLines
- Me.LogFileName = New FileInfo(LogFileName)
- End Sub
- Sub New(LogFileName As String)
- Me.LogFileName = New FileInfo(LogFileName)
- End Sub
- Public Property MaxLogLines As Integer = 99
- Public Property LogFileName As FileInfo
- Public Sub Logit(ByVal Message As String)
- Static LogLines As New List(Of String)
- If LogLines.Count = 0 Then
- If Me.LogFileName.Exists Then
- Try
- LogLines = IO.File.ReadAllLines(Me.LogFileName.FullName).ToList
- Catch ex As Exception
- Exit Sub 'there's nothing we can do really...
- End Try
- End If
- End If
- 'clean up the message
- If Message.EndsWith(Environment.NewLine) Then
- Message = Message.Substring(0, Message.Length - 2)
- End If
- Message = System.DateTime.Now & " " & Message
- LogLines.Add(Message)
- 'make sure we keep only MaxEntries entries
- Do While LogLines.Count > Me.MaxLogLines
- LogLines.RemoveAt(0)
- Loop
- Try
- IO.File.WriteAllLines(Me.LogFileName.FullName, LogLines)
- Catch ex As Exception
- 'There's no where to log it so just ignore error
- End Try
- End Sub
- End Class
Friend MyLogger As New LimitLog(150, MyLogFileName)
or
Friend MyLogger As New LimitLog(MyLogFileName)
Notice the class has two (overloaded) New subs. One allows you to initialize the object with both the maximum number of entries and the logs filename. The other just gets the filename and uses the default of 99 entries.
Notice there is no New() sub (without parameters) - this forces you to set either the filename and the maximum number of lines or just the filename when you create the object. This is neater and cleaner - far less prone to errors. Now each call to MyLogger.Logit is just the message and it will be added to the end of the log file.
A note on error checking
You may wish to put in a little more error checking. Notice however that the two error checks I make simply fall-through and are ignored - that's because this is a log file routine intended to log errors - so if there is an error inside of it - well, there's nowhere else to log an error...
Of course - improvements to this code are very welcome - you can post right here.
I've included the class as a zip file for the ultra lazy. Enjoy!