Seditio Source
Root |
./othercms/elxis_5.3_atlas_rev2452/includes/libraries/elxis/performance.class.php
<?php
/**
* @version        $Id: performance.class.php 2307 2019-10-28 19:27:02Z IOS $
* @package        Elxis
* @subpackage    Debug
* @copyright    Copyright (c) 2006-2019 Elxis CMS (http://www.elxis.org). All rights reserved.
* @license        Elxis Public License ( http://www.elxis.org/elxis-public-license.html )
* @author        Elxis Team ( http://www.elxis.org )
* @description     Elxis CMS is free software. Read the license for copyright notices and details
*/

defined('_ELXIS_') or die ('Direct access to this location is not allowed');


class
elxisPerformance {

    private
$blocks = array();
    private
$global_time = 0;
    private
$block_time = 0;
    private
$current_block = '';
    private
$sys_errors = 0;
    private
$sys_queries = 0;
    private
$sys_sql = array();
    private
$blocks_sql = array();


   
/*********************/
    /* MAGIC CONSTRUCTOR */
    /*********************/
   
public function __construct() {
        if (
defined('ELXIS_DEFENDER_DT') && (ELXIS_DEFENDER_DT > 0)) {
           
$dt2 = (defined('ELXIS_DEFENDER_DT2')) ? ELXIS_DEFENDER_DT2 : 0;
           
$this->global_time = microtime(true) - (ELXIS_DEFENDER_DT + $dt2);
           
$dt = (ELXIS_DEFENDER_DT + $dt2) * 1000;
           
$dt = number_format($dt, 2, '.', '');
           
$this->blocks['Elxis_Defender'] = array(
               
'file' => 'includes/libraries/elxis/defender.class.php',
               
'exec_time' => $dt,
               
'db_queries' => 0,
               
'errors' => 0
           
);
        } else {
           
$this->global_time = microtime(true);
        }
    }


   
/**************************/
    /* START BLOCK MONITORING */
    /**************************/
   
public function startBlock($name, $file='') {
       
$this->block_time = microtime(true);
        if (
$name == '') { $name = 'Block_'.$this->block_time; }
       
$this->current_block = $name;
       
$this->blocks[$name] = array(
           
'file' => $file,
           
'exec_time' => 0,
           
'db_queries' => 0,
           
'errors' => 0
       
);
    }


   
/*************************/
    /* STOP BLOCK MONITORING */
    /*************************/
   
public function stopBlock() {
        if (
$this->current_block == '') { return; }
       
$name = $this->current_block;
       
$this->blocks[$name]['exec_time'] = $this->stopBenchmark($this->block_time, microtime(true));
       
$this->current_block = '';
    }


   
/****************************************/
    /* INCREASE CURRENT BLOCK ERRORS BY ONE */
    /****************************************/
   
public function addError() {
        if (
$this->current_block == '') {
           
$this->sys_errors++;
            return;
        }
       
$name = $this->current_block;
       
$this->blocks[$name]['errors']++;
    }


   
/********************************************/
    /* INCREASE CURRENT BLOCK DB QUERIES BY ONE */
    /********************************************/
   
public function addQuery($sql='') {
        if (
$this->current_block == '') {
           
$this->sys_queries++;
            if (
$sql != '') { $this->sys_sql[] = $sql; }
            return;
        }
       
$name = $this->current_block;
       
$this->blocks[$name]['db_queries']++;
        if (
$sql != '') {
            if (!isset(
$this->blocks_sql[$name])) {
               
$this->blocks_sql[$name] = array();
            }
           
$this->blocks_sql[$name][] = $sql;
        }
    }


   
/*******************************/
    /* GENERATE PERFORMANCE REPORT */
    /*******************************/
   
private function getReport() {
       
$report = array();
       
$report['global'] = array(
           
'file' => ELXIS_SELF,
           
'exec_time' => $this->stopBenchmark($this->global_time, microtime(true)),
           
'db_queries' => $this->sys_queries,
           
'errors' => $this->sys_errors
       
);

       
$report['system'] = array(
           
'file' => 'includes/loader.php',
           
'exec_time' => $report['global']['exec_time'],
           
'db_queries' => $this->sys_queries,
           
'errors' => $this->sys_errors
       
);

        if (
$this->blocks) {
            foreach (
$this->blocks as $name => $block) {
               
$report['global']['db_queries'] += $block['db_queries'];
               
$report['global']['errors'] += $block['errors'];
               
$report['system']['exec_time'] -= $block['exec_time'];
               
$report[$name] = $block;
            }
        }
        return
$report;
    }


   
/********************************************/
    /* GENERATE PERFORMANCE MONITOR HTML REPORT */
    /********************************************/
   
public function makeReport($debuglevel=0) {
       
$eLang = eFactory::getLang();
       
$report = $this->getReport();

       
$str = '<div class="elx5_box elx5_border_orange">'."\n";
       
$str .= '<div class="elx5_box_body">'."\n";
       
$str .= '<table dir="'.$eLang->getinfo('DIR').'" class="elx5_datatable">'."\n";
       
$str .= '<tr><th colspan="5" class="elx5_themphasis">'.$eLang->get('ELX_PERF_MONITOR').'</th></tr>'."\n";
       
$str .= "<tr>\n";
       
$str .= "\t".'<th>'.$eLang->get('ITEM').'</th>'."\n";
       
$str .= "\t".'<th class="elx5_tabhide">'.$eLang->get('INIT_FILE').'</th>'."\n";
       
$str .= "\t".'<th>'.$eLang->get('EXEC_TIME').'</th>'."\n";
       
$str .= "\t".'<th class="elx5_center elx5_lmobhide">'.$eLang->get('DB_QUERIES').'</th>'."\n";
       
$str .= "\t".'<th class="elx5_center">'.$eLang->get('ERRORS').'</th>'."\n";
       
$str .= "</tr>\n";
       
$k = 0;
        foreach (
$report as $name => $data) {
           
$rowclass = ($name === 'global') ? 'elx_trx' : 'elx_tr'.$k;
            if (
strlen($data['file']) > 20) {
               
$file_txt = '<span title="'.$data['file'].'" style="cursor: pointer;">...'.substr($data['file'], -17).'</span>';
            } else {
               
$file_txt = $data['file'];
            }

           
$name = ucfirst(str_replace('_', ' ', $name));
           
$timestr = ($data['exec_time'] > 400) ? number_format(($data['exec_time']/1000), 2, '.', '').' sec' : $data['exec_time'].' ms';
           
$str .= '<tr class="'.$rowclass.'">'."\n";
           
$str .= "\t<td>".$name."</td>\n";
           
$str .= "\t<td class=\"elx5_tabhide\" dir=\"ltr\">".$file_txt."</td>\n";
           
$str .= "\t<td>".$timestr."</td>\n";
           
$str .= "\t".'<td class="elx5_center elx5_lmobhide">'.$data['db_queries']."</td>\n";
           
$str .= "\t".'<td class="elx5_center">'.$data['errors']."</td>\n";
           
$str .= "</tr>\n";
           
$k = 1 - $k;
        }
       
$str .= "</table>\n";
       
$str .= "</div>\n</div>\n";

        if (
$debuglevel > 1) {
           
$str .= $this->makeMemoryReport();
        }
        if (
$debuglevel > 3) {
           
$str .= $this->makePluginsReport();
        }
       
$str .= $this->makeSQLReport();
        return
$str;
    }


   
/****************************/
    /* MAKE SQL QUERRIES REPORT */
    /****************************/
   
private function makeSQLReport() {
        if (!
$this->sys_sql && !$this->blocks_sql) { return ''; }
       
$eLang = eFactory::getLang();

       
$str = '<div class="elx5_box elx5_border_orange">'."\n";
       
$str .= '<div class="elx5_box_body">'."\n";
       
$str .= '<table dir="'.$eLang->getinfo('DIR').'" class="elx5_datatable">'."\n";
       
$str .= '<tr><th class="elx5_themphasis">'.$eLang->get('DB_QUERIES').'</th></tr>'."\n";
        if (
$this->sys_sql) {
           
$str .= '<tr><th>System</th></tr>'."\n";
            foreach (
$this->sys_sql as $sql) {
               
$str .= '<tr><td dir="ltr">'.htmlspecialchars($sql)."</td></tr>\n";
            }
        }
        if (
$this->blocks_sql) {
            foreach (
$this->blocks_sql as $name => $sqls) {
                if (
$sqls) {
                   
$str .= '<tr><th>'.ucfirst($name)."</th></tr>\n";
                    foreach (
$sqls as $sql) {
                       
$str .= '<tr><td dir="ltr">'.htmlspecialchars($sql)."</td></tr>\n";                
                    }
                }
            }
        }
       
$str .= "</table>\n";
       
$str .= "</div>\n</div>\n";
        return
$str;
    }


   
/**************************/
    /* MAKE PHP MEMORY REPORT */
    /**************************/
   
private function makeMemoryReport() {
        if (!
function_exists('memory_get_usage')) { return ''; }
        if (!
function_exists('memory_get_peak_usage')) { return ''; }

       
$mu = memory_get_usage();
       
$mu = $this->getSize($mu);
       
$mup = memory_get_peak_usage();
       
$mup = $this->getSize($mup);

       
$str = '<div class="elx5_box elx5_border_orange">'."\n";
       
$str .= '<div class="elx5_box_body">'."\n";
       
$str .= '<table class="elx5_datatable">'."\n";
       
$str .= '<tr><th colspan="2" class="elx5_themphasis">Memory usage by PHP</th></tr>'."\n";
       
$str .= '<tr><th>Used memory</th><td dir="ltr">'.$mu."</td></tr>\n";
       
$str .= '<tr><th>Memory peak</th><td dir="ltr">'.$mup."</td></tr>\n";
       
$str .= "</table>\n";
       
$str .= "</div>\n</div>\n";
        return
$str;
    }


   
/*******************************/
    /* MAKE CONTENT PLUGINS REPORT */
    /*******************************/
   
private function makePluginsReport() {
        if (
defined('ELXIS_ADMIN')) { return; }

       
$eLang = eFactory::getLang();
       
$data = eFactory::getPlugin()->runData();

       
$str = '<div class="elx5_box elx5_border_orange">'."\n";
       
$str .= '<div class="elx5_box_body">'."\n";
       
$str .= '<table dir="'.$eLang->getinfo('DIR').'" class="elx5_datatable">'."\n";
       
$str .= '<tr><th colspan="2" class="elx5_themphasis">'.$eLang->get('CONTENT_PLUGINS').'</th></tr>'."\n";
       
$str .= '<tr><th>Available plugins</th><td dir="ltr">'.implode(', ', $data['plugins'])."</td></tr>\n";
       
$str .= '<tr><th>Articles processed</th><td dir="ltr">'.$data['runtimes']."</td></tr>\n";
       
$str .= '<tr><th>Plugin executions</th><td dir="ltr">'.$data['plugintimes']."</td></tr>\n";
       
$str .= "</table>\n";
       
$str .= "</div>\n</div>\n";
        return
$str;
    }


   
/******************************/
    /* HUMAN FRIENDLY SIZE FORMAT */
    /******************************/
   
private function getSize($bytes) {
        if (
$bytes < 1024) { return $bytes.' bytes'; }
        if (
$bytes < 1048576) { return round($bytes/1024, 2).' KB'; }
        return
round($bytes/1048576, 2).' MB';
    }


   
/******************/
    /* STOP BENCHMARK */
    /******************/
   
private function stopBenchmark($start, $end) {
       
$total_time = $end - $start;
       
$total_time = $total_time * 1000;
        return
number_format($total_time, 2, '.', '');
    }

}

?>