No announcement yet.

Yet Another DebugView Tool

  • Filter
  • Time
  • Show
Clear All
new posts

  • Yet Another DebugView Tool

    I find DebugView to be incredibly useful for developing and debugging apps. This is especially true if I'm working with more than one app at the same time (e.g. client and server network apps). The sample code below also allows setting a level for logged messages and a global threshold for which messages to actually log. By setting a compiler directive, logging code will not be added. I find it useful to also know which function generated the message.

    To use with multiple apps, $PROCNAME must be different for each app (e.g. $PROCNAME = "APP_1" and the DebugView Include filter must include all apps that you want to get messages for (e.g. "[APP_1];[APP_2]"). I can't remember why but I also find it useful to set the DebugView Exclude filter to "avcore".

    The code can be tweaked to remove or add other data (e.g. a thread ID for the thread that logged the message) or allow longer messages.

    #COMPILE EXE      ' Default is an EXE file
    #INCLUDE ""
    %DATALOG = %TRUE  ' Set TRUE (non-zero) to log or FALSE (zero) to skip logging code
    %LOG_NORMAL   = 4    ' Events that will ALWAYS be logged (e.g. start, stop, version)
    %LOG_FAIL     = 3    ' Events that cause the application to fail will always be logged
    %LOG_WARN     = 2    ' Non-fatal events that don't cause app to fail but are not normal
    %LOG_VERBOSE  = 1    ' Interesting events but not as chatty as DEBUG
    %LOG_DEBUG    = 0    ' All possible events - VERY chatty so use sparingly!!!
    $PROCNAME = "LOG_TEST"    ' Process/application needs to be named for dbgview logging.
    GLOBAL gLogLevel AS LONG  ' This sets a global log level threshold (may not want to see ALL
    SUB DataLogger ( _
        BYREF sFunction AS STRING, _  ' Function name that generated the message
        BYVAL level     AS LONG, _    ' Log level of the message
        BYREF sArg      AS STRING _   ' Text description of message
        ) THREADSAFE                  ' Can be used by multiple threads
      '-- Define string buffers. Use static, fixed-lengh strings so we don't have to keep allocating
      '   and de-allocating memory. We only need this for file logging. Safe since we're threadsafe.
      STATIC zMsg   AS  STRINGZ * 129    ' Buffer to hold message
      STATIC sLevel AS  STRING * 4       ' Buffer to hold level name to post on log message
      sLevel = SWITCH$ ( _
          level = %LOG_NORMAL,  "NORM", _
          level = %LOG_FAIL,    "FAIL", _
          level = %LOG_WARN,    "WARN", _
          level = %LOG_VERBOSE, "VERB", _
          level = %LOG_DEBUG,   "DBUG" _
        zMsg =  _
            "[" & $PROCNAME & "] [" & sLevel & "] " & LEFT$(sFunction, 25) _
            & $SPC & LEFT$(sArg, 75)
        OutputDebugString zMsg   ' This will probably generate a page fault. Oh well...
    END SUB ' DataLogger
    MACRO DLog ( _
        level, _  ' Error level of the candidate message
        sArg _    ' String value with message description
      IF (level >= gLogLevel) OR (level = %LOG_FAIL) THEN DataLogger FUNCNAME$, level, sArg
    END MACRO   ' DLog
      gLogLevel = %LOG_WARN
      DLog (%LOG_DEBUG, "DEBUG level")
      DLog (%LOG_VERBOSE, "VERBOSE level")
      DLog (%LOG_WARN, "WARN level")
      DLog (%LOG_FAIL, "FAIL level")
      DLog (%LOG_NORMAL, "NORMAL level")