Error-Log Klasse

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

M0rgenstern

Betreff: Error-Log Klasse

BeitragDo, März 01, 2012 13:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Community,
Ich habe mich gestern Abend mal ein wenig damit auseinandergesetzt, wie man Fehler und Ausnahmen in BlitzMax korrekt behandeln kann. Klar, Try/Catch nutzen etc.
Aber oftmals macht das Programm einfach weiter und man merkt nicht zwangsläufig, dass ein Feher gefangen wurde, außer höchstens durch Debuglog-Ausgaben.
Da hab ich mir gedacht: Es wäre doch ganz schick, wenn man in solchen (und ähnlichen Fällen) einfach eine Datei hätte, in die die gefangenen Ausnahmen oder aufgetretenen Fehler reingeschrieben werden können. Das ist ja auch hilfreich, wenn das Programm veröffentlicht wird, für Fehlerlogs die der Benutzer dann übermitteln kann.

Ums kurz zu machen: Heraus kam eine Klasse, die Fehler schön formatiert in eine Datei schreibt. Man kann auch mehrere Log-Dateien haben, nämlich pro Klasseninstanz eine.
Es gibt drei Möglichkeiten einen Fehler zu loggen:
- Eine gefangene Exception
- Ein Fehler, von dem man weiß, dass er auftreten kann, der aber nicht zwangsläufig zum Crash führt und für den man nicht unbedingt einen Try/Catch Block machen will
- Ein Fehler, in den man reinschreiben kann, was man will.

Hier ist die Klasse:
BlitzMax: [AUSKLAPPEN]
'Error Logger - It allows to have multiple Error-Log files (one for each instance)
'It provides an simple way of logging nicely formatted errors
Type TErrorLogger
Field _strLogFile:TStream 'The log file in which the logger will write the logs
Field _sLoggerName:String 'The name of the logger (will just be shown in file)
Field _iErrorNumber:Int 'To count the amount of the logged errors

'Returns the current stream
Method LogFile:TStream()
Return _strLogFile
End Method

'Closes the current stream and opens it new (by new stream)
Method SetLogFile(pstrLogFile:TStream)
If(LogFile() <> Null)
LogFile().Close()
EndIf
_strLogFile = pstrLogFile
End Method

'Closes the current stream and opens it new (by new filename)
Method SetNewLogFile(psFileName:String)
If(LogFile() <> Null)
LogFile().Close()
EndIf
_strLogFile = WriteStream(psFileName)
End Method

'Returns the name of the logger
Method LoggerName:String()
Return _sLoggerName
End Method

'Sets the name for the logger (private method, only use once)
Method __SetLoggerName(psLogName:String)
_sLoggerName = psLogName
End Method

'Returns the current amount of logged errors
Method ErrorNumber:Int()
Return _iErrorNumber
End Method

'Sets the current amount of errors (private method)
Method __SetErrorNumber(piErrorNumb:Int)
_iErrorNumber = piErrorNumb
End Method

'Constructor - Needs a filename (don't forget the file extension) and a name for the logger
Function Create:TErrorLogger(psFileName:String, psLogName:String)
Local errorLogger:TErrorLogger = New TErrorLogger

errorLogger.SetNewLogFile(psFileName) 'Open file for writing
errorLogger.__SetLoggerName(psLogName)
errorLogger.__SetErrorNumber(0)

'Write some majoer infos in file
errorLogger.LogFile().WriteLine("Error File of Logger: " + errorLogger.LoggerName())
errorLogger.LogFile().WriteLine("")

Return errorLogger
End Function

'Logs a catched exception of a try/catch block
'psMethodName: The name of the method or function where the exception was caught
'psClassName: The name of the class where the exception was caught (if empty nothing will be written)
'psCustomText: Some text which can be written additional (if empty nothing will be written)
'pObjException: The exception which ist caught
'piIsFunction: If it was a function or a method where the exception was caught
'pobjUsedObject: For example an object which was used when the exception was caught (if empty nothing will be written)
Method LogException(psMethodName:String, psClassName:String = "", psCustomText:String = "", ..
pobjException:Object, piIsFunction:Int, pobjUsedObject:Object = Null)
IncErrorNumber()
LogFile().WriteLine("[CATCHED_EXCEPTION] Error No. " + ErrorNumber())

If(piIsFunction) Then
LogFile().WriteLine(" -In Function: " + psMethodName)
Else
LogFile().WriteLine(" -In Method: " + psMethodName)
EndIf

If(psClassName <> "") Then
LogFile().WriteLine(" -In Class: " + psClassName)
EndIf

If(pobjUsedObject <> Null) Then
LogFile().WriteLine(" -By using Object: " + pobjUsedObject.ToString())
EndIf

LogFile().WriteLine(" -ExceptionText: " + pobjException.ToString())

If(psCustomText <> "") Then
LogFile().WriteLine(" -Custom Text: " + psCustomText)
EndIf

LogFile().WriteLine("")
End Method

'Logs a detected error
'psMethodName: The name of the method or function where the exception was caught
'psClassName: The name of the class where the exception was caught (if empty nothing will be written)
'psErrorText: The text which should be written about this error (e.g. some explanations or values)
'piIsFunction: If it was a function or a method where the exception was caught
'pobjUsedObject: For example an object which was used when the exception was caught (if empty nothing will be written)
Method LogError(psMethodName:String, psClassName:String = "", psErrorText:String, piIsFunction:Int, pobjUsedObject:Object = Null)
IncErrorNumber()

LogFile().WriteLine("[DETECTED_ERROR] Error No. " + ErrorNumber())

If(piIsFunction) Then
LogFile().WriteLine(" -In Function: " + psMethodName)
Else
LogFile().WriteLine(" -In Method: " + psMethodName)
EndIf

If(psClassName <> "") Then
LogFile().WriteLine(" -In Class: " + psClassName)
EndIf

If(pobjUsedObject <> Null) Then
LogFile().WriteLine(" -By using Object: " + pobjUsedObject.ToString())
EndIf

LogFile().WriteLine(" -Error Text: " + psErrorText)

LogFile().WriteLine("")
End Method

'Logs a detected error when no further parameters are needed
'psErrorText: The text which should be written about this error (e.g. some explanations or values)
Method LogCustomError(psErrorText:String)
IncErrorNumber()

LogFile().WriteLine("[DETECTED_ERROR] Error No. " + ErrorNumber())
LogFile().WriteLine(" -Error Text: " + psErrorText)

LogFile().WriteLine("")
End Method

'Writes the last line in the file and then closes the file
Method EndLogging()
LogFile().WriteLine("Total Errors logged: " + ErrorNumber())
If(LogFile() <> Null) Then
LogFile().Close()
EndIf
End Method

'Increments the ErrorNumber
Method IncErrorNumber()
__SetErrorNumber(ErrorNumber() + 1)
End Method
End Type


Und natürlich gibts auch ein Beispielprogramm dazu:
BlitzMax: [AUSKLAPPEN]

Global ErrorLog:TErrorLogger = TErrorLogger.Create("Elogger.log", "Errors")

TPoint.Create(20.0, 30.0)
TPoint.Create(30.0, 4.0)
TPoint.Create(-10.0, 2.0)

TPoint.Init()

TPoint.Create(10.0, -2.0)
TPoint.Create(-10.0, -2.0)

ErrorLog.LogCustomError("Sorry, no cake for you at " + CurrentDate())

ErrorLog.EndLogging()

Type TPoint
Global tlAllPoints:TList

Field fPosX:Float
Field fPosY:Float

Function Init()
tlAllPoints = New TList
End Function

Function Create:TPoint(x:Float, y:Float)
Local point:TPoint = New TPoint

point.SetX(x)
point.SetY(y)

Try
tlAllPoints.AddLast(point)
Return point
Catch ex:Object
ErrorLog.LogException("Create", "TPoint", "Probably list not initialized.", ex, True, point)
End Try
End Function

Method SetX(x:Float)
fPosX = x
If(x < 0) Then
ErrorLog.LogError("SetX", "TPoint", "Point can't be drawn on screen: " + fPosX + " | " + fPosY, False, Self)
EndIf
End Method

Method SetY(y:Float)
fPosY = y
If(y < 0) Then
ErrorLog.LogError("SetY", "TPoint", "Point can't be drawn on screen: " + fPosX + " | " + fPosY, False, Self)
EndIf
End Method
End Type


Die Datei, die das Programm schreibt sieht dann so aus:
Zitat:
Error File of Logger: Errors

[CATCHED_EXCEPTION] Error No. 1
-In Function: Create
-In Class: TPoint
-By using Object: 0232EBB0
-ExceptionText: Attempt to access field or method of Null object
-Custom Text: Probably list not initialized.

[CATCHED_EXCEPTION] Error No. 2
-In Function: Create
-In Class: TPoint
-By using Object: 0232F1E0
-ExceptionText: Attempt to access field or method of Null object
-Custom Text: Probably list not initialized.

[DETECTED_ERROR] Error No. 3
-In Method: SetX
-In Class: TPoint
-By using Object: 0232F570
-Error Text: Point can't be drawn on screen: -10.0000000 | 0.000000000

[CATCHED_EXCEPTION] Error No. 4
-In Function: Create
-In Class: TPoint
-By using Object: 0232F570
-ExceptionText: Attempt to access field or method of Null object
-Custom Text: Probably list not initialized.

[DETECTED_ERROR] Error No. 5
-In Method: SetY
-In Class: TPoint
-By using Object: 0232FC40
-Error Text: Point can't be drawn on screen: 10.0000000 | -2.00000000

[DETECTED_ERROR] Error No. 6
-In Method: SetX
-In Class: TPoint
-By using Object: 023300B0
-Error Text: Point can't be drawn on screen: -10.0000000 | 0.000000000

[DETECTED_ERROR] Error No. 7
-In Method: SetY
-In Class: TPoint
-By using Object: 023300B0
-Error Text: Point can't be drawn on screen: -10.0000000 | -2.00000000

[DETECTED_ERROR] Error No. 8
-Error Text: Sorry, no cake for you at 01 Mar 2012

Total Errors logged: 8


Dort sieht man dann, warum man in den LogFunktionen wahlweise eine Instanz des gerade benutzten Objekts mitgeben kann: Man sieht im Log nacher, ob das gleiche Objekt öfter Fehler verursacht hat.

So, falls es noch Fragen, Anregungen oder ähnliches gibt, dann schreibt einfach.

Lg, M0rgenstern

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group