38 public $performance_data;
52 if(!defined(
'SQ_IN_PERFORMANCE_TIMING'))
return;
53 $this->performance_data = Array();
55 $this->timer_stack = Array();
69 if(!defined(
'SQ_IN_PERFORMANCE_TIMING'))
return;
70 unset($this->performance_data);
71 $this->_clearPerformanceData();
73 $this->performance_data[
'total_start'] = microtime(TRUE);
84 if(!defined(
'SQ_IN_PERFORMANCE_TIMING'))
return;
85 $this->performance_data[
'total_end'] = microtime(TRUE);
88 if(!isset($this->performance_data[
'total_num_queries'])) {
89 $this->performance_data[
'total_num_queries'] = 0;
90 $this->performance_data[
'total_time_queries'] = 0;
93 $this->performance_data[
'total_num_queries'] += count($queries);
94 $this->performance_data[
'total_time_queries'] += array_sum($queries);
97 $this->_savePerformanceData($this->performance_data);
113 if(!defined(
'SQ_IN_PERFORMANCE_TIMING'))
return;
114 $assetid = $asset->id;
115 $name = $asset->name;
116 $type_code = $asset->type();
117 if(empty($assetid) || empty($name) || empty($type_code))
return;
120 $time = microtime(TRUE);
121 $this->performance_data[$assetid][
'name'] = $name;
122 $this->performance_data[$assetid][
'type_code'] = $type_code;
123 $this->performance_data[$assetid][
'data'][$step][] = Array (
129 if(!isset($this->performance_data[
'total_num_queries'])) {
130 $this->performance_data[
'total_num_queries'] = 0;
131 $this->performance_data[
'total_time_queries'] = 0;
134 $num_queries = count($logged_queries);
135 $time_queries = array_sum($logged_queries);
137 $this->performance_data[
'total_num_queries'] += $num_queries;
138 $this->performance_data[
'total_time_queries'] += $time_queries;
142 if(!empty($this->timer_stack)) {
143 $parent_timer = $this->timer_stack[count($this->timer_stack) - 1];
144 $parent_assetid = $parent_timer[
'assetid'];
145 $parent_step = $parent_timer[
'step'];
146 $last_position = count ($this->performance_data[$parent_assetid][
'data'][$parent_step]) - 1;
147 $last_position_parent =& $this->performance_data[$parent_assetid][
'data'][$parent_step][$last_position];
150 $last_position_parent[
'end'] = $time;
151 $last_position_parent[
'duration'] = round($time - $last_position_parent[
'start'], 6);
152 $last_position_parent[
'num_queries'] = $num_queries;
153 $last_position_parent[
'time_queries'] = $time_queries;
156 $this->performance_data[$parent_assetid][
'data'][$parent_step][] = Array (
166 $this->timer_stack[] = Array (
167 'assetid' => $assetid,
186 if(!defined(
'SQ_IN_PERFORMANCE_TIMING'))
return;
187 $assetid = $asset->id;
188 $name = $asset->name;
189 $type_code = $asset->type();
190 if(empty($assetid) || empty($name) || empty($type_code))
return;
192 $time = microtime(TRUE);
193 $last_timer =& $this->performance_data[$assetid][
'data'][$step][count($this->performance_data[$assetid][
'data'][$step]) - 1];
194 $last_timer[
'end'] = $time;
195 $last_timer[
'duration'] = round($last_timer[
'end'] - $last_timer[
'start'], 6);
196 $last_timer[
'bar_end'] = TRUE;
199 $count = count($logged_queries);
200 $time_queries = array_sum($logged_queries);
202 $last_timer[
'num_queries'] = $count;
203 $last_timer[
'time_queries'] = $time_queries;
204 $this->performance_data[
'total_num_queries'] += $last_timer[
'num_queries'];
205 $this->performance_data[
'total_time_queries'] += $last_timer[
'time_queries'];
209 $current_stack_timer = array_pop ($this->timer_stack);
211 if(!empty($this->timer_stack)) {
212 $parent_timer = $this->timer_stack[count($this->timer_stack) - 1];
213 $parent_assetid = $parent_timer[
'assetid'];
214 $parent_step = $parent_timer[
'step'];
215 $last_position = count ($this->performance_data[$parent_assetid][
'data'][$parent_step]) - 1;
216 $last_position_parent =& $this->performance_data[$parent_assetid][
'data'][$parent_step][$last_position];
218 $last_position_parent[
'end'] = $time;
219 $last_position_parent[
'duration'] = round($time - $last_position_parent[
'start'], 4);
222 $this->performance_data[$parent_assetid][
'data'][$parent_step][] = Array (
247 $primary_url = current_url(TRUE, TRUE);
248 $this->_clearPerformanceData();
251 if(isset($_GET[
'performance_setting_caching'])) {
252 $_SESSION[
'SQ_PERFORMANCE_SETTING'][
'caching'] = $_GET[
'performance_setting_caching'] ;
253 unset($_GET[
'performance_setting_caching']);
257 if(isset($_GET[
'performance_setting_user'])) {
258 $_SESSION[
'SQ_PERFORMANCE_SETTING'][
'default_user'] = $GLOBALS[
'SQ_SYSTEM']->user->id;
264 foreach($_GET as $name => $value) {
265 if(!empty($param_string))
266 $param_string .=
'&';
267 $param_string .= urlencode($name).
'='.urlencode($value);
269 if(!empty($param_string)) {
270 $param_string =
'?'.$param_string;
273 $timing_url = $primary_url.
'/_performance_timing'.$param_string;
276 $result_url = $primary_url.
'/_performance_result'.$param_string;
279 $title = $asset->name .
' - Squiz Matrix Performance Mode';
281 <!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
282 <html style=
"height: 100%;"><head>
283 <meta http-equiv=
"content-type" content=
"text/html; charset=ISO-8859-1">
285 <TITLE><?php echo $title; ?></TITLE>
286 <SCRIPT LANGUAGE=
"JavaScript">
290 function fillFrame() {
291 parent.content_frame.location.href =
"<?php echo ($timing_url); ?>";
299 <frameset name=
"frames" rows=
"90%,350" frameborder=
"1" framespacing=
"2" border=
"3" bordercolor=#000 onLoad=
"fillFrame();">
300 <frame name=
"content_frame" id=
'content_frame' src=
"about:blank"/>
301 <frame name=
"result_frame" id=
'result_frame' src=
"<?php echo $result_url; ?>" />
322 require_once SQ_DATA_PATH.
'/private/conf/performance_config.inc';
324 header(
'Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
325 header(
'Pragma: no-cache');
326 header(
'Expires: '.gmdate(
'D, d M Y H:i:s', time()-3600).
' GMT');
328 $performance_data = $this->_loadPerformanceData();
330 if(empty($performance_data)) {
331 $this->_printWaitingScreen();
335 $this->performance_data = $performance_data;
338 $caching_status = isset($_SESSION[
'SQ_PERFORMANCE_SETTING'][
'caching']) && $_SESSION[
'SQ_PERFORMANCE_SETTING'][
'caching'] ===
'Off' ?
'Off' :
'Default';
339 $caching_status_reverse = $caching_status ===
'Default' ?
'Off' :
'Default';
342 $as_user =
'Default';
343 $as_user_reverse =
'Public';
344 if(isset($_REQUEST[
'performance_setting_user'])) {
345 if($_REQUEST[
'performance_setting_user'] ===
'Public') {
347 $as_user_reverse =
'Default';
353 foreach ($this->performance_data as $assetid => $content) {
354 if(!is_numeric($assetid))
continue;
358 foreach ($content[
'data'] as $step => $timers) {
359 foreach ($timers as $index => $timer) {
361 $total += $timer[
'duration'];
362 if(isset($timer[
'num_queries']))
363 $num_queries += $timer[
'num_queries'];
368 $slowest[$assetid] = Array(
'time' => $total,
'num_queries' => $num_queries);
370 $active_total += $total;
374 $this->performance_data[$assetid][
'data'][
'all'] = Array();
375 foreach ($content[
'data'] as $step => $timers) {
376 foreach($timers as $timer) {
377 $this->_combineSteps($this->performance_data[$assetid][
'data'][
'all'], $timer);
386 $total_time = $this->performance_data[
'total_end'] - $this->performance_data[
'total_start'];
387 $total_start = $this->performance_data[
'total_start'];
388 $total_assets_count = count($this->performance_data) - 2;
389 $total_num_queries = $this->performance_data[
'total_num_queries'];
390 $total_time_queries = $this->performance_data[
'total_time_queries'];
391 $total_system_time = $total_time - $active_total;
393 <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
396 <meta http-equiv=
"content-type" content=
"text/html; charset=ISO-8859-1">
397 <link rel=
"stylesheet" href=
"<?php echo (sq_web_path('lib').'/web/css/performance.css'); ?>" />
399 <link rel=
"stylesheet" href=
"<?php echo (sq_web_path('lib').'/web/css/performance-ie.css'); ?>" />
401 <script type=
"text/javascript">
403 function toggleExpend(
id) {
405 var rows = getElementsByName_iefix(
"tr",
"row_" +
id);
406 var len = rows.length;
408 for(i=0, k=0, z=0;i<len;i++) {
409 if(rows[i].style.display ==
"none") {
410 rows[i].style.display=
"";
413 for(var j = 0; j < rows[i].childNodes.length; j++)
415 var rowSpan = rows[i].childNodes[j].rowSpan;
416 var className = rows[i].childNodes[j].className;
417 var style = rows[i].childNodes[j].style;
418 if (className ==
"asset-perfAction" || className ==
"asset-perfCell" || style == null) {
423 if( rowSpan == 1 && z == 0) {
424 rows[i].childNodes[j].rowSpan = len - 1;
426 rows[i].childNodes[j].style.display =
"";
427 if(className ==
"assetExpand" || className ==
"assetExpand expanded") {
429 rows[i].childNodes[j].setAttribute(
"class",
'assetExpand expanded');
432 rows[i].childNodes[j].setAttribute(
"class",
'assetExpand');
437 rows[i].childNodes[j].style.display =
"none";
444 rows[i].style.display=
"none";
453 function getElementsByName_iefix(tag, name) {
455 var elem = document.getElementsByTagName(tag);
456 var arr =
new Array();
457 for(i = 0,iarr = 0; i < elem.length; i++) {
458 att = elem[i].getAttribute(
"name");
473 var addUrlParam =
function(search, key, val){
474 var newParam = key +
'=' + val,
475 params =
'?' + newParam;
480 params = search.replace(
new RegExp(
'([\?&])' + key +
'=[^&]*'),
"$1" + newParam);
483 if (params === search && !search.match(
new RegExp(
'([\?&])' + key))) {
484 params +=
'&' + newParam;
497 <div
id=
"perfToolBar">
498 <div
id=
"perfToolBarPadder">
500 <div
id=
"productLogo"><img src=
"<?php echo (sq_web_path('lib').'/web/images/performance/logo-matrix.png'); ?>" alt=
"logo-matrix" width=
"160" height=
"31" /></div>
502 <div
id=
"perfSummary">
503 <div
class=
"perfTotal">Total Time <strong><?php echo ($this->_printTime($total_time)); ?></strong>, System <strong><?php echo ($this->_printTime($total_system_time)); ?></strong> (<?php echo ($this->_printPercent($total_system_time, $total_time, 2)); ?>), Queries: <strong><?php echo ($this->_printTime($total_time_queries)); ?></strong> (<?php echo $total_num_queries; ?>)</div>
504 <div
class=
"perfSwitch">
505 <a href=
"javascript:" onclick=
"javascript:parent.document.location = parent.document.location.pathname + addUrlParam(parent.document.location.search, 'performance_setting_caching', '<?php echo $caching_status_reverse; ?>');" title=
"Use current Matrix Caching setting or disable Matrix Caching" target=
"_top">Caching: <?php echo $caching_status; ?></a>
507 <a href=
"javascript:" onclick=
"javascript:parent.document.location = parent.document.location.pathname + addUrlParam(parent.document.location.search, 'performance_setting_user', '<?php echo $as_user_reverse; ?>');" title=
"Render page as current logged in user or Public User" target=
"_top">
User: <?php echo $as_user; ?></a>
509 <div
class=
"perfHighrollers">
510 <span
class=
"highRoller-label">
Asset count: <strong><?php echo $total_assets_count; ?></strong> Slowest:</span>
511 <span
class=
"highRoller-bar">
515 $top_total_queries = 0;
516 foreach ($slowest as $assetid => $data) {
517 $time = $data[
'time'];
518 $num_queries = $data[
'num_queries'];
521 $top_total_time += $time;
522 $top_total_queries += $num_queries;
523 $width = $this->_printPercent($time, $total_time);
524 $time = $this->_printTime($time);
525 $name = $this->performance_data[$assetid][
'name'];
526 $slowest_class[$assetid] =
'GUI-colourList-position-'.$i;
527 echo
'<span class="highRoller '.$slowest_class[$assetid].
'" style="width: '.$width.
'" title="'.$name.
' '.$time.
', '.$num_queries.
' queries"><span class="highRoller-details">'.$name.
' '.$time.
'</span></span>';
532 $other_width = $this->_printPercent($total_time - $top_total_time, $total_time);
533 $other_time = $this->_printTime($total_time - $top_total_time);
534 $other_queries = $total_num_queries - $top_total_queries;
536 echo
'<span class="highRoller GUI-colourList-position-other" style="width: '.$other_width.
'" title="Other '.$other_time.
', '.$other_queries.
' queries"><span class="highRoller-details">Other '.$other_time.
', '.$other_queries.
' queries</span></span>';
543 <div
id=
"perfContents">
545 <table
id=
"perfTable" cellpadding=
"0" cellspacing=
"0" border=
"0">
559 foreach ($this->performance_data as $assetid => $content) {
560 if(!is_numeric($assetid))
continue;
564 if(isset($performance_config[$content[
'type_code']][
'report'])) {
565 $report =
'<a href="'.$performance_config[$content[
'type_code']][
'report'].
'" target="_blank" >';
568 $step_count = count($content[
'data']);
569 $expendable = $step_count > 1;
570 if($expendable) $step_count = 1;
572 $first_row_printed = FALSE;
573 foreach($content[
'data'] as $step => $data) {
574 if(count($data) == 0)
continue;
579 $row_total_active = 0;
580 $row_total_num_queries = 0;
581 $row_total_time_queries = 0;
582 foreach($data as $time_data) {
583 $total += $time_data[
'duration'];
584 if($time_data[
'active'])
585 $row_total_active += $time_data[
'duration'];
586 if(isset($time_data[
'num_queries'])) {
587 $row_total_num_queries += $time_data[
'num_queries'];
588 $row_total_time_queries += $time_data[
'time_queries'];
591 $row_total = $this->_printTime($row_total);
592 $row_total_active = $this->_printTime($row_total_active);
593 $row_total_time_queries = $this->_printTime($row_total_time_queries);
594 $special_color = isset($slowest_class[$assetid]) ? $slowest_class[$assetid] :
'';
595 $icon_url = $GLOBALS[
'SQ_SYSTEM']->am->getAssetIconURL($content[
'type_code']);
600 echo
'<tr class="expendable" name="row_'.$assetid.
'">';
603 echo
'<tr class="expendable" style="display:none;" name="row_'.$assetid.
'">';
611 <td rowspan=
"<?php echo $step_count; ?>" class=
"assetID">#<?php echo $assetid; ?></td>
612 <td rowspan=
"<?php echo $step_count; ?>" class=
"assetType" style=
"background-image: url(<?php echo $icon_url; ?>)" title=
"<?php echo $content['type_code']; ?>" ><img src=
"<?php echo $icon_url; ?>" alt=
"<?php echo $content['type_code']; ?>" width=
"16" height=
"16" /></td>
613 <td rowspan=
"<?php echo $step_count; ?>" class=
"assetName" title=
"<?php echo 'Active: '.$row_total_active.' / Total: '.$row_total.' / Queries: '.$row_total_time_queries.' ('.$row_total_num_queries.')'; ?>"><?php echo !empty($report) ? $report :
''; echo $content[
'name']; echo !empty($report) ?
'</a>' :
''; ?></td>
616 echo
'<td rowspan="'.$step_count.
'" class="assetExpand" ><div class="expandIcon" onClick="toggleExpend('.$assetid.
')"></div></td>';
619 echo
'<td rowspan="'.$step_count.
'" class="assetExpand" > </td>';
621 $first_row_printed = TRUE;
624 <td
class=
"asset-perfAction" title=
"<?php echo $step; ?>"><?php echo $step; ?></td>
625 <td
class=
"asset-perfCell">
628 foreach($data as $index => $time_data) {
629 if(isset($time_data[
'bar_start'])) {
632 $bar_active_total_time = 0;
633 $bar_num_queries = 0;
634 $bar_time_queries = 0;
636 for ($i = $index, $has_begin = FALSE, $has_end = FALSE; isset($data[$i]) && !($has_begin && $has_end); $i++) {
637 if(isset($data[$i][
'bar_start'])) $has_begin = TRUE;
638 if(isset($data[$i][
'bar_end'])) $has_end = TRUE;
640 $bar_total_time += $data[$i][
'duration'];
641 if($data[$i][
'active'])
642 $bar_active_total_time += $data[$i][
'duration'];
643 if(isset($data[$i][
'num_queries'])) {
644 $bar_num_queries += $data[$i][
'num_queries'];
645 $bar_time_queries += $data[$i][
'time_queries'];
649 $bar_margin_left = $this->_printPercent($time_data[
'start'] - $total_start - $offset, $total_time);
650 $bar_width = $this->_printPercent($bar_total_time, $total_time);
651 $bar_total = $this->_printTime($bar_total_time);
652 $bar_active_total = $this->_printTime($bar_active_total_time);
653 $bar_time_queries = $this->_printTime($bar_time_queries);
656 echo
'<div class="perfBar '.$special_color.
'" style="margin-left:'.$bar_margin_left.
'; width: '.$bar_width.
';" title="Active: '.$bar_active_total.
' / Total: '.$bar_total.
' / Queries: '.$bar_time_queries.
' ('.$bar_num_queries.
')">';
657 echo
'<div style="display:none;">';
661 $block_width = $this->_printPercent($time_data[
'duration'], $bar_total_time);
662 $is_dile = $time_data[
'active'] ?
'' :
'idle';
663 echo
'<div class="perfBlock '.$is_dile.
'" style="width: '.$block_width.
';" ></div>';
665 if(isset($time_data[
'bar_end'])) {
669 $offset = $time_data[
'end'] - $total_start;
675 <div
class=
"perfBar-totals"><?php echo
'Active: '.$row_total_active.
' / Total: '.$row_total; ?></div>
695 unset($this->performance_data);
696 $this->_clearPerformanceData();
707 private function _printWaitingScreen () {
710 <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
711 <html style=
"height: 100%;">
713 <meta http-equiv=
"content-type" content=
"text/html; charset=ISO-8859-1">
714 <link rel=
"stylesheet" href=
"<?php echo (sq_web_path('lib').'/web/css/performance.css'); ?>" />
716 <link rel=
"stylesheet" href=
"<?php echo (sq_web_path('lib').'/web/css/performance-ie.css'); ?>" />
718 <meta http-equiv=
"refresh" content=
"1">
721 <body style=
"height: 100%;">
723 <div
id=
"perfLoading">
724 <span
id=
"loadingMsg">Please wait
while performance is analysed ...</span>
743 private function _printPercent ($time, $total_time, $precision = PERFORMANCE_PERCENTAGE_PRINT_PRECISION) {
744 $percent = round($time / $total_time, $precision) * 100;
758 private function _printTime ($time, $precision = PERFORMANCE_TIME_PRINT_PRECISION) {
759 $time = round($time, $precision);
772 private function _combineSteps (&$all, $timer) {
773 foreach ($all as $index => $current_timer) {
774 if ($timer[
'start'] < $current_timer[
'end'] || ($timer[
'start'] == $current_timer[
'end'] && $timer[
'end'] < $current_timer[
'end'])) {
775 array_splice($all, $index, count($all), array_merge(Array($timer), array_slice($all, $index)));
791 private function _savePerformanceData ($data) {
792 $path = SQ_DATA_PATH.
'/temp/performance_mode_data';
793 $file = fopen ($path,
"w");
794 fwrite($file, serialize($data));
805 private function _clearPerformanceData () {
806 $path = SQ_DATA_PATH.
'/temp/performance_mode_data';
807 if(file_exists($path))
817 private function _loadPerformanceData () {
818 $path = SQ_DATA_PATH.
'/temp/performance_mode_data';
819 $data = file_exists($path) ? file_get_contents($path) :
'';
820 return unserialize($data);