      1: <?php
      2:
      3: /**
      4:  *
      5:  * A Key Performance Indicator (KPI) logging class
      6:  *
      7:  * @package alpha::util
      8:  * @since 1.1
      9:  * @author John Collins <dev@alphaframework.org>
     10:  * @version $Id: AlphaKPI.inc 1567 2012-08-05 19:57:34Z alphadevx $
     11:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
     12:  * @copyright Copyright (c) 2012, John Collins (founder of Alpha Framework).
     13:  * All rights reserved.
     14:  *
     15:  * <pre>
     16:  * Redistribution and use in source and binary forms, with or
     17:  * without modification, are permitted provided that the
     18:  * following conditions are met:
     19:  *
     20:  * * Redistributions of source code must retain the above
     21:  *   copyright notice, this list of conditions and the
     22:  *   following disclaimer.
     23:  * * Redistributions in binary form must reproduce the above
     24:  *   copyright notice, this list of conditions and the
     25:  *   following disclaimer in the documentation and/or other
     26:  *   materials provided with the distribution.
     27:  * * Neither the name of the Alpha Framework nor the names
     28:  *   of its contributors may be used to endorse or promote
     29:  *   products derived from this software without specific
     30:  *   prior written permission.
     31:  *
     32:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
     33:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
     34:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     35:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     36:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     37:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     38:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     39:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     40:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     41:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     42:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     43:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     44:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     45:  * </pre>
     46:  *
     47:  */
     48: class AlphaKPI {
     49:     /**
     50:      * The date/time of the KPI event
     51:      *
     52:      * @var Timestamp
     53:      * @since 1.1
     54:      */
     55:     private $timeStamp;
     56:
     57:     /**
     58:      * The name of the KPI
     59:      *
     60:      * @var String
     61:      * @since 1.1
     62:      */
     63:     private $name;
     64:
     65:     /**
     66:      * The session ID of the current HTTP session
     67:      *
     68:      * @var string
     69:      * @since 1.1
     70:      */
     71:     private $sessionID;
     72:
     73:     /**
     74:      * The start time of the KPI event (UNIX timestamp in seconds)
     75:      *
     76:      * @var float
     77:      * @since 1.1
     78:      */
     79:     private $startTime;
     80:
     81:     /**
     82:      * The end time of the KPI event (UNIX timestamp in seconds)
     83:      *
     84:      * @var float
     85:      * @since 1.1
     86:      */
     87:     private $endTime;
     88:
     89:     /**
     90:      * The duration in seconds
     91:      *
     92:      * @var float
     93:      * @since 1.1
     94:      */
     95:     private $duration;
     96:
     97:     /**
     98:      * Constructor
     99:      *
    100:      * @param string $name The name of the KPI which is used in the log files, must only be letters and/or numbers.
    101:      * @throws IllegalArguementException
    102:      * @since 1.1
    103:      */
    104:     public function __construct($name) {
    105:         $this->name = new String();
    106:         $this->name->setRule(AlphaValidator::REQUIRED_ALPHA_NUMBEIC);
    107:         $this->name->setHelper('The KPI name can only contain letters and numbers');
    108:
    109:         $this->name->setValue($name);
    110:
    111:         $this->timeStamp = new Timestamp(date('Y-m-d H:i:s'));
    112:
    113:         $this->startTime = microtime(true);
    114:
    115:         if(!isset($_SESSION))
    116:             session_start();
    117:
    118:         // a startTime value may have been passed from a previous request
    119:         if(isset($_SESSION[$name.'-startTime'])) {
    120:             $this->startTime = $_SESSION[$name.'-startTime'];
    121:             $_SESSION[$name.'-startTime'] = null;
    122:         }
    123:
    124:         $this->sessionID = session_id();
    125:     }
    126:
    127:     /**
    128:      * Stores the current startTime for the KPI in the session, useful for multi-request KPI tracking.
    129:      *
    130:      * @since 1.0
    131:      */
    132:     public function storeStartTimeInSession() {
    133:         $_SESSION[$this->name->getValue().'-startTime'] = $this->startTime;
    134:     }
    135:
    136:     /**
    137:      * Writes the KPI event to a log file named logs/kpi-'.$this->name->getValue().'.csv, which will be created if it does
    138:      * not exist.
    139:      *
    140:      * @since 1.1
    141:      */
    142:     public function log() {
    143:         global $config;
    144:
    145:         $this->endTime = microtime(true);
    146:
    147:         $this->duration = $this->endTime - $this->startTime;
    148:
    149:         $logfile = new LogFile($config->get('app.file.store.dir').'logs/kpi-'.$this->name->getValue().'.csv');
    150:
    151:         $logfile->setMaxSize($config->get('app.log.file.max.size'));
    152:         $logfile->setSeperator(',');
    153:
    154:         $logfile->writeLine(array($this->timeStamp, $this->name->getValue(), $this->sessionID, $this->startTime, $this->endTime,
    155:             $this->duration));
    156:     }
    157:
    158:     /**
    159:      * Writes a step in the KPI event to a log file named logs/kpi-'.$this->name->getValue().'.csv, which will be created if it does
    160:      * not exist.
    161:      *
    162:      * @since 1.1
    163:      */
    164:     public function logStep($stepName) {
    165:         global $config;
    166:
    167:         $this->endTime = microtime(true);
    168:
    169:         $this->duration = $this->endTime - $this->startTime;
    170:
    171:         $logfile = new LogFile($config->get('app.file.store.dir').'logs/kpi-'.$this->name->getValue().'.csv');
    172:
    173:         $logfile->setMaxSize($config->get('app.log.file.max.size'));
    174:         $logfile->setSeperator(',');
    175:
    176:         $logfile->writeLine(array($this->timeStamp, $this->name->getValue().' ['.$stepName.']', $this->sessionID, $this->startTime,
    177:             $this->endTime, $this->duration));
    178:     }
    179: }
    180:
    181: ?>