Anforderungen:
(1) Angabe eines Debuglevels
Als Verursacher meines Code benötige ich mehr Informationen zum internen Status meiner Software als ein Anwender. Je nach persönlicher Fähigkeit könnte ein betatester wiederum mehr Informationen vertragen bzw. als ein gewöhnlicher Anwender. Daher sehe ich die Notwendigkeit von Debuglevel. Mir erschien die folgende Einteilung geeignet:
- "Debug" für echte programmiertechnische Debugmeldungen (z.B. "tmp.l = 4711")
- "Verbose" für Informationen zum internem Programmablauf (z.B. "Procedure xyz called", "line 02 parsed")
- "Info" für Informationen zum Programmablauf (z.B. "Open config file xyz.cfg")
- "Warn" für Warnungen (z.B. "File open xyz.cfg failed")
(2) Welche Debuglevel sollen in das Executable übernommen werden
Eigentlich möchte ich nicht, das jeder nicht benötigte Debugaufruf im executable landet. Einerseits um meinen Code zu schützen, andererseits um das Laufzeitverhalten nicht zu beinträchtigen. Eine Konstante soll bestimmen, ob die Debugunterstützung grundsätzlich aktiviert wird und je Debuglevel eine einzelne Konstante. Niiieee wieder auskommentieren von Debug Anweisungen

(3) Ausgabe von Datum und Uhrzeit
(4) Unterstützung einer Angabe in welcher Sektion/Prozedur/Codeteil der Aufruf stattfand, um diesen beim auswerten zuordnen zu können
(5) Unterstützung einer Angabe in welchem Thread dieser Sektion/Prozedur/Codeteil aufgerufen wurde, um diese beim auswerten zuordnen zu können
(6) Threadsafe aktivierbar.
Über eine Compilerdirektive soll der Code Threadsafe werden
Umsetzung:
Siehe folgenden Code

Was fehlt:
Eine grafische Darstellung der gespeicherten Ereignisse mit Filter usw. Da jeder in seiner Anwendung individuelle Anforderungen an Art und Umfang haben wird, habe ich vorerst darauf verzichtet.
Code mod_debug:
Code: Alles auswählen
;
;
; mod_debug
;
;
EnableExplicit
#mod_debug_enable_general = #True ; Would you like to enable mod_debug?
#mod_debug_enable_threadsafe = #True ; Should mod_debug work within threads?
#mod_debug_enable_level_debug = #True ; For Developer
#mod_debug_enable_level_verbose = #True ; For User/Developer: Verbose Messages
#mod_debug_enable_level_info = #True ; For User: INFO
#mod_debug_enable_level_warning = #True ; For User: WARNINGS
#mod_debug_display_on_event = #True ; Should any enabled event
CompilerIf #mod_debug_enable_general = #True
#mod_debug_level_debug = 1
#mod_debug_level_verbose = 2
#mod_debug_level_info = 4
#mod_debug_level_warning = 8
Structure event_structure
event_level.l
event_timestamp.l
event_procedure.s
event_thread_id.l
event_message.s
EndStructure
NewList mod_debug_events.event_structure()
CompilerIf #mod_debug_enable_threadsafe = #True
Define mod_debug_events_mutex.l
mod_debug_events_mutex = CreateMutex()
CompilerEndIf
Procedure.s i_mod_debug_generate_line(p_level.l, p_timestamp.l, p_procedure.s, p_message.s, p_thread_id.l=0)
Define i_line.s
i_line = FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", p_timestamp)
Select p_level
Case #mod_debug_level_debug
i_line.s + " [DEBG] "
Case #mod_debug_level_verbose
i_line.s + " [VERB] "
Case #mod_debug_level_info
i_line.s + " [INFO] "
Case #mod_debug_level_warning
i_line.s + " [WARN] "
EndSelect
i_line + p_procedure
If p_thread_id
i_line + "("+Str(p_thread_id)+")"
EndIf
i_line + ": " + p_message
ProcedureReturn i_line
EndProcedure
Procedure i_mod_debug_add_event(p_level.l, p_procedure.s, p_message.s, p_thread_id.l=0)
;
;
;
Shared mod_debug_events.event_structure()
CompilerIf #mod_debug_enable_threadsafe = #True
Shared mod_debug_events_mutex
LockMutex(mod_debug_events_mutex)
CompilerEndIf
AddElement(mod_debug_events())
mod_debug_events()\event_level = p_level
mod_debug_events()\event_timestamp = Date()
mod_debug_events()\event_procedure = p_procedure
mod_debug_events()\event_message = p_message
mod_debug_events()\event_thread_id = p_thread_id
CompilerIf #mod_debug_enable_threadsafe = #True
UnlockMutex(mod_debug_events_mutex)
CompilerEndIf
CompilerIf #mod_debug_display_on_event=#True
Debug i_mod_debug_generate_line(p_level, Date(), p_procedure, p_message, p_thread_id)
CompilerEndIf
EndProcedure
Procedure i_mod_debug_display_events(p_loglevel.l)
;
;
;
Shared mod_debug_events.event_structure()
Define i_loglevel.l
Define i_line.s
CompilerIf #mod_debug_enable_threadsafe = #True
Shared mod_debug_events_mutex
LockMutex(mod_debug_events_mutex)
CompilerEndIf
ForEach mod_debug_events()
i_loglevel = mod_debug_events()\event_level
If i_loglevel & p_loglevel
i_line = i_mod_debug_generate_line(mod_debug_events()\event_level, mod_debug_events()\event_timestamp, mod_debug_events()\event_procedure, mod_debug_events()\event_message, mod_debug_events()\event_thread_id)
Debug i_line
EndIf
Next
CompilerIf #mod_debug_enable_threadsafe = #True
UnlockMutex(mod_debug_events_mutex)
CompilerEndIf
EndProcedure
CompilerEndIf
Macro mod_debug_add_debug(p_procedure,p_message,p_thread_id=0)
;
; Wrapper for i_mod_debug_add_event
CompilerIf #mod_debug_enable_general = #True
CompilerIf #mod_debug_enable_level_debug = #True
i_mod_debug_add_event(#mod_debug_level_debug, p_procedure, p_message, p_thread_id)
CompilerEndIf
CompilerEndIf
EndMacro
Macro mod_debug_add_verbose(p_procedure, p_message, p_thread_id=0)
;
; Wrapper for i_mod_debug_add_event
CompilerIf #mod_debug_enable_general = #True
CompilerIf #mod_debug_enable_level_verbose = #True
i_mod_debug_add_event(#mod_debug_level_verbose, p_procedure, p_message, p_thread_id)
CompilerEndIf
CompilerEndIf
EndMacro
Macro mod_debug_add_info(p_procedure, p_message, p_thread_id=0)
;
; Wrapper for i_mod_debug_add_event
CompilerIf #mod_debug_enable_general = #True
CompilerIf #mod_debug_enable_level_info = #True
i_mod_debug_add_event(#mod_debug_level_info, p_procedure, p_message, p_thread_id)
CompilerEndIf
CompilerEndIf
EndMacro
Macro mod_debug_add_warning(p_procedure, p_message, p_thread_id=0)
;
; Wrapper for i_mod_debug_add_event
CompilerIf #mod_debug_enable_general = #True
CompilerIf #mod_debug_enable_level_warning = #True
i_mod_debug_add_event(#mod_debug_level_warning, p_procedure, p_message, p_thread_id)
CompilerEndIf
CompilerEndIf
EndMacro
Macro mod_debug_display_events(p_loglevel)
CompilerIf #mod_debug_enable_general = #True
i_mod_debug_display_events(p_loglevel)
CompilerEndIf
EndMacro
Code Beispiel:
Code: Alles auswählen
XincludeFile("mod_debug.pb")
Procedure test()
mod_debug_add_debug("test","debug message")
mod_debug_add_verbose("test","verbose message")
mod_debug_add_info("test","info message")
mod_debug_add_warning("test","warning message")
EndProcedure
test()
mod_debug_add_debug("test", "debug message")
mod_debug_add_verbose("test", "verbose message")
mod_debug_add_info("test", "info message")
mod_debug_add_warning("test", "warning message")
mod_debug_display_events(#mod_debug_level_debug | #mod_debug_level_verbose | #mod_debug_level_info | #mod_debug_level_warning)