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
- Error and Event Logging in VB.NET
- Write Error Log using VB.NET
- Writing exceptions in log files (Logger class in VB.Net)
- Best practices of Exception Management in VB.NET
- LOG-Datei zur Fehlerprotokollierung (.NET)
- EventLog-Klasse
- Write to the Event Log in VB.Net