typedef void *(*map_alloc_f)(void *, size_t);
typedef void (*map_free_f)(void *baton, void *ptr);
-typedef void (*trace_log_f) (const char *);
+typedef void (*trace_log_f) (const struct kr_request *, const char *);
typedef void (*trace_callback_f)(struct kr_request *);
typedef enum {KNOT_ANSWER, KNOT_AUTHORITY, KNOT_ADDITIONAL} knot_section_t;
typedef struct {
typedef void *(*map_alloc_f)(void *, size_t);
typedef void (*map_free_f)(void *baton, void *ptr);
-typedef void (*trace_log_f) (const char *);
+typedef void (*trace_log_f) (const struct kr_request *, const char *);
typedef void (*trace_callback_f)(struct kr_request *);
"
-- helper for trace_chain_callbacks
-- ignores return values from successfull calls but logs tracebacks for throws
-local function void_xpcall_log_tb(func, arg)
- local ok, err = xpcall(func, debug.traceback, arg)
+local function void_xpcall_log_tb(func, req, msg)
+ local ok, err = xpcall(func, debug.traceback, req, msg)
if not ok then
- log('error: callback %s arg %s stack traceback:\n%s', func, arg, err)
+ log('error: callback %s req %s msg %s stack traceback:\n%s', func, req, msg, err)
end
end
+local function void_xpcall_finish_tb(func, req)
+ local ok, err = xpcall(func, debug.traceback, req)
+ if not ok then
+ log('error: callback %s req %s stack traceback:\n%s', func, req, err)
+ end
+end
+
+
-- Metatype for request
local kr_request_t = ffi.typeof('struct kr_request')
ffi.metatype( kr_request_t, {
else
local old_log = req.trace_log
log_wrapper = ffi.cast('trace_log_f',
- function(msg)
+ function(cbreq, msg)
jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
- void_xpcall_log_tb(old_log, msg)
- void_xpcall_log_tb(new_log, msg)
+ void_xpcall_log_tb(old_log, cbreq, msg)
+ void_xpcall_log_tb(new_log, cbreq, msg)
end)
req.trace_log = log_wrapper
end
function(cbreq)
jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
if old_finish ~= nil then
- void_xpcall_log_tb(old_finish, cbreq)
+ void_xpcall_finish_tb(old_finish, cbreq)
end
if new_finish ~= nil then
- void_xpcall_log_tb(new_finish, cbreq)
+ void_xpcall_finish_tb(new_finish, cbreq)
end
-- beware: finish callbacks can call log callback
if log_wrapper ~= nil then
msg = mp_vprintf_append(mp, msg, fmt, args);
if (kr_log_rtrace_enabled(req))
- req->trace_log(msg);
+ req->trace_log(req, msg);
else
/* caller is responsible for detecting verbose mode, use QRVERBOSE() macro */
printf("%s", msg);
/**
* @brief Callback for request logging handler.
* @param[in] msg Log message. Pointer is not valid after handler returns. */
-typedef void (*trace_log_f)(const char *msg);
+typedef void (*trace_log_f)(const struct kr_request *request, const char *msg);
#define kr_log_info printf
#define kr_log_error(...) fprintf(stderr, ## __VA_ARGS__)
-- Create logging handler callback
local buffer = {}
- local buffer_log_cb = ffi.cast('trace_log_f', function (msg)
+ local buffer_log_cb = ffi.cast('trace_log_f', function (_, msg)
table.insert(buffer, ffi.string(msg))
end)
end
end
-local debug_logline_cb = ffi.cast('trace_log_f', function (msg)
+local function free_cb(func)
+ func:free()
+end
+
+local debug_logline_cb = ffi.cast('trace_log_f', function (_, msg)
jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
-- msg typically ends with newline
io.write(ffi.string(msg))
end)
+ffi.gc(debug_logline_cb, free_cb)
local debug_logfinish_cb = ffi.cast('trace_callback_f', function (req)
jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
'answer packet:\n' ..
tostring(req.answer))
end)
+ffi.gc(debug_logfinish_cb, free_cb)
-- log request packet
function policy.REQTRACE(_, req)
policy.REQTRACE(state, req)
end
+local debug_stashlog_cb = ffi.cast('trace_log_f', function (req, msg)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+
+ -- stash messages for conditional logging in trace_finish
+ local stash = req:vars()['policy_debug_stash']
+ table.insert(stash, ffi.string(msg))
+end)
+ffi.gc(debug_stashlog_cb, free_cb)
+
-- buffer verbose logs and print then only if test() returns a truthy value
function policy.DEBUG_IF(test)
+ local debug_finish_cb = ffi.cast('trace_callback_f', function (cbreq)
+ jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
+ if test(cbreq) then
+ debug_logfinish_cb(cbreq) -- unconditional version
+ local stash = cbreq:vars()['policy_debug_stash']
+ io.write(table.concat(stash, ''))
+ end
+ end)
+ ffi.gc(debug_finish_cb, function (func) func:free() end)
+
return function (state, req)
+ req:vars()['policy_debug_stash'] = {}
policy.QTRACE(state, req)
- local priv_log_buf = {}
- local priv_log_cb = ffi.cast('trace_log_f', function (msg)
- jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
-
- -- stash messages for conditional logging in trace_finish
- table.insert(priv_log_buf, ffi.string(msg))
- end)
-
- local priv_finish_cb
- priv_finish_cb = ffi.cast('trace_callback_f', function (cbreq)
- jit.off(true, true) -- JIT for (C -> lua)^2 nesting isn't allowed
- if test(cbreq) then
- debug_logfinish_cb(cbreq) -- unconditional version
- io.write(table.concat(priv_log_buf, ''))
- end
- priv_log_cb:free()
- priv_finish_cb:free()
- end)
- req:trace_chain_callbacks(priv_log_cb, priv_finish_cb)
+ req:trace_chain_callbacks(debug_stashlog_cb, debug_finish_cb)
policy.REQTRACE(state, req)
return
end
-- logging
local function add_tracer(logbuf)
return function (req)
- local function qrylogger(msg)
+ local function qrylogger(_, msg)
table.insert(logbuf, ffi.string(msg))
end
req.trace_log = ffi.cast('trace_log_f', qrylogger)