HTTP
|
|
|
|
<?php ///////////////////////////////////////////////////////////////////////////
// file: serverlog.php
///////////////////////////////////////////////////////////////////////////
// author: jez hancock jezhanco@lineone.net
///////////////////////////////////////////////////////////////////////////
// description:
// Parse each line of an apache log file into it's component parts.
// Output the component parts into an html table for ease of viewing
// remotely via a browser.
// Sample log line is included below -
// check your log file format and change script appropriately.
///////////////////////////////////////////////////////////////////////////
// Log file lines this script is based on.
// You will need to change the function parseLog_status() below if your logfile format is different.
// server4.carpediem-it.co.uk - - [08/Sep/2001:00:12:23 -0700] "GET /bands/viewband.php?bandID=21 HTTP/1.0" 200 1572 "http://sonictown.php4hosting.com/bands/listbands.php" "Lynx/2.8rel.2 libwww-FM/2.14" PID28905
//
// r113.easily.co.uk - - [08/Sep/2001:00:13:42 -0700] "GET /cgi-bin/cgiirc/irc.cgi HTTP/1.0" 404 216 "-" "PHP/4.0.3pl1" PID24054
//
// host62-6-86-132.dialup.lineone.co.uk - - [08/Sep/2001:00:14:08 -0700] "GET /bands/viewband.php?bandID=21 HTTP/1.1" 200 1572 "http://sonictown.php4hosting.com/bands/listbands.php" "Mozilla/4.0 (compatible; MSIE 5.0; Windows 95; DigExt)" PID29244
// Full path to access log file on server: $log="access_log";
// attempt to open the log file: $lines=file($log) or die("Cannot open logfile");
// page title: $pageTitle="Apache Combined Server Log Viewer";
// total lines: $totalLines=count($lines);
// will hold lines according to status field of log line:
$status_200=$status_404=$status_304=$status_other=array();
// will hold first and last times in log: $firstTime=$lastTime="";
// START MAIN EXECUTION
###############
// Do the do: parseLog_status($lines); pageOpen();
// display results based on filter: switch($filter){
case "200":
doResults($status_200);
break;
case "304":
doResults($status_304);
break;
case "404":
doResults($status_404);
break;
case "other":
doResults($status_other);
break;
default:
doResults($status_200);
doResults($status_304);
doResults($status_404);
doResults($status_other);
break;
} pageClose(); // END MAIN EXECUTION
####################################
/////////////
// FUNCTIONS
/////////////
####################################
/******************************************************
* Function Name : pageOpen
*
* Task : build the page
*
* Arguments : none
*
* Returns : none
*
******************************************************/ function pageOpen() {
global $status_200,$status_404,$status_304,$status_other,
$totalLines,$firstTime,$lastTime,$pageTitle,$log; ?> <html>
<head>
<title><?php echo $pageTitle ?></title>
</head>
<body>
<h1>Reports for <?php echo($GLOBALS[SERVER_NAME]) ?></h1>
<h2>Access logfile: <?php echo $log ?> </h2>
<h2>Period: <?php print("<b>$firstTime</b> to <b>$lastTime</b>n") ?></h2>
<?php
print("<pre>n");
print("404 pages (page not found): ".count($status_404)."n");
print("200 pages (successful request): ".count($status_200)."n");
print("304 pages: (page not changed): ".count($status_304)."n");
print("other pages: ".count($status_other)."n");
print("Lines in Log: ".$totalLines."n");
print("</pre>n"); ?> <form action="<?php print($GLOBALS[PHP_SELF])?>" method="POST">
Filter Results On Status: <select name="filter">
<option selected>select
<option value="200">200
<option value="404">404
<option value="304">304
<option value="other">Other
</select><input type="submit" name="submit" value="submit">
</form>
<?php } // end func
/******************************************************
* Function Name : parseLog_status($lines)
*
* Task : parse each logfile line into array depending on status
*
* Arguments : $lines - lines from logfile
*
* Returns : none
*
******************************************************/ function parseLog_status($lines) {
global $status_200,$status_404,$status_304,$status_other,$firstTime,$lastTime,$totalLines;
// inc counter - used to check if first or last item in logfile:
$count=0;
// parse each line:
foreach($lines as $line){
// trim spaces just in case:
$line=trim($line);
// split each line of log file at spaces - assumes log file fields are space delimited:
$fields=split(" ", $line);
// SERVER SPECIFIC:
// LAST FIELD IN $FIELDS IS PID, POP THIS OFF STACK:
array_pop($fields);
// server4.carpediem-it.co.uk - - [08/Sep/2001:00:12:02 -0700] "GET /bands/listbands.php HTTP/1.0" 200 1093 "-" "Lynx/2.8rel.2 libwww-FM/2.14" PID22731
// and assign each field a readable name:
$host=$fields[0];
$ident=$fields[1];
$uname=$fields[2];
$dateLong=substr($fields[3], 1);
// get time strings:
$tmp=split(":", $dateLong);
array_shift($tmp);
$UStime=join(":", $tmp);
$UKhr=($tmp[0]+8)%24 ;
$UKhr=str_pad($UKhr, 2, "0", STR_PAD_LEFT);
$UKtime= $UKhr.":".$tmp[1].":".$tmp[2];
$dateOffset=substr($fields[4], 0, 5);
$requestType=substr($fields[5], 1);
$requestURI=$fields[6];
$uaProtocol=substr($fields[7], 0, -1);
$status=$fields[8];
$bytes=$fields[9];
$referer=substr($fields[10], 1, -1);
$ua=implode(" ", array_slice($fields, 11));
// create array of fields for this line:
$result=array(
$host,
$ident,
$uname,
$UStime,
$UKtime,
$requestType,
$requestURI,
$uaProtocol,
$bytes,
$referer,
$ua
);
// Push $result onto an array depending on $status:
switch($status){
case "200":
array_push($status_200, $result);
break;
case "304":
array_push($status_304, $result);
break;
case "404":
array_push($status_404, $result);
break;
default:
array_push($status_other, $result);
break;
}
// check if first or last line - if so get start/end time for period
switch($count){
case 0:
// track first timestamp in log:
$firstTime=$dateLong;
break;
case $totalLines-1:
// track last timestamp in log:
$lastTime=$dateLong;
}
// increment counter:
$count++;
}
} // end func
/******************************************************
* Function Name : doResults($title, $results)
*
* Task : display a table of results/log lines
*
* Arguments : string $title - title of result table
array $results - array of lines to show
*
* Returns : none
*
******************************************************/ function doResults($results) {
global $filter;
isset($filter)?"":$filter="All";
print("<h3>$filter Accesses</h3>n");
if(!empty($results)){
// rpint out results: ?> <br>
<table border="1" cellpadding="2" cellspacing="1">
<tr>
<th> Host </th>
<th> ID </th>
<th> Usr </th>
<th> Time: <br>US<br>(UK)</th>
<th> Request </th>
<th> URI </th>
<th> Protocol </th>
<th> Bytes </th>
<th> Referer </th>
<th> User Agent </th>
</tr>
<?php
foreach($results as $result) {
?> <tr>
<td><?php echo $result[0]; ?></td>
<td><?php echo $result[1]; ?></td>
<td><?php echo $result[2]; ?></td>
<td><?php echo $result[3]."<br>(".$result[4].")"; ?></td>
<td><?php echo $result[5]; ?></td>
<td><?php echo $result[6]; ?></td>
<td><?php echo $result[7]; ?></td>
<td><?php echo $result[8]; ?></td>
<td><?php echo $result[9]; ?></td>
<td><?php echo $result[10]; ?></td>
</tr>
<?php
}
print("</table>n");
} else {
print("No entries of type: $filter<br><br>n");
}
} // end func doResults($title, $results)
/******************************************************
* Function Name : pageClose()
*
* Task : close page - ending html tags
*
* Arguments : none
*
* Returns : none
*
******************************************************/ function pageClose() {
?> </body>
</html>
<?php } // end func pageClose() ?>
|
|
|
Usage Example
|
Sorry, no example for security reasons.
|
|
|
Rate This Script
|
|
|
|