Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Make the perflogger storage configurable

Add a cvs based storage
Bugfixes
  • Loading branch information...
commit c03683f5df594f4ca73f24151789eb46b65a6845 1 parent 9dfb7a7
@gggeek authored
View
86 classes/ezperflogger.php
@@ -103,7 +103,7 @@ static public function filter( $output )
$size = strlen( $output );
if ( $size == 0 )
$size = '-';
- $text = $_SERVER["REMOTE_ADDR"] . ' - - [' . strftime( '%d/%b/%Y:%H:%M:%S %Z' ). '] "' . $_SERVER["REQUEST_METHOD"] . ' ' . $_SERVER["REQUEST_URI"]. ' ' . $_SERVER["SERVER_PROTOCOL"] . '" 200 ' . $size . ' "' . @$_SERVER["HTTP_REFERER"] . '" "' . @$_SERVER["HTTP_USER_AGENT"] . '" ';
+ $text = $_SERVER["REMOTE_ADDR"] . ' - - [' . date( 'd/M/Y:H:i:s O' ) . '] "' . $_SERVER["REQUEST_METHOD"] . ' ' . $_SERVER["REQUEST_URI"]. ' ' . $_SERVER["SERVER_PROTOCOL"] . '" 200 ' . $size . ' "' . @$_SERVER["HTTP_REFERER"] . '" "' . @$_SERVER["HTTP_USER_AGENT"] . '" ';
foreach( $ini->variable( 'GeneralSettings', 'TrackVariables' ) as $i => $var )
{
/// @todo should remove any " or space chars in the value for proper parsing by updateperfstats.php
@@ -119,7 +119,10 @@ static public function filter( $output )
{
$counters[$var] = $values[$i];
}
- eZPerfLoggerStorage::updateStats( array( array(
+ $storageClass = $ini->variable( 'GeneralSettings', 'StorageClass' );
+ /// @todo log error id storage class does not implement correct interface
+ // when we deprecate php 5.2, we will be able to use $storageClass::insertStats...
+ call_user_func( array( $storageClass, 'insertStats' ), array( array(
'url' => $_SERVER["REQUEST_URI"],
'ip' => $_SERVER["REMOTE_ADDR"],
'time' => time(),
@@ -138,7 +141,7 @@ static public function parseLog( $logFilePath )
$contentArray = array();
- $plIni = eZINI::instance( 'ezperformacelogger.ini' );
+ $plIni = eZINI::instance( 'ezperformancelogger.ini' );
$sys = eZSys::instance();
$varDir = $sys->varDirectory();
@@ -166,8 +169,10 @@ static public function parseLog( $logFilePath )
}
}
-// $cli->output( "Start line:\n" . $startLine );
$lastLine = "";
+ $startTime = time();
+ $count = 0;
+ $storageClass = $plIni->variable( 'GeneralSettings', 'StorageClass' );
if ( is_file( $logFilePath ) )
{
@@ -176,52 +181,69 @@ static public function parseLog( $logFilePath )
{
$noteVars = $plIni->variable( 'GeneralSettings', 'TrackVariables' );
$noteVarsCount = count( $noteVars );
- $startParse = false;
+ $startParse = !$hasStartLine;
$stopParse = false;
- while ( !feof ($handle) and !$stopParse )
+ while ( !feof( $handle ) and !$stopParse )
{
$line = fgets( $handle, 1024 );
if ( !empty( $line ) )
{
- if ( $line != "" )
- $lastLine = $line;
+ $lastLine = $line;
- if ( $startParse or !$hasStartLine )
+ if ( $startParse )
{
- $logPartArray = preg_split( "/[\"]+/", $line );
- $timeIPPart = $logPartArray[0];
- list( $ip, $timePart ) = explode( '[', $timeIPPart, 2 );
- list( $time, $rest ) = explode( ' ', $timePart, 2 );
+ if ( !preg_match( '/([0-9.]+) +([^ ]+) +([^ ]+) +\[([^]]+)\] +(.+)/', $line, $matches ) )
+ {
+ /// @todo log warning
+ continue;
+ }
+ $datetime = DateTime::createFromFormat( 'd/M/Y:H:i:s O', $matches[4] );
+ if ( !$datetime )
+ {
+ /// @todo log warning
+ continue;
+ }
+ $time = $datetime->format( 'U' );
+ $ip = $matches[1];
if ( $time == $startTime )
$stopParse = true;
- $requirePart = $logPartArray[1];
- list( $requireMethod, $url ) = explode( ' ', $requirePart );
+ $logPartArray = explode( '"', $matches[5] ); //preg_split( "/[\"]+/", $line );
+ list( $requireMethod, $url, $protocol ) = explode( ' ', $logPartArray[1] );
/// NB: we assume there is no " in the 'perf counters' part
- $notePart = $logPartArray[count($logPartArray)-1];
+ $notePart = ltrim( rtrim( $logPartArray[count( $logPartArray )-1], " \n\r" ), ' ' );
$notes = explode( ' ', $notePart );
if ( count( $notes ) < $noteVarsCount )
{
-// $cli->output( "Warning: log file line does not match configuration: not enough perf counters found." );
+ /// @todo log warning
+ continue;
}
- else
- {
- $contentArray[] = array(
- 'url' => $url,
- 'time' => $time,
- 'ip' => trim( $ip ),
- 'counters' => array_combine( $noteVars, $notes ) );
- /// @todo if $contentArray grows too big, we're gonna go OOM
- /// so we should update db incrementally
- }
+ $contentArray[] = array(
+ 'url' => $url,
+ 'time' => $time,
+ 'ip' => $ip,
+ /// @todo if the number of elements found is bigger than the number expected, we will not add anything. Use array_slice
+ 'counters' => array_combine( $noteVars, $notes ) );
+ // if $contentArray grows too big, we're gonna go OOM, so we update db incrementally
+ $count++;
+ if ( ( $count % 1000 ) == 1 )
+ {
+ /// @todo log error if storage class does not implement correct interface
+ // when we deprecate php 5.2, we will be able to use $storageClass::insertStats...
+ call_user_func( array( $storageClass, 'insertStats' ), $contentArray );
+ $contentArray = array();
+ }
}
- if ( $line == $startLine )
+ else
{
- $startParse = true;
+ if ( $line == $startLine )
+ {
+ $startParse = true;
+ }
}
}
}
@@ -241,7 +263,9 @@ static public function parseLog( $logFilePath )
if ( count( $contentArray ) )
{
- eZPerfLoggerStorage::updateStats( $contentArray );
+ /// @todo log error if storage class does not implement correct interface
+ // when we deprecate php 5.2, we will be able to use $storageClass::insertStats...
+ call_user_func( array( $storageClass, 'insertStats' ), $contentArray );
}
$dt = new eZDateTime();
@@ -258,7 +282,7 @@ static public function parseLog( $logFilePath )
eZDebug::writeError( "Could not store last date up perf-log file parsing in $updateViewLogPath, double-counting might occur", __METHOD__ );
}
- return count( $contentArray );
+ return $count;
}
}
View
41 classes/ezperfloggercsvstorage.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Class used to store performance data in a csv file.
+ *
+ * The idea is to store data in a format more friendly to spreadsheets than the web server access log
+ *
+ * @author G. Giunta
+ * @copyright (C) G. Giunta 2008-2012
+ * @license Licensed under GNU General Public License v2.0. See file license.txt
+ */
+class eZPerfLoggerCSVStorage implements eZPerfLoggerStorage
+{
+
+ /**
+ *
+ */
+ public static function insertStats( $data )
+ {
+ $ini = eZINI::instance( 'ezperformancelogger.ini' );
+ $csvfile = $ini->variable( 'csvSettings', 'FileName' );
+ $separator = $ini->variable( 'csvSettings', 'Separator' );
+ $quotes = $ini->variable( 'csvSettings', 'Quotes' );
+ $fp = fopen( $csvfile, 'a' );
+ if ( !$fp )
+ {
+ return false;
+ }
+ foreach( $data as $line )
+ {
+ $data = $line['counters'];
+ $data[] = date( 'd/M/Y:H:i:s O', $line['time'] );
+ $data[] = $line['ip'];
+ $data[] = $quotes . str_replace( $quotes, $quotes . $quotes, $line['url'] ). $quotes;
+ fwrite( $fp, implode( $separator, $data ) . "\n" );
+ }
+ fclose( $fp );
+ return true;
+ }
+}
+
+?>
View
51 classes/ezperfloggerstorage.php
@@ -1,51 +0,0 @@
-<?php
-/**
- * Class used to store performance data.
- *
- * The idea is to store one row for each access to the site (if it had perf data associated);
- * additional "summary" tables might be created later on.
- * @see piwik_log_action and piwik_log_link_visit_action tables for a possible implementation
- *
- * @todo we could introduce an Interface and an "instance" method later on to make storage configurable
- *
- * @author G. Giunta
- * @copyright (C) G. Giunta 2008-2012
- * @license Licensed under GNU General Public License v2.0. See file license.txt
- */
-class eZPerfLoggerStorage extends eZPersistentObject
-{
-
- static function definition()
- {
- return array(
- 'fields' => array(),
- 'class' => 'eZPerfLoggerStorage',
- 'name' => ''
- );
- }
-
- /**
- * Adds in the db new data points (one per line)
- *
- * @param array $data Format for array of data:
- * 'url' => string,
- * 'time' => int,
- * 'ip' => string,
- * 'counters' => array
- */
- public static function updateStats( $data )
- {
- /// @todo
-
- }
-
- /**
- * Deletes all stats data
- */
- public static function resetStats()
- {
- /// @todo
- }
-}
-
-?>
View
20 interfaces/ezperfloggerstorage.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @author G. Giunta
+ * @copyright (C) G. Giunta 2008-2012
+ * @license Licensed under GNU General Public License v2.0. See file license.txt
+ */
+interface eZPerfLoggerStorage
+{
+ /**
+ * @param array $data Format for array of data:
+ * 'url' => string,
+ * 'time' => int,
+ * 'ip' => string,
+ * 'counters' => array
+ * @return bool false on error
+ */
+ public static function insertStats( $data );
+}
+
+?>
View
20 settings/ezperformancelogger.ini
@@ -26,4 +26,22 @@ LogMethods[]=logfile
#LogMethods[]=database
# The name of the log file, for example mytest.log
-PerfLogFileName=D:/var/log/ezperflog.log
+PerfLogFileName=D:/temp/var/log/ezperflog.log
+
+# The php class which will be used to store the perf data (typically in a db):
+# when the updateperfstats cronjob is run, it parses the access log, extracts
+# data and passes it to this class to storing elsewhere
+# supported: eZPerfLoggerDBStorage, eZPerfLoggerCSVStorage
+# NB: when the logmethod "database" is used (see parameter above), perf data
+# is stored directly to the db just as if eZPerfLoggerDBStorage was used here.
+# In fact, in that case you should not run the cronjob, as you will get double
+# statistics
+StorageClass=eZPerfLoggerCSVStorage
+
+# The following settings apply when StorageClass=eZPerfLoggerCSVStorage
+[csvSettings]
+FileName=D:/temp/var/log/ezperflog.csv
+# separator char for csv
+Separator=;
+# quotes around url. Can be left empty
+Quotes=
Please sign in to comment.
Something went wrong with that request. Please try again.