cgi-bin/tek/lib/debug.lua
author Timm S. Mueller <tmueller@neoscientists.org>
Wed, 24 Feb 2010 14:44:46 +0100
changeset 258 30e3e6d34685
parent 247 71a5ca44a68e
permissions -rw-r--r--
Added HTTP headers and meta tags discouraging the browser to cache the page
when logged on or when the page content is dynamic
     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 5 {{WARN}}. 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() - Enters the debug console
    28 --		- debug.dump() - Dumps a table recursively
    29 --		- debug.error() - Prints a text in the {{ERROR}} debug level
    30 --		- debug.execute() - Executes a function in the specified debug level
    31 --		- debug.fail() - Prints a text in the {{FAIL}} debug level
    32 --		- debug.info() - Prints a text in the {{INFO}} debug level
    33 --		- debug.print() - Prints a text in the specified debug level
    34 --		- debug.stacktrace() - Prints a stacktrace in the specified debug level
    35 --		- debug.trace() - Prints a text in the {{TRACE}} debug level
    36 --		- debug.warn() - Prints 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.3"
    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 = WARN
    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)\n')
   144 	stderr:write('Use "cont" to continue.\n')
   145 	debug.debug()
   146 end
   147 
   148 -------------------------------------------------------------------------------
   149 --	dump(table): Dump a table as Lua source using {{out}} as the output
   150 --	stream. Cyclic references are silently dropped.
   151 -------------------------------------------------------------------------------
   152 
   153 local function encodenonascii(c)
   154 	return ("\\%03d"):format(c:byte())
   155 end
   156 
   157 local function encode(s)
   158 	return s:gsub('([%z\001-\031\092"])', encodenonascii)
   159 end
   160 
   161 local function dumpr(tab, indent, outfunc, saved)
   162 	saved[tab] = tab
   163 	local is = ("\t"):rep(indent)
   164 	for key, val in pairs(tab) do
   165 		if not saved[val] then
   166 			outfunc(is)
   167 			local t = type(key)
   168 			if t == "number" or t == "boolean" then
   169 				outfunc('[' .. tostring(key) .. '] = ')
   170 			elseif t == "string" then
   171 				if key:match("[^%a_]") then
   172 					outfunc('["' .. encode(key) .. '"] = ')
   173 				else
   174 					outfunc(key .. ' = ')
   175 				end
   176 			else
   177 				outfunc('["' .. tostring(key) .. '"] = ')
   178 			end
   179 			t = type(val)
   180 			if t == "table" then
   181 				outfunc('{\n')
   182 				dumpr(val, indent + 1, outfunc, saved)
   183 				outfunc(is .. '},\n')
   184 			elseif t == "string" then
   185 				outfunc('"' .. encode(val) .. '",\n')
   186 			elseif t == "number" or t == "boolean" then
   187 				outfunc(tostring(val) .. ',\n')
   188 			else
   189 				outfunc('"' .. tostring(val) .. '",\n')
   190 			end
   191 		end
   192 	end
   193 end
   194 
   195 function dump(tab, outf)
   196 	dumpr(tab, 0, outf or wrout, { })
   197 end