PHP
对xdebug不感冒,还是喜欢查看error.log来定位问题。想找个工具来监视error.log的最新修改,无果。
还是自己动手吧,先到htdocs下建目录log:
log/index.php
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>error.log digest</title>
<style>
body {}{
font: 10pt helvetica;
padding: 20px;
}
table {}{
border: none;
border-collapse: collapse;
width: 900px;
margin: 0 auto;
}
th, td {}{
font: 10pt helvetica;
border: 1px solid #ccc;
padding: 10px;
}
th {}{
font-weight: bold;
font-size: 11pt;
}
tr.latest td {}{
background-color: #ffffe1;
}
tr.hint td {}{
background-color: #eee;
}
td.log-time, td.log-type {}{
text-align: center;
}
td.log-text {}{
text-align: left;
}
</style>
</head>
<body>
<?php
/*
* Configurations
*/
require_once 'conf.php';
$CONFIGS = fetchConfigs();
/*
* 'Constants'
*/
$MONTHS = array(
'Jan' => '01',
'Feb' => '02',
'Mar' => '03',
'Apr' => '04',
'May' => '05',
'Jun' => '06',
'Jul' => '07',
'Aug' => '08',
'Sep' => '09',
'Oct' => '10',
'Nov' => '11',
'Dec' => '12'
);
$NOW = new DateTime();
/*
* main()
* In reverse order, i.e, latest on top
*/
{
require_once 'revfile.inc';
$file = new RevFile($CONFIGS['log_file']);
renderBegin();
$limit = isset($CONFIGS['limit_entries']) ? $CONFIGS['limit_entries'] : -1;
// Read limited count of entries, default is 100.
// This is reasonable as we are only interested in the last couple of lines.
// As a side effect, performance improved in this way.
if ($limit > -1) {
while (!$file->sof() && $limit-- > 0) {
$line = $file->getLine();
$parts = extractLine($line);
if (count($parts) > 0) {
renderLine($parts);
}
}
}
// No limit, read all entries
// Either not set in the config file or set to -1.
else {
while (!$file->sof()) {
$line = $file->getLine();
$parts = extractLine($line);
if (count($parts) > 0) {
renderLine($parts);
}
}
}
renderEnd();
}
/**
* Extract each part of a line via RegExp: month, day, time, year, type, text
*
* @sample
* PHP Parse error:parse error in E:\\apache\\httpd\\htdocs\\log\\index.php on line 135
*/
function extractLine($line) {
global $MONTHS;
$rv = array();
// if '' contained in the line, ignore it
$ignore = '/\/i';
if (preg_match($ignore, $line)) {
return $rv;
}
// this is what we are interested
$interested = '/^\[.+({3}) ({2}) ({2}:{2}:{2}) ({4})\] \[(+)\] \[.+\] (.+)$/i';
$matches = array();
if (preg_match($interested, $line, $matches)) {
$rv = array(
'month' => $MONTHS[$matches],
'day' => $matches,
'time' => $matches,
'year' => $matches,
'type' => $matches,
'text' => $matches
);
}
return $rv;
}
function renderBegin() {
global $NOW, $CONFIGS;
$html = '<table><tody>';
$html .= '<tr><th colspan="3">'.$CONFIGS['log_file'].' ('.$NOW->format('Y-m-d H:i:s').')</th></tr>';
$html .= '<tr><th style="width:130px;">Time</th><th>Type</th><th>Text</th></tr>';
echo $html;
}
function renderEnd() {
global $CONFIGS;
$html = '';
if (count($CONFIGS)) {
$html .= '<tr class="hint"><td colspan="3">Configurations (Edit file <a href="log.conf">log.conf</a> to change)</td></tr>';
foreach ($CONFIGS as $key => $value) {
$html .= "<tr class=\"hint\"><td colspan=\"2\">$key</td><td>$value</td></tr>";
}
}
$html .= '</tbody></table>';
echo $html;
}
function renderLine($parts) {
$timeStamp = $parts['year'].'-'.$parts['month'].'-'.$parts['day'].' '.$parts['time'];
$trTag = '<tr>';
$logTime = new DateTime($timeStamp);
// latest: the entry is logged AND [<= 10 minutes]
if (isLatest($logTime)) {
$trTag = '<tr class="latest">';
}
$html = $trTag.'<td class="log-time">'.$timeStamp.'</td><td class="log-type">'.$parts['type'].'</td><td class="log-text">'.$parts['text'].'</td>';
echo $html;
}
function isLatest($logTime) {
global $NOW, $CONFIGS;
$rv = false;
$threshold = $CONFIGS['threshold_mark_latest'];
if ($threshold < 60) {
$rv = ($NOW->format('Y-m-d') == $logTime->format('Y-m-d') &&
$NOW->format('H') == $logTime->format('H') &&
($NOW->format('i') - $logTime->format('i')) < $threshold);
}
return $rv;
}
?>
</body>
</html>
log/revfile.inc
<?php
/*****************************************************
** Title: RevFile Class
** Version.: 1.00
** Author..: Steve Weet <sweet@weet.demon.co.uk>
** Filename: class.RevFile.php
** Last changed..: 30th Jan 2004
** Purpose.: Allows the display of a file in
** ..: In reverse order
******************************************************/
// Example Usage
/*
$file = new RevFile("/etc/passwd");
while (!$file->sof()) {
echo $file->getLine() ;
}
*/
class RevFile
{
protected $_fileName;
protected $_fileHandle;
protected $_filePos;
function __construct($filename)
{
$this->_fileName = $filename;
$this->_fileHandle = @fopen($filename, "r") or die("Could not open file $filename\n");
// Find EOF
if (!(fseek($this->_fileHandle, 0, SEEK_END) == 0)) {
die ("Could not find end of file in $filename\n");
}
// Store file position
$this->_filePos = ftell($this->_fileHandle);
// Check that file is not empty or doesn;t contain a single newline
if ($this->_filePos < 2) {
die ("File is empty\n");
}
// Position file pointer just before final newline
// i.e. Skip EOF
$this->_filePos -= 1;
}
function getLine()
{
$pos = $this->_filePos -1;
$ch=" ";
$line = "";
while ($ch != "\n" && $pos >= 0) {
fseek($this->_fileHandle, $pos);
$ch = fgetc($this->_fileHandle);
// Decrement out pointer and prepend to the line
// if we have not hit the new line
if ($ch != "\n") {
$pos = $pos -1;
$line = $ch . $line;
}
}
$this->_filePos = $pos ;
return $line . "\n";
}
function sof()
{
return ($this->_filePos <= 0);
}
}
?>
log/conf.php
<?php
/**
* Simple config file loading
* @author sol
* @example
* $CONFIGS = fetchConfigs();
* foreach ($CONFIGS as $key => $value) {
* echo "$key = $value<br>";
* }
*/
function fetchConfigs() {
$rv = array();
$lines = file('log.conf');
if ($lines) {
$comment = '/^#/';
$config = '/^(+) *=? *"?([^"]+)"?$/i';
$matches = array();
foreach ($lines as $line) {
$line = trim($line);
// ignore comment, empty line
if (strlen($line) && !preg_match($comment, $line)) {
if (preg_match($config, $line, $matches)) {
$key = $matches;
$value = $matches;
$rv[$key] = $value;
}
}
}
}
else {
die('Could not parse config file: "log.conf"');
}
return $rv;
}
?>
log/log.conf
#
# Path to the log file.
#
log_file = "e:\apache\httpd\logs\error.log"
#
# How many log entries to fetch (one line one entry).
# Keep in mind that we read log file in reverse order.
# -1 means no limit.
# DEFAULT = 100
#
limit_entries = 20
#
# A time threshold setting, in minutes.
# Comparing page-visit-time with log-entry-time, those entries earlier
# than when this program runs, say, 10 mins, shall be marked as the latest.
# There are visual difference between Latest and Normal entries.
# Ranges from 1 to 59 (minutes).
# DEFAULT = 10
#
threshold_mark_latest = 10
打包下载:log.rar
页:
[1]