| rev | line source | 
| jbe@295 | 1 local function format_time(seconds) | 
| jbe@298 | 2   return string.format("%.1f ms", seconds * 1000) | 
| jbe@295 | 3 end | 
| jbe@295 | 4 | 
| jbe/bsw@0 | 5 local function open(class) | 
| jbe/bsw@0 | 6   slot.put('<li class="trace_' .. class .. '">') | 
| jbe/bsw@0 | 7 end | 
| bsw@115 | 8 local function open_head(node) | 
| jbe/bsw@0 | 9   slot.put('<div class="trace_head">') | 
| bsw@115 | 10   if node.start_hires_time and node.stop_hires_time then | 
| bsw@115 | 11     local total_duration = node.stop_hires_time - node.start_hires_time | 
| bsw@115 | 12     local child_duration = 0 | 
| bsw@115 | 13     for i, child in ipairs(node) do | 
| bsw@115 | 14       if child.start_hires_time and child.stop_hires_time then | 
| bsw@115 | 15         child_duration = child_duration + child.stop_hires_time - child.start_hires_time | 
| bsw@115 | 16       end | 
| bsw@115 | 17     end | 
| bsw@115 | 18     local duration = total_duration - child_duration | 
| bsw@115 | 19     local start_text = math.floor(node.start_hires_time * 10000 + 0.5) / 10 | 
| bsw@115 | 20     local total_duration_text = math.floor(total_duration * 10000 + 0.5) / 10 | 
| bsw@115 | 21     local child_duration_text = math.floor(child_duration * 10000 + 0.5) / 10 | 
| bsw@115 | 22     local duration_text = math.floor(duration * 10000 + 0.5) / 10 | 
| bsw@115 | 23     slot.put('<div class="time">') | 
| bsw@115 | 24     slot.put('<span class="start_label">start:</span>') | 
| bsw@115 | 25     slot.put(" ") | 
| bsw@115 | 26     slot.put('<span class="start">' .. start_text .. 'ms</span>') | 
| bsw@115 | 27     slot.put(" | ") | 
| bsw@115 | 28     slot.put('<span class="duration_label">this:</span>') | 
| bsw@115 | 29     slot.put(" ") | 
| bsw@115 | 30     slot.put('<span class="duration">' .. duration_text .. 'ms</span>') | 
| bsw@115 | 31     slot.put(" | ") | 
| bsw@115 | 32     slot.put('<span class="child_duration_label">children:</span>') | 
| bsw@115 | 33     slot.put(" ") | 
| bsw@115 | 34     slot.put('<span class="child_duration">' .. child_duration_text .. 'ms</span>') | 
| bsw@115 | 35     slot.put(" | ") | 
| bsw@115 | 36     slot.put('<span class="total_duration_label">total:</span>') | 
| bsw@115 | 37     slot.put(" ") | 
| bsw@115 | 38     slot.put('<span class="total_duration">' .. total_duration_text .. 'ms</span>') | 
| bsw@115 | 39     slot.put('</div>') | 
| bsw@115 | 40   end | 
| jbe/bsw@0 | 41 end | 
| jbe/bsw@0 | 42 local function close_head() | 
| jbe/bsw@0 | 43   slot.put('</div>') | 
| jbe/bsw@0 | 44 end | 
| jbe/bsw@0 | 45 local function close() | 
| jbe/bsw@0 | 46   slot.put('</li>') | 
| jbe/bsw@0 | 47 end | 
| jbe/bsw@0 | 48 function trace._render_sub_tree(node) | 
| jbe/bsw@0 | 49   local function render_children(tail) | 
| jbe/bsw@0 | 50     if #node > 0 then | 
| jbe/bsw@0 | 51       slot.put('<ul class="trace_list">') | 
| jbe/bsw@0 | 52       for idx, child in ipairs(node) do | 
| jbe/bsw@0 | 53         trace._render_sub_tree(child) | 
| jbe/bsw@0 | 54       end | 
| jbe/bsw@0 | 55       if tail then | 
| jbe/bsw@0 | 56         slot.put(tail) | 
| jbe/bsw@0 | 57       end | 
| jbe/bsw@0 | 58       slot.put("</ul>") | 
| jbe/bsw@0 | 59     end | 
| jbe/bsw@0 | 60   end | 
| jbe/bsw@0 | 61   local function close_with_children() | 
| jbe/bsw@0 | 62     close_head() | 
| jbe/bsw@0 | 63     render_children() | 
| jbe/bsw@0 | 64     close() | 
| jbe/bsw@0 | 65   end | 
| jbe/bsw@0 | 66   local node_type = node.type | 
| jbe/bsw@0 | 67   if node_type == "root" then | 
| jbe/bsw@0 | 68     render_children() | 
| jbe/bsw@0 | 69   elseif node_type == "debug" then | 
| jbe/bsw@0 | 70     open("debug") | 
| jbe/bsw@0 | 71     slot.put(encode.html(node.message)) | 
| jbe/bsw@0 | 72     close() | 
| poelzi@31 | 73   elseif node_type == "debug_table" then | 
| poelzi@31 | 74     open("debug") | 
| poelzi@31 | 75     slot.put("<table>") | 
| poelzi@31 | 76     if type(node.message) == "table" then | 
| poelzi@31 | 77       for k, v in pairs(node.message) do | 
| jbe@45 | 78         slot.put("<tr><td>", encode.html(tostring(k)), "</td><td>", encode.html(tostring(v)), "</td></tr>") | 
| poelzi@31 | 79       end | 
| poelzi@31 | 80       slot.put("</table>") | 
| poelzi@31 | 81     else | 
| poelzi@31 | 82       slot.put("debug_table: not of table type") | 
| poelzi@31 | 83     end | 
| poelzi@31 | 84     close() | 
| poelzi@29 | 85   elseif node_type == "traceback" then | 
| poelzi@29 | 86     open("debug") | 
| poelzi@29 | 87     slot.put('<pre>') | 
| poelzi@29 | 88     slot.put(encode.html(node.message)) | 
| poelzi@29 | 89     slot.put('</pre>') | 
| poelzi@29 | 90     close() | 
| jbe/bsw@0 | 91   elseif node_type == "request" then | 
| jbe/bsw@0 | 92     open("request") | 
| bsw@115 | 93     open_head(node) | 
| jbe/bsw@0 | 94     slot.put("REQUESTED") | 
| jbe/bsw@0 | 95     if node.view then | 
| jbe/bsw@0 | 96       slot.put(" VIEW") | 
| jbe/bsw@0 | 97     elseif node.action then | 
| jbe/bsw@0 | 98       slot.put(" ACTION") | 
| jbe/bsw@0 | 99     end | 
| jbe/bsw@0 | 100     slot.put( | 
| jbe/bsw@0 | 101       ": ", | 
| jbe/bsw@0 | 102       encode.html(node.module), | 
| jbe/bsw@0 | 103       "/", | 
| jbe/bsw@0 | 104       encode.html(node.view or node.action) | 
| jbe/bsw@0 | 105     ) | 
| jbe/bsw@0 | 106     close_with_children() | 
| jbe/bsw@0 | 107   elseif node_type == "config" then | 
| jbe/bsw@0 | 108     open("config") | 
| bsw@115 | 109     open_head(node) | 
| jbe/bsw@0 | 110     slot.put('Configuration "', encode.html(node.name), '"') | 
| jbe/bsw@0 | 111     close_with_children() | 
| jbe/bsw@0 | 112   elseif node_type == "filter" then | 
| jbe/bsw@0 | 113     open("filter") | 
| bsw@115 | 114     open_head(node) | 
| jbe/bsw@0 | 115     slot.put(encode.html(node.path)) | 
| jbe/bsw@0 | 116     close_with_children() | 
| jbe/bsw@0 | 117   elseif node_type == "view" then | 
| jbe/bsw@0 | 118     open("view") | 
| bsw@115 | 119     open_head(node) | 
| jbe/bsw@0 | 120     slot.put( | 
| jbe/bsw@0 | 121       "EXECUTE VIEW: ", | 
| jbe/bsw@0 | 122       encode.html(node.module), | 
| jbe/bsw@0 | 123       "/", | 
| jbe/bsw@0 | 124       encode.html(node.view) | 
| jbe/bsw@0 | 125     ) | 
| jbe/bsw@0 | 126     close_with_children() | 
| jbe/bsw@0 | 127   elseif node_type == "action" then | 
| jbe/bsw@0 | 128     if | 
| jbe/bsw@0 | 129       node.status and ( | 
| jbe/bsw@0 | 130         node.status == "ok" or | 
| jbe/bsw@0 | 131         string.find(node.status, "^ok_") | 
| jbe/bsw@0 | 132       ) | 
| jbe/bsw@0 | 133     then | 
| jbe/bsw@0 | 134       open("action_success") | 
| jbe/bsw@0 | 135     elseif | 
| jbe/bsw@0 | 136       node.status and ( | 
| jbe/bsw@0 | 137         node.status == "error" or | 
| jbe/bsw@0 | 138         string.find(node.status, "^error_") | 
| jbe/bsw@0 | 139       ) | 
| jbe/bsw@0 | 140     then | 
| jbe/bsw@0 | 141       open("action_softfail") | 
| jbe/bsw@0 | 142     else | 
| jbe/bsw@0 | 143       open("action_neutral") | 
| jbe/bsw@0 | 144     end | 
| bsw@115 | 145     open_head(node) | 
| jbe/bsw@0 | 146     slot.put( | 
| jbe/bsw@0 | 147       "EXECUTE ACTION: ", | 
| jbe/bsw@0 | 148       encode.html(node.module), | 
| jbe/bsw@0 | 149       "/", | 
| jbe/bsw@0 | 150       encode.html(node.action) | 
| jbe/bsw@0 | 151     ) | 
| jbe/bsw@0 | 152     close_head() | 
| jbe/bsw@0 | 153     if node.status == "softfail" then | 
| jbe/bsw@0 | 154       render_children( | 
| jbe/bsw@0 | 155         '<li class="trace_action_status">Status code: "' .. | 
| jbe/bsw@0 | 156         encode.html(node.failure_code) .. | 
| jbe/bsw@0 | 157         '"</li>' | 
| jbe/bsw@0 | 158       ) | 
| jbe/bsw@0 | 159     else | 
| jbe/bsw@0 | 160       render_children() | 
| jbe/bsw@0 | 161     end | 
| jbe/bsw@0 | 162     close() | 
| jbe/bsw@0 | 163   elseif node_type == "redirect" then | 
| jbe/bsw@0 | 164     open("redirect") | 
| bsw@115 | 165     open_head(node) | 
| jbe/bsw@0 | 166     slot.put("303 REDIRECT TO VIEW: ", encode.html(node.module), "/", encode.html(node.view)) | 
| jbe/bsw@0 | 167     close_with_children() | 
| jbe/bsw@0 | 168   elseif node_type == "forward" then | 
| jbe/bsw@0 | 169     open("forward") | 
| bsw@115 | 170     open_head(node) | 
| jbe/bsw@0 | 171     slot.put("INTERNAL FORWARD TO VIEW: ", encode.html(node.module), "/", encode.html(node.view)) | 
| jbe/bsw@0 | 172     close_with_children() | 
| jbe@223 | 173   --[[ | 
| jbe/bsw@0 | 174   elseif node_type == "exectime" then | 
| jbe/bsw@0 | 175     open("exectime") | 
| bsw@115 | 176     open_head(node) | 
| jbe/bsw@0 | 177     slot.put( | 
| jbe/bsw@0 | 178       "Finished after " .. | 
| jbe@65 | 179       string.format("%.1f", extos.monotonic_hires_time() * 1000) .. | 
| jbe/bsw@0 | 180       ' ms (' .. | 
| jbe/bsw@0 | 181       string.format("%.1f", os.clock() * 1000) .. | 
| jbe/bsw@0 | 182       ' ms CPU)' | 
| jbe/bsw@0 | 183     ) | 
| jbe/bsw@0 | 184     close_with_children() | 
| jbe@223 | 185   --]] | 
| jbe/bsw@0 | 186   elseif node_type == "sql" then | 
| jbe/bsw@0 | 187     open("sql") | 
| jbe/bsw@0 | 188     if node.error_position then | 
| jbe/bsw@0 | 189       -- error position starts counting with 1 | 
| jbe/bsw@0 | 190       local part1 = string.sub(node.command, 1, node.error_position - 1) | 
| jbe/bsw@0 | 191       local part2 = string.sub(node.command, node.error_position) | 
| jbe/bsw@0 | 192       slot.put(encode.html(part1)) | 
| jbe/bsw@0 | 193       slot.put('<span class="trace_error_position">⇒</span>') | 
| jbe/bsw@0 | 194       slot.put(encode.html(part2)) | 
| jbe/bsw@0 | 195     else | 
| jbe/bsw@0 | 196       slot.put(encode.html(node.command)) | 
| jbe/bsw@0 | 197     end | 
| jbe@296 | 198     slot.put(" (execution time: ", format_time(node.execution_time), ")") | 
| jbe/bsw@0 | 199     close(); | 
| jbe/bsw@0 | 200   elseif node_type == "error" then | 
| jbe/bsw@0 | 201     open("error") | 
| bsw@115 | 202     open_head(node) | 
| jbe/bsw@0 | 203     slot.put("UNEXPECTED ERROR") | 
| jbe/bsw@0 | 204     close_head() | 
| jbe/bsw@0 | 205     close() | 
| jbe/bsw@0 | 206   end | 
| jbe/bsw@0 | 207 end |