├── trace-own.cache ├── README.markdown ├── xdebug.ini ├── trace-code.php ├── trace.css ├── trace.config.php └── trace.php /trace-own.cache: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Original code from: http://www.rdlt.com/xdebug-trace-file-parser.html 2 | 3 | Detects all the traces in your xdebug trace directory and offers to look at them in a nice way. 4 | -------------------------------------------------------------------------------- /xdebug.ini: -------------------------------------------------------------------------------- 1 | ; Place this file in /etc/php5/conf.d 2 | extension=xdebug.so 3 | xdebug.auto_trace=On 4 | xdebug.trace_format=1 5 | xdebug.trace_output_dir=/var/log/php 6 | xdebug.show_mem_delta=On 7 | xdebug.var_display_max_data=128 8 | xdebug.collect_params=4 9 | xdebug.collect_return=On 10 | xdebug.trace_options=1 11 | xdebug.trace_output_name= %H-%p.trace 12 | xdebug.profiler_output_name = %s.%t.profile 13 | xdebug.profiler_output_dir=/var/log/php 14 | -------------------------------------------------------------------------------- /trace-code.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 9 | 10 | Xdebug Trace File Parser 11 | 12 | 13 | 14 | ($_GET['line'] - 4) && $i < $_GET['line']) { 26 | $class = 'near'; 27 | } 28 | if ($i < ($_GET['line'] + 4) && $i > $_GET['line']) { 29 | $class = 'near'; 30 | } 31 | if ($i == $_GET['line']) { 32 | $class = 'line'; 33 | } 34 | 35 | echo ''; 36 | $i++; 37 | } 38 | ?> 39 |
' . ($i) . '' . str_replace('<?php ', '', highlight_string('
40 | 41 | -------------------------------------------------------------------------------- /trace.css: -------------------------------------------------------------------------------- 1 | *,html * { 2 | font: 12px verdana, sans-serif; 3 | color: black; 4 | } 5 | 6 | strong { 7 | font-weight: bold; 8 | } 9 | 10 | small { 11 | font-size: 11px; 12 | } 13 | 14 | h1 { 15 | font-size: 24px; 16 | font-weight: bold; 17 | } 18 | 19 | h2 { 20 | font-size: 18px; 21 | } 22 | 23 | label { 24 | display: block; 25 | margin-bottom: 5px; 26 | } 27 | 28 | img { 29 | vertical-align: middle; 30 | border: 0; 31 | } 32 | 33 | table { 34 | width: 100%; 35 | } 36 | 37 | td,th { 38 | padding: 3px; 39 | vertical-align: top; 40 | } 41 | 42 | th { 43 | background: #343434; 44 | color: white; 45 | text-align: left; 46 | } 47 | 48 | td.digit { 49 | text-align: right; 50 | } 51 | 52 | a { 53 | color: navy; 54 | text-decoration: none; 55 | } 56 | 57 | a:hover { 58 | text-decoration: underline; 59 | } 60 | 61 | a:visited { 62 | color: purple; 63 | } 64 | 65 | span.warning { 66 | font-weight: bold; 67 | color: maroon; 68 | font-size: 11px; 69 | } 70 | 71 | tr.near td { 72 | background: #fffac1; 73 | } 74 | 75 | tr.line td { 76 | background: #f7f09f; 77 | } 78 | 79 | span.user { 80 | color: chartreuse; 81 | } 82 | 83 | span.native { 84 | color: lightseagreen; 85 | } 86 | 87 | 88 | span.Zend { 89 | color: yellowgreen; 90 | } 91 | 92 | span.Corretge { 93 | color: coral; 94 | } 95 | 96 | 97 | tr:nth-child(even) {background: ivory;} 98 | tr:nth-child(odd) {background: aliceblue;} 99 | -------------------------------------------------------------------------------- /trace.config.php: -------------------------------------------------------------------------------- 1 | $b['cnt']) ? -1 : 1; 29 | } 30 | 31 | function usortByArrayKey(&$array, $key, $asc=SORT_ASC) { 32 | $sort_flags = array(SORT_ASC, SORT_DESC); 33 | if(!in_array($asc, $sort_flags)) throw new InvalidArgumentException('sort flag only accepts SORT_ASC or SORT_DESC'); 34 | $cmp = function(array $a, array $b) use ($key, $asc, $sort_flags) { 35 | if(!is_array($key)) { //just one key and sort direction 36 | if(!isset($a[$key]) || !isset($b[$key])) { 37 | throw new Exception('attempting to sort on non-existent keys'); 38 | } 39 | if($a[$key] == $b[$key]) return 0; 40 | return ($asc==SORT_ASC xor $a[$key] < $b[$key]) ? 1 : -1; 41 | } else { //using multiple keys for sort and sub-sort 42 | foreach($key as $sub_key => $sub_asc) { 43 | //array can come as 'sort_key'=>SORT_ASC|SORT_DESC or just 'sort_key', so need to detect which 44 | if(!in_array($sub_asc, $sort_flags)) { $sub_key = $sub_asc; $sub_asc = $asc; } 45 | //just like above, except 'continue' in place of return 0 46 | if(!isset($a[$sub_key]) || !isset($b[$sub_key])) { 47 | throw new Exception('attempting to sort on non-existent keys'); 48 | } 49 | if($a[$sub_key] == $b[$sub_key]) continue; 50 | return ($sub_asc==SORT_ASC xor $a[$sub_key] < $b[$sub_key]) ? 1 : -1; 51 | } 52 | return 0; 53 | } 54 | }; 55 | usort($array, $cmp); 56 | } 57 | -------------------------------------------------------------------------------- /trace.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 11 | 12 | Xdebug Trace File Parser 13 | 14 | 15 |

Xdebug Trace File Parser

16 |

Settings

17 |
18 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 |
Resum 53 | 59 |

Output

60 | No file selected

'; 85 | } 86 | else if (!file_exists($traceFile)) 87 | { 88 | echo '

Invalid file

'; 89 | } 90 | else 91 | { 92 | 93 | 94 | 95 | /** 96 | * és una manera molt poc eficient de llegir un arxiu. 97 | */ 98 | //$trace = file_get_contents($traceFile); 99 | //$lines = explode("\n", $trace); 100 | 101 | 102 | $previousLevel = 0; 103 | $levelIds = array(); 104 | $ids = 0; 105 | 106 | 107 | $defFn = get_defined_functions(); 108 | /** 109 | * counter 110 | */ 111 | $jCnt = 0; 112 | 113 | /** 114 | * Sumary 115 | */ 116 | $aSumary = array(); 117 | $aSumaryS = array(); 118 | 119 | /** 120 | * Process all lines 121 | */ 122 | //foreach ($lines as $line) 123 | $fh = fopen($traceFile, 'r'); 124 | while ($jReadedLine = fgets($fh)) 125 | { 126 | /** 127 | * Add one to the counter 128 | */ 129 | $jCnt++; 130 | 131 | switch ($xdebug_trace_format) 132 | { 133 | /** 134 | * xdebug.trace_format = 1 Computerized 135 | * @link http://www.xdebug.org/docs/all_settings#trace_format 136 | */ 137 | case 1: 138 | $data = explode("\t", $jReadedLine); 139 | @list($level, $id, $point, $time, $memory, $function, $type, $file, $filename, $line, $numParms) = $data; 140 | 141 | /** 142 | * if there is params save it 143 | */ 144 | if (isset($numParms) and $numParms > 0) 145 | { 146 | $valParms = ''; 147 | for ($i = 11; $i < (11 + $numParms); $i++) 148 | { 149 | $valParms .= "
  • " . str_replace('\n', 150 | '
    ', 151 | htmlentities($data[$i])) . "
  • \n"; 152 | } 153 | } 154 | elseif (!empty($file)) 155 | { 156 | $valParms = "
  • {$file}
  • "; 157 | } 158 | else 159 | { 160 | $valParms = ''; 161 | } 162 | 163 | $memory = round($memory / (1024 * 1024), 4); 164 | 165 | break; 166 | 167 | /** 168 | * Other xdebug.trace_format 169 | * @todo code for all types 170 | */ 171 | default: 172 | 173 | $strippedLine = preg_replace('(([\s]{2,}))', ' ', 174 | trim($line)); 175 | list ($time, $memory) = explode(" ", $strippedLine); 176 | 177 | $memory = round($memory / (1024 * 1024), 4); 178 | 179 | $level = round(((strpos($line, '->') - strpos($line, 180 | $memory) + strlen($memory))) / 2); 181 | 182 | if ($level <= $previousLevel && isset($levelIds[$level])) 183 | { 184 | $fullTrace[$levelIds[$level]]['timeOnExit'] = $time; 185 | $fullTrace[$levelIds[$level]]['memoryOnExit'] = $memory; 186 | } 187 | $id = ++$ids; 188 | $levelIds[$level] = $id; 189 | $previousLevel = $level; 190 | 191 | $parts = array_map('trim', explode("->", $line, 2)); 192 | $parts = explode(" ", $parts[1]); 193 | $function = $parts[0]; 194 | list($line, $file) = array_map('strrev', 195 | explode(":", 196 | strrev($parts[1]), 197 | 2)); 198 | $filename = $file; 199 | $point = 0; 200 | $type = in_array(substr($function, 0, 201 | strpos($function, "(")), 202 | $defFn['internal']) ? 0 : 1; 203 | 204 | $valParms = ''; 205 | 206 | break; 207 | } 208 | 209 | if (empty($function)) 210 | { 211 | $fullTrace[$id]['timeOnExit'] = $time; 212 | $fullTrace[$id]['memoryOnExit'] = $memory; 213 | continue; 214 | } 215 | 216 | 217 | 218 | // if (!empty($filename) and strpos('eyeOS/Loader', $filename) > 0) 219 | // { 220 | // continue; 221 | // } 222 | 223 | if ($point == 0) 224 | { 225 | // starting function 226 | $fullTrace[$id] = array('level' => $level, 227 | 'id' => $id, 228 | 'timeOnEntry' => $time, 229 | 'memoryOnEntry' => $memory, 230 | 'function' => $function, 231 | 'type' => $type, 232 | 'file' => $file, 233 | 'filename' => $filename, 234 | 'line' => $line, 235 | 'valParms' => $valParms); 236 | 237 | if (isset($lastMemory) and ($memory - $lastMemory) > $memJump) 238 | { 239 | $fullTrace[$id]['memoryAlert'] = $memory - $lastMemory; 240 | } 241 | else 242 | { 243 | $fullTrace[$id]['memoryAlert'] = false; 244 | } 245 | 246 | 247 | if (isset($lastMemory) and ($time - $lastTime) > $timeJump) 248 | { 249 | $fullTrace[$id]['timeAlert'] = $time - $lastTime; 250 | } 251 | else 252 | { 253 | $fullTrace[$id]['timeAlert'] = false; 254 | } 255 | 256 | $lastMemory = $memory; 257 | $lastTime = $time; 258 | } 259 | else 260 | { 261 | $fullTrace[$id]['timeOnExit'] = $time; 262 | $fullTrace[$id]['memoryOnExit'] = $memory; 263 | } 264 | } 265 | ?> 266 | 267 | 268 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | "; 290 | var_dump($trace); 291 | echo "
    "; 292 | /** 293 | */ 294 | ?> 295 | 296 | 349 | 357 | 370 | 386 | 387 | 426 |
    269 |
    270 | function calls in seconds, using MB of memory. 272 |
    in = start func.
    out = end func.
    in = start func.
    out = end func.
    Function / FileLineTimeMemory
    306 | \

    334 | 335 | 336 | Warning, time jump exceeds trigger! {$trace['timeAlert']}"; 340 | } 341 | if (isset($trace['memoryAlert']) and $trace['memoryAlert']) 342 | { 343 | echo "
    Warning, memory jump exceeds trigger! {$trace['memoryAlert']}"; 344 | } 345 | ?> 346 |
    347 | 348 |
    350 | {$trace['line']}"; 354 | } 355 | ?> 356 | in: s
    out:
    359 |
    in: MB
    out: MB
    372 | 373 | 374 | 385 |
    427 |

    Sumari de funcions per temps emprat

    436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | "; 446 | 447 | foreach ($aSumary as $row) 448 | { 449 | if ($row['cnt'] != 0) 450 | { 451 | 452 | $jAvgTim = $row['tim'] / $row['cnt']; 453 | $jAvgMem = $row['mem'] / $row['cnt']; 454 | } 455 | else 456 | { 457 | $jAvgTim = 0; 458 | $jAvgMem = 0; 459 | } 460 | 461 | $row['cnt'] = number_format($row['cnt'], 0); 462 | $row['tim'] = number_format($row['tim'], 0); 463 | $row['mem'] = number_format($row['mem'], 0); 464 | 465 | $jAvgMem = number_format($jAvgMem, 0); 466 | $jAvgTim = number_format($jAvgTim, 0); 467 | 468 | echo " 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | "; 477 | } 478 | 479 | 480 | echo "
    Functiontimessum Timesum Memoryavg Timeavg Memory
    {$row['func']}{$row['cnt']}{$row['tim']}{$row['mem']}{$jAvgTim}{$jAvgMem}
    "; 481 | 482 | 483 | 484 | 485 | echo "

    Sumari d'scripts per temps emprat

    486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | "; 496 | 497 | foreach ($aSumaryS as $row) 498 | { 499 | if ($row['cnt'] != 0) 500 | { 501 | 502 | $jAvgTim = $row['tim'] / $row['cnt']; 503 | $jAvgMem = $row['mem'] / $row['cnt']; 504 | } 505 | else 506 | { 507 | $jAvgTim = 0; 508 | $jAvgMem = 0; 509 | } 510 | 511 | $row['cnt'] = number_format($row['cnt'], 0); 512 | $row['mem'] = number_format($row['mem'], 0); 513 | $row['tim'] = number_format($row['tim'], 0); 514 | $jAvgMem = number_format($jAvgMem, 0); 515 | $jAvgTim = number_format($jAvgTim, 0); 516 | 517 | echo " 518 | 519 | 520 | 521 | 522 | 523 | 524 | "; 525 | } 526 | 527 | 528 | echo "
    Scriptinstructionssum Timesum Memoryavg Time per instavg Memory per inst
    {$row['filename']}{$row['cnt']}{$row['tim']}{$row['mem']}{$jAvgTim}{$jAvgMem}
    "; 529 | ?> 530 | 531 | 548 | 549 | 550 | --------------------------------------------------------------------------------