Es gibt im Internet eine Vielzahl von Anleitungen für die Erstellung von LogFiles (siehe Links). Trotzdem möchte ich an dieser Stelle meine Lösung präsentieren.

LogFile + EventLog

Imports System
Imports System.IO
Imports System.Data
Imports System.Diagnostics

Module ErrorLog
    Private filePath As String
    Private fileStream As FileStream
    Private streamWriter As StreamWriter
    Private EventLogCounter As Integer = 0

    Public Sub OpenLogFile(Optional ByVal LogFileName As String = "")
        ' Name der Logfile, wenn kein Name übergeben wurde 
        If LogFileName.Length = 0 Then
            ' Dateiname anhand des aktuellen Datums festlegen
            LogFileName = Application.StartupPath & "\EventLog_" & _
              Format$(Now, "yyyy-MM-dd") & ".log"
        End If
        filePath = LogFileName

        ' Datei öffen (Text anhängen) - gegebenfalls erstellen
        If System.IO.File.Exists(LogFileName) Then
            fileStream = New FileStream(LogFileName, FileMode.Append, FileAccess.Write)
        Else
            fileStream = New FileStream(LogFileName, FileMode.Create, FileAccess.Write)
        End If
        streamWriter = New StreamWriter(fileStream)

    End Sub


    Public Sub LogMessage(ByVal ErrorLevel As Integer, ByVal Message As String, Optional ByVal LogFileName As String = "", Optional ByVal closefile As Boolean = False)
        Try
            If IsNothing(streamWriter) Then
                Call OpenLogFile(LogFileName)
            Else
                If filePath <> LogFileName Then 'Prüfen, ob eine anderer Datei vielleicht offen ist 
                    CloseLogFile()
                    OpenLogFile(LogFileName)
                End If
            End If

            Call RealLogMessage(ErrorLevel, Message)
            If closefile = True Then
                CloseLogFile()
            End If
        Catch ex As System.ObjectDisposedException
            Call OpenLogFile(LogFileName)
            RealLogMessage(ErrorLevel, Message)
            If closefile = True Then
                CloseLogFile()
            End If
        Catch ex As Exception
            Debug.Print("!")
        End Try
    End Sub

    Public Sub RealLogMessage(ByVal ErrorLevel As Integer, ByVal Message As String)
        Select Case ErrorLevel
            Case 1
                streamWriter.WriteLine(Now.ToString & "[Information] -" & Message)
            Case 2
                streamWriter.WriteLine(Now.ToString & "[SQL Information] -" & Message)
            Case 3
                streamWriter.WriteLine(Now.ToString & "[Warning] -" & Message)
                WriteToEventLog(Message, , EventLogEntryType.Warning)
            Case 4
                streamWriter.WriteLine(Now.ToString & "[Error] -" & Message)
                WriteToEventLog(Message, , EventLogEntryType.Error)
            Case 5
                streamWriter.WriteLine(Now.ToString & "[Critical Error] -" & Message)
                WriteToEventLog(Message, , EventLogEntryType.Error)
        End Select
    End Sub

    Public Sub CloseLogFile()
        Try
            streamWriter.Close()
            fileStream.Close()
        Catch ex As Exception

        End Try
    End Sub


    Public Function WriteToEventLog(ByVal entry As String, Optional ByVal appName As String = "VB.NET Application", Optional ByVal eventType As  _
                    EventLogEntryType = EventLogEntryType.Information, _
                    Optional ByVal logName As String = "Anwendung") As Boolean
        Dim objEventLog As New EventLog()
        Try
            'Register the Application as an Event Source
            If Not EventLog.SourceExists(appName) Then
                EventLog.CreateEventSource(appName, logName)
            End If
            'log the entry
            objEventLog.Source = appName
            objEventLog.WriteEntry(entry, eventType)
            Return True
        Catch ex As Security.SecurityException
            If EventLogCounter = 0 Then
                RealLogMessage(1, "Can't write to EventLog because of Security Setting." & vbNewLine & "see http://msdn.microsoft.com/de-de/library/6s7642se.aspx")
                EventLogCounter = 1
            End If
            Return False
        Catch Ex As Exception
            Return False
        End Try
    End Function
End Module

Erweiterung

Je nach Umfang des Projektes logge ich unterschiedlich viel mit, was insbesonderer bei der Fehlersuche recht hilfreich ist. Da aber in der Endversion meist nur ein Bruchteil mitgeloggt werden soll, habe ich folgende Änderungen in oben genannten Code eingefügt. Mittels der Private Variable (StartLogging) kann eingestellt werden, ab welchem „ErrorLevel“ wirklich mitgeloggt werden soll.

Erweiterung

Private StartLogging As Integer = 1
...
    Public Sub LogMessage(ByVal ErrorLevel As Integer, ByVal Message As String, Optional ByVal LogFileName As String = "", Optional ByVal closefile As Boolean = False)
        If ErrorLevel >= StartLogging Then
            Try
                If IsNothing(streamWriter) Then
                    Call OpenLogFile(LogFileName)
                Else
                    If filePath <> LogFileName Then 'Prüfen, ob eine anderer Datei vielleicht offen ist 
                        CloseLogFile()
                        OpenLogFile(LogFileName)
                    End If
                End If

                Call RealLogMessage(ErrorLevel, Message)
                If closefile = True Then
                    CloseLogFile()
                End If
            Catch ex As System.ObjectDisposedException
                Call OpenLogFile(LogFileName)
                RealLogMessage(ErrorLevel, Message)
                If closefile = True Then
                    CloseLogFile()
                End If
            Catch ex As Exception
                Debug.Print("!")
            End Try
        End If
    End Sub

Problem unter Windows 7

Unter Windows 7 bekommt man für gewöhnlich die Fehlermeldung: „Die Quelle wurde nicht gefunden, aber einige oder alle Ereignisprotokolle konnten nicht durchsucht werden. Protokolle, auf die kein Zugriff möglich war: Security.“ In der MSDN steht dazu 

Hinweis

Um in Windows Vista und höher oder Windows Server 2003 nach einer Ereignisquelle zu suchen, müssen Sie Administratorrechte haben. 
Der Grund für diese Anforderung besteht darin, dass alle Ereignisprotokolle, einschließlich der für die Sicherheit, durchsucht werden müssen, um zu bestimmen, ob die Ereignisquelle eindeutig ist. Mit Windows Vista beginnend, verfügen Benutzer nicht über die Berechtigung, auf das Sicherheitsprotokoll zuzugreifen; daher wird ein SecurityException ausgelöst. 
Mit Windows Vista beginnend, bestimmt Benutzerkontensteuerung (UAC) die Rechte eines Benutzers. Als Mitglied der integrierten Administratorgruppe sind Ihnen zwei Zugriffstoken für die Laufzeit zugewiesen: ein Standardbenutzertoken und ein Administratorzugriffstoken. Standardmäßig verwenden Sie die Standardbenutzerrolle. Um Code ausführen zu können, der auf Leistungsindikatoren zugreift, müssen Sie zuerst Ihre Berechtigungen von Standardbenutzer auf Administrator erhöhen. Dazu starten Sie eine Anwendung, indem Sie mit der rechten Maustaste auf das Anwendungssymbol klicken und angeben, dass Sie die Anwendung als Administrator ausführen möchten.

Links

Icon

ErrorLogWriter 9.91 KB 424 downloads

...
Icon

ErrorLog 1.28 KB 199 downloads

...