Tipp-Upload: VB.NET 0142: Logger
von Spatzenkanonier
Hinweis zum Tippvorschlag
Dieser Vorschlag wurde noch nicht auf Sinn und Inhalt überprüft und die Zip-Datei wurde noch nicht auf schädlichen Inhalt hin untersucht.
Bitte haben Sie ein wenig Geduld, bis die Freigabe erfolgt.
Über den Tipp
Dieser Tippvorschlag ist noch unbewertet.
Der Vorschlag ist in den folgenden Kategorien zu finden:
- Dateien und Laufwerke
- Sonstiges
Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
Logging, LogFile, My, ApplicationEvents, Exception, Ausnahmen
Der Vorschlag wurde erstellt am: 06.11.2007 23:13.
Die letzte Aktualisierung erfolgte am 05.02.2009 15:45.
Beschreibung
Logger ist eine sehr einfache Klasse, mit der man komfortabel beliebige Meldungen in ein LogFile schreiben kann. Das LogFile wird ordentlich im Anwendungs-Daten-Verzeichnis plaziert (wie man es eigentlich machen sollte). Gezeigt wird auch, wie man anwendungsweit unbehandelte Ausnahmen loggen kann. Ein "Absturz" des Programms wird dadurch nicht unterdrückt, da m.E. i.A. der sofortige Abbruch die einzig verantwortliche Aktion ist, um die gravierenden Folgeschäden abzuwenden, die auftreten können, wenn ein Programm instabil weiterläuft.
Anmerkungen:
1) Dieses Beispiel funktioniert nur in Windows Applications, die als Einzelinstanz laufen (Letzteres kann man durch eine entsprechende Einstellung in den Projekteigenschaften erzwingen).
2) Es gibt (auch kostenlos) Tools, die flexibleres und leistungsfähigeres Logging bereitstellen.
3) Es gibt auch anspruchsvollere Logging-Konzepte, als dieses "Schreibe, wenn ich sage".
Schwierigkeitsgrad |
Verwendete API-Aufrufe: |
Download: |
' Dieser Source stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' ' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird. ' In den Zip-Dateien ist er jedoch zu finden. ' ------------ Anfang Projektgruppe ErrorLog.sln ------------ ' ----------- Anfang Projektdatei ErrorLog.vbproj ----------- ' ------------ Anfang Datei ApplicationEvents.vb ------------ ' IDE-Voreinstellungen: ' Option Strict On ' Option Explicit On ' Projekt-Voreinstellungen: ' Imports System.Windows.Forms ' Imports Microsoft.VisualBasic.ControlChars Imports Microsoft.VisualBasic.ApplicationServices Namespace My ' Diese nützliche Datei wird generiert und geöffnet, wenn man in den ' Anwendungseinstellungen auf "Anwendungsereignisse anzeigen" klickst Partial Friend Class MyApplication ' #Const HideErrLogDisplay = True '2 Möglichkeiten, UnhandledExceptions zu loggen #If HideErrLogDisplay Then ' Diese Variante behandelt UnhandledExceptions nur in ' der kompilierten Exe, läßt im DebugMode die IDE ihren ' Job tun Private Sub MyApplication_UnhandledException( _ ByVal sender As Object, _ ByVal e As UnhandledExceptionEventArgs) Handles Me.UnhandledException Logger.Entry(e.ExceptionObject).Add(Now).OpenLogFile() End Sub #Else ' Diese Variante zeigt das ErrorLogFile auch an, wenn in der IDE gedebugt wird Private Sub MyApplication_Startup(ByVal sender As Object, ByVal e As _ StartupEventArgs) Handles Me.Startup AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf AD_UnhandledException End Sub Private Sub AD_UnhandledException( _ ByVal sender As Object, ByVal e As System.UnhandledExceptionEventArgs) Logger.Entry(e.ExceptionObject).Add(Now).OpenLogFile() End Sub #End If End Class ' MyApplication End Namespace ' My ' ------------- Ende Datei ApplicationEvents.vb ------------- ' --------------- Anfang Datei frmErrorLog.vb --------------- Public Class frmErrorLog Private Sub cmdLogText_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles cmdLogText.Click Logger.Entry("Hi!").Add("I am a Logging-Entry") ' andere Schreibweise mit selbem Ergebnis: ' Logger.Entry("Hi", Lf, "I am a Logging-Entry") End Sub Private Sub cmdLogWithTimestamp_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles cmdLogWithTimestamp.Click ' Timestamp anfügen ist so einfach, dass ich nicht mal eine extra Sub dafür spendiere Logger.Entry(Now).Add("Hi!").Add("I am a Logging-Entry with timestamp") End Sub Private Sub cmdLogException_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles cmdLogException.Click ' Beispiel, eine gefangene Exception zu loggen (mit Timestamp) Try Dim Lb As Label = DirectCast(sender, Label) Catch ex As Exception Logger.Entry(Now).Add(ex) End Try End Sub Private Sub cmdUnhandledException_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles cmdUnhandledException.Click ' Dieser Fehler wird in den globalen ApplicationEvents behandelt werden Dim Lb As Label = DirectCast(sender, Label) End Sub Private Sub cmdOpenLog_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles cmdOpenLog.Click Logger.OpenLogFile() End Sub End Class ' ---------------- Ende Datei frmErrorLog.vb ---------------- ' ------------------ Anfang Datei Logger.vb ------------------ Imports System.Text Imports System.IO ' Durch Verwendung des Interfaces erwirke ich, daß die Intellisense bei Verwendung dieser ' Methoden nur wesentliche Member anbietet Public Interface ILogger Function Add(ByVal ParamArray Segments() As Object) As ILogger Sub OpenLogFile() End Interface Public Class Logger Implements ILogger Private _LogFile As String Private Shared ReadOnly _Singleton As New Logger Private WithEvents _AppDomain As AppDomain Private _Writer As StreamWriter Private Sub New() Dim Segments As String() = { Environment.GetFolderPath( _ Environment.SpecialFolder.ApplicationData), Application.CompanyName, _ Application.ProductName, "Errors", "Error.txt"} _LogFile = String.Join(Path.DirectorySeparatorChar, Segments) Dim sDir As String = Path.GetDirectoryName(_LogFile) If Not Directory.Exists(sDir) Then Directory.CreateDirectory(sDir) _Writer = New StreamWriter(_LogFile, Append:=False, Encoding:=Encoding.UTF8) _AppDomain = AppDomain.CurrentDomain End Sub Public Shared Function Entry(ByVal ParamArray Segments() As Object) As ILogger Return _Singleton.Entry1(Segments) End Function Public Shared Sub OpenLogFile() _Singleton.OpenLogFile1() End Sub Private Function Entry1(ByVal ParamArray Segments() As Object) As ILogger ' Die Einträge können auch wesentlich aufwändiger formatiert werden (z.B. Xml generieren). ' z.B. könnte hier auch ein Timestamp generiert werden. _Writer.WriteLine() Add(Segments) Return Me End Function Private Function Add(ByVal ParamArray Segments() As Object) As ILogger _ Implements ILogger.Add For Each Obj As Object In Segments If Obj Is Nothing Then _Writer.Write("#Null#") Else _Writer.Write(Obj.ToString) End If Next _Writer.WriteLine() ' Da Add() den Singleton selbst zurückgibt, kann man mehrere Aufrufe aneinanderketten. ' Das schreibt sich einfacher als ein With-Block und ist z.T. sogar besser lesbar. Return Me End Function Private Sub OpenLogFile1() Implements ILogger.OpenLogFile _Writer.Flush() ' akt. Puffer wegschreiben ' LogFile mit Extension-spezifischer Anwendung öffnen System.Diagnostics.Process.Start(_LogFile) End Sub Private Sub AppDomain_ProcessExit(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles _AppDomain.ProcessExit _Writer.Dispose() End Sub Private Sub AppDomain_UnhandledException( _ ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs) _ Handles _AppDomain.UnhandledException If e.IsTerminating Then _Writer.Dispose() End Sub End Class ' ------------------- Ende Datei Logger.vb ------------------- ' ------------ Ende Projektdatei ErrorLog.vbproj ------------ ' ------------- Ende Projektgruppe ErrorLog.sln -------------
Diskussion
Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.
Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.