设为首页 收藏本站
查看: 809|回复: 0

[经验分享] PHP

[复制链接]

尚未签到

发表于 2015-8-27 09:06:04 | 显示全部楼层 |阅读模式
对xdebug不感冒,还是喜欢查看error.log来定位问题。

想找个工具来监视error.log的最新修改,无果。

还是自己动手吧,先到htdocs下建目录log:


DSC0000.gif DSC0001.gif log/index.php
DSC0002.gif <!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> DSC0003.gif
DSC0004.gif DSC0005.gif         body {}{
DSC0006.gif             font: 10pt helvetica;
            padding: 20px;
DSC0007.gif         }
        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;
        }
DSC0008.gif     </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
     * [Tue Sep 29 13:04:38 2009] [error] [client 127.0.0.1] PHP Parse error:  parse error in E:\\apache\\httpd\\htdocs\\log\\index.php on line 135
     */
    function extractLine($line) {
        global $MONTHS;
        $rv = array();

        // if '[notice]' contained in the line, ignore it
        $ignore = '/\[notice\]/i';
        if (preg_match($ignore, $line)) {
            return $rv;
        }

        // this is what we are interested
        $interested = '/^\[.+([a-z]{3}) ([0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2}) ([0-9]{4})\] \[([a-z]+)\] \[.+\] (.+)$/i';
        $matches = array();
        if (preg_match($interested, $line, $matches)) {
            $rv = array(
                'month' => $MONTHS[$matches[1]],
                'day' => $matches[2],
                'time' => $matches[3],
                'year' => $matches[4],
                'type' => $matches[5],
                'text' => $matches[6]
            );
        }
        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 [today] 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 = '/^([a-z_]+) *=? *"?([^"]+)"?$/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[1];
                    $value = $matches[2];
                    $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、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-104794-1-1.html 上篇帖子: PHP之星际设计模式上(转自lightsaber) 下篇帖子: [原创]keheng浅谈PHP中MVC框架之目录结构
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表