cgi-bin/tek/lib/debug.lua
author Timm S. Mueller <tmueller@neoscientists.org>
Fri, 12 Sep 2008 22:00:42 +0200
changeset 244 3a4291950c9f
parent 226 f16ff668a409
child 247 71a5ca44a68e
permissions -rw-r--r--
luahtml: added UTF-8-to-form encoder written in C; Markup, Debug: minor fixes
and new debugging features merged back in from other projects; FastCGI
launcher: no longer enforces full garbage collection
     1 -------------------------------------------------------------------------------
     2 --
     3 --	tek.lib.debug
     4 --	Written by Timm S. Mueller <tmueller at schulze-mueller.de>
     5 --	See copyright notice in COPYRIGHT
     6 --
     7 --	OVERVIEW::
     8 --	Debug library - implements debug output and debug levels:
     9 --
    10 --	2  || TRACE || used for tracking bugs
    11 --	4  || INFO  || informational messages
    12 --	5  || WARN  || something unexpected happened
    13 --	10 || ERROR || something went wrong, e.g. resource unavailable
    14 --	20 || FAIL  || something went wrong that can't be coped with
    15 --
    16 --	The default debug level is 10 {{ERROR}}. To set the debug level
    17 --	globally, e.g.:
    18 --			db = require "tek.lib.debug"
    19 --			db.level = db.INFO
    20 --
    21 --	The default debug output stream is {{stderr}}.
    22 --	To override it globally, e.g.:
    23 --			db = require "tek.lib.debug"
    24 --			db.out = io.open("logfile", "w")
    25 --
    26 --	FUNCTIONS::
    27 --		- debug.console() - Enter debug console
    28 --		- debug.dump() - Dump a table recursively
    29 --		- debug.error() - Print a text in the {{ERROR}} debug level
    30 --		- debug.execute() - Execute a function in the specified debug level
    31 --		- debug.fail() - Print a text in the {{FAIL}} debug level
    32 --		- debug.info() - Print a text in the {{INFO}} debug level
    33 --		- debug.print() - Print a text in the specified debug level
    34 --		- debug.stacktrace() - Print a stacktrace in the specified debug level
    35 --		- debug.trace() - Print a text in the {{TRACE}} debug level
    36 --		- debug.warn() - Print a text in the {{WARN}} debug level
    37 --
    38 -------------------------------------------------------------------------------
    39 
    40 local debug = require "debug"
    41 local getinfo = debug.getinfo
    42 local stderr = io.stderr
    43 local pairs = pairs
    44 local select = select
    45 local time = os.time
    46 local tonumber = tonumber
    47 local tostring = tostring
    48 local traceback = debug.traceback
    49 local type = type
    50 local unpack = unpack
    51 
    52 module "tek.lib.debug"
    53 _VERSION = "Debug 4.0"
    54 
    55 -- symbolic:
    56 
    57 TRACE = 2
    58 INFO = 4
    59 WARN = 5
    60 ERROR = 10
    61 FAIL = 20
    62 
    63 -- global defaults:
    64 
    65 level = ERROR
    66 out = stderr
    67 wrout = function(...) out:write(...) end
    68 
    69 -------------------------------------------------------------------------------
    70 --	print(lvl, msg, ...): Prints formatted text if the global debug level
    71 --	is less or equal the specified level.
    72 -------------------------------------------------------------------------------
    73 
    74 function print(lvl, msg, ...)
    75 	if level and lvl >= level then
    76 		local t = getinfo(3, "lS")
    77 		local arg = { }
    78 		for i = 1, select('#', ...) do
    79 			local v = select(i, ...)
    80 			arg[i] = v and type(v) ~= "number" and tostring(v) or v or 0
    81 		end
    82 		wrout(("(%02d %d %s:%d) " .. msg):format(lvl,
    83 			time(), t.short_src, t.currentline, unpack(arg)) .. "\n")
    84 	end
    85 end
    86 
    87 -------------------------------------------------------------------------------
    88 --	execute(lvl, func, ...): Executes the specified function if the global
    89 --	debug library is less or equal the specified level.
    90 -------------------------------------------------------------------------------
    91 
    92 function execute(lvl, func, ...)
    93 	if level and lvl >= level then
    94 		return func(...)
    95 	end
    96 end
    97 
    98 -------------------------------------------------------------------------------
    99 --	trace(msg, ...): Prints formatted debug info with {{TRACE}} level
   100 -------------------------------------------------------------------------------
   101 function trace(msg, ...) print(2, msg, ...) end
   102 
   103 -------------------------------------------------------------------------------
   104 --	info(msg, ...): Prints formatted debug info with {{INFO}} level
   105 -------------------------------------------------------------------------------
   106 function info(msg, ...) print(4, msg, ...) end
   107 
   108 -------------------------------------------------------------------------------
   109 --	warn(msg, ...): Prints formatted debug info with {{WARN}} level
   110 -------------------------------------------------------------------------------
   111 function warn(msg, ...) print(5, msg, ...) end
   112 
   113 -------------------------------------------------------------------------------
   114 --	error(msg, ...): Prints formatted debug info with {{ERROR}} level
   115 -------------------------------------------------------------------------------
   116 function error(msg, ...) print(10, msg, ...) end
   117 
   118 -------------------------------------------------------------------------------
   119 --	fail(msg, ...): Prints formatted debug info with {{FAIL}} level
   120 -------------------------------------------------------------------------------
   121 function fail(msg, ...) print(20, msg, ...) end
   122 
   123 -------------------------------------------------------------------------------
   124 --	stacktrace(debuglevel, stacklevel): Prints a stacktrace starting at
   125 --	the function of the given {{level}} on the stack (excluding the
   126 --	{{stracktrace}} function itself) if the global debug level is less
   127 --	or equal the specified {{debuglevel}}.
   128 -------------------------------------------------------------------------------
   129 
   130 function stacktrace(lvl, level)
   131 	print(lvl, traceback("", level or 1 + 1))
   132 end
   133 
   134 -------------------------------------------------------------------------------
   135 --	console(): Enter the debug console.
   136 -------------------------------------------------------------------------------
   137 
   138 function console()
   139 	stderr:write('Entering the debug console.\n')
   140 	stderr:write('To redirect the output, e.g.:\n')
   141 	stderr:write('  tek.lib.debug.out = io.open("logfile", "w")\n')
   142 	stderr:write('To dump a table, e.g.:\n')
   143 	stderr:write('  tek.lib.debug.dump("app", app)\n')
   144 	stderr:write('Use "cont" to continue.\n')
   145 	debug.debug()
   146 end
   147 
   148 -------------------------------------------------------------------------------
   149 --	dump(name, table): Dump a table
   150 -------------------------------------------------------------------------------
   151 
   152 local function basicSerialize(o)
   153 	if type(o) == "string" then
   154 		return ("%q"):format(o)
   155 	elseif type(o) == "userdata" then
   156 		return "<userdata>"
   157 	end
   158 	return tostring(o)
   159 end
   160 
   161 function dump(name, value, saved)
   162 	saved = saved or {}       -- initial value
   163 	wrout(name, " = ")
   164 	local t = type(value)
   165 	if t == "table" then
   166 		if saved[value] then    -- value already saved?
   167 			wrout(saved[value], "\n")
   168 		else
   169 			saved[value] = name   -- save name for next time
   170 			wrout("{}\n")
   171 			for k,v in pairs(value) do      -- save its fields
   172 				local fieldname = ("%s[%s]"):format(name, basicSerialize(k))
   173 				dump(fieldname, v, saved)
   174 			end
   175 		end
   176 	else
   177 		wrout(basicSerialize(value), "\n")
   178 	end
   179 end