@@ -34,6 +34,7 @@ local version = "0.4.1"
3434local os_date = os.date
3535local os_time = os.time
3636local debug_getinfo = debug.getinfo
37+ local debug_getlocal = debug.getlocal
3738local math_random = math.random
3839local json_encode = json .encode
3940local string_format = string.format
@@ -140,7 +141,50 @@ local function _get_server_name()
140141 return ngx and ngx .var .server_name or " undefined"
141142end
142143
143- local function backtrace (level )
144+ local function get_function_details (f )
145+ local info = debug_getinfo (f , " fSl" )
146+ return string_format (" %s defined at line %d in %s" , tostring (info .func ), info .linedefined , info .short_src )
147+ end
148+
149+ -- these two are mutually recursive, hence declaration before instantiation
150+ local json_prep_table , json_prep_value
151+ json_prep_value = function (v , max_depth )
152+ if max_depth == nil then
153+ max_depth = 0
154+ end
155+
156+ local tv = type (v )
157+ if tv == " function" then
158+ return get_function_details (v )
159+ elseif tv == " lightuserdata" or tv == " userdata" or tv == " thread" then
160+ return tostring (v )
161+ elseif tv == " table" then
162+ if max_depth <= 0 then
163+ return tostring (v )
164+ else
165+ return json_prep_table (v , max_depth - 1 )
166+ end
167+ else
168+ return v
169+ end
170+ end
171+
172+ json_prep_table = function (t , max_depth )
173+ if max_depth == nil then
174+ max_depth = 0
175+ end
176+
177+ local out = {}
178+ for k , v in pairs (t ) do
179+ local tk = type (k )
180+ if tk == " number" or tk == " string" then
181+ out [k ] = json_prep_value (v , max_depth )
182+ end
183+ end
184+ return out
185+ end
186+
187+ local function backtrace (level , capture_frame_locals , max_depth )
144188 local frames = {}
145189
146190 level = level + 1
@@ -151,12 +195,32 @@ local function backtrace(level)
151195 break
152196 end
153197
154- table_insert ( frames , 1 , {
198+ local frame = {
155199 filename = info .short_src ,
156200 [" function" ] = info .name ,
157201 lineno = info .currentline ,
158- })
202+ }
203+
204+ if capture_frame_locals then
205+ local frame_locals = {}
206+ local frame_local_idx = 1
207+ while true do
208+ local k , v = debug_getlocal (level , frame_local_idx )
209+ if k == nil then
210+ break
211+ end
212+
213+ -- unsure whether this tostring is actually necessary
214+ k = tostring (k )
215+ if k :sub (0 , 1 ) ~= " (" then -- internal/temp vars start with (, ignore them
216+ frame_locals [k ] = json_prep_value (v , max_depth )
217+ end
218+ frame_local_idx = frame_local_idx + 1
219+ end
220+ frame .vars = frame_locals
221+ end
159222
223+ table_insert (frames , 1 , frame )
160224 level = level + 1
161225 end
162226 return { frames = frames }
@@ -253,6 +317,8 @@ function _M.new(self, dsn, conf)
253317 obj .level = " error"
254318 obj .verify_ssl = true
255319 obj .cacert = " ./data/cacert.pem"
320+ obj .capture_frame_locals = true
321+ obj .max_depth = 0
256322
257323 if conf then
258324 if conf .tags then
@@ -270,6 +336,14 @@ function _M.new(self, dsn, conf)
270336 if conf .cacert then
271337 obj .cacert = conf .cacert
272338 end
339+
340+ if conf .capture_frame_locals == false then
341+ obj .capture_frame_locals = false
342+ end
343+
344+ if conf .max_depth then
345+ obj .max_depth = conf .max_depth
346+ end
273347 end
274348
275349 return setmetatable (obj , mt )
@@ -319,7 +393,7 @@ function _M.captureException(self, exception, conf)
319393 trace_level = conf .trace_level
320394
321395 clear_tab (_json )
322- exception [1 ].stacktrace = backtrace (trace_level )
396+ exception [1 ].stacktrace = backtrace (trace_level , self . capture_frame_locals , self . max_depth )
323397 _json .exception = exception
324398 _json .message = exception [1 ].value
325399
@@ -448,7 +522,7 @@ function _M.catcher(self, err)
448522
449523 clear_tab (_exception [1 ])
450524 _exception [1 ].value = err
451- _exception [1 ].stacktrace = backtrace (catcher_trace_level )
525+ _exception [1 ].stacktrace = backtrace (catcher_trace_level , self . capture_frame_locals , self . max_depth )
452526
453527 clear_tab (_json )
454528 _json .exception = _exception
0 commit comments