<?php
include "core.php";
head();
?>
				<section role="main" class="content-body">
					<header class="page-header">
						<h2>Error Monitoring</h2>
					
						<div class="right-wrapper pull-right">
							<ol class="breadcrumbs">
								<li>
									<a href="dashboard">
										<i class="fa fa-home"></i>
									</a>
								</li>
                                <li><span>Error Monitoring &nbsp;&nbsp;&nbsp;</span></li>
							</ol>
						</div>
					</header>

					<!-- start: page -->
					<div class="row">
						<div class="col-md-9">
							<section class="panel">
								<header class="panel-heading">
									<div class="panel-actions">
										<a href="#" class="fa fa-caret-down"></a>
										<a href="#" class="fa fa-times"></a>
									</div>

									<h2 class="panel-title">Error Monitoring</h2>
									<p class="panel-subtitle">Scanning of all <kbd>error_log</kbd> files on the site and displaying all errors, warnings and notices.</p>
								</header>
								<div class="panel-body">

<?php
$log_errors = ini_get('log_errors');

if (!$log_errors)
    echo '<p>Error Logging is disabled on your server</p>';

$error_log = ini_get('error_log');
$logs      = array(
    $error_log
);
$count     = 10000;
$lines     = array();

foreach ($logs as $log) {
    if (is_readable($log))
        $lines = array_merge($lines, last_lines($log, $count));
}

$lines = array_map('trim', $lines);
$lines = array_filter($lines);

if (empty($lines)) {
    //echo '<p>No errors found...</p>';
}

foreach ($lines as $key => $line) {
    if (false != strpos($line, ']'))
        list($time, $error) = explode(']', $line, 2);
    else
        list($time, $error) = array(
            '',
            $line
        );
    
    $time        = trim($time, '[]');
    $error       = trim($error);
    $lines[$key] = compact('time', 'error');
}

if (count($error_log) > 1) {
    uasort($lines, array(
        'time_field_compare'
    ));
    $lines = array_slice($lines, 0, $count);
}

?>
        <table class="table table-bordered table-striped mb-none" id="datatable-default">
        <thead>
			<tr>
				<th>Date & Time</th>
				<th>Error</th>
			</tr>
		</thead>
        <tbody>
        <?php
foreach ($lines as $line) {
    $error = $line['error'];
    $time  = $line['time'];
    
    if (!empty($error))
        echo ("<tr><td>{$time}</td><td>{$error}</td></tr>");
}
?>
            </tbody>
        </table> 
        <?php

// Compare callback for freeform date/time strings.
function time_field_compare($a, $b)
{
    if ($a == $b)
        return 0;
    return (strtotime($a['time']) > strtotime($b['time'])) ? -1 : 1;
}

// Reads lines from end of file. Memory-safe.
function last_lines($path, $line_count, $block_size = 512)
{
    $lines = array();
    
    // we will always have a fragment of a non-complete line
    // keep this in here till we have our next entire line.
    $leftover = '';
    
    $fh = fopen($path, 'r');
    // go to the end of the file
    fseek($fh, 0, SEEK_END);
    
    do {
        // need to know whether we can actually go back
        // $block_size bytes
        $can_read = $block_size;
        
        if (ftell($fh) <= $block_size)
            $can_read = ftell($fh);
        
        if (empty($can_read))
            break;
        
        // go back as many bytes as we can
        // read them to $data and then move the file pointer
        // back to where we were.
        fseek($fh, -$can_read, SEEK_CUR);
        $data = fread($fh, $can_read);
        $data .= $leftover;
        fseek($fh, -$can_read, SEEK_CUR);
        
        // split lines by \n. Then reverse them,
        // now the last line is most likely not a complete
        // line which is why we do not directly add it, but
        // append it to the data read the next time.
        $split_data = array_reverse(explode("\n", $data));
        $new_lines  = array_slice($split_data, 0, -1);
        $lines      = array_merge($lines, $new_lines);
        $leftover   = $split_data[count($split_data) - 1];
    } while (count($lines) < $line_count && ftell($fh) != 0);
    
    if (ftell($fh) == 0)
        $lines[] = $leftover;
    
    fclose($fh);
    // Usually, we will read too many lines, correct that here.
    return array_slice($lines, 0, $line_count);
}

?>
                                    
								</div>
							</section>

						</div>
						<div class="col-md-3">
							<section class="panel">
								<header class="panel-heading">
									<div class="panel-actions">
										<a href="#" class="fa fa-caret-down"></a>
										<a href="#" class="fa fa-times"></a>
									</div>

									<h2 class="panel-title">Information & Tips</h2>
								</header>
								<div class="panel-body">
									Logging errors is recommended best practice, even for production site. Checking those logs however might seem like a chore. The error monitoring brings all entries from error log on this page.<br /><br />
                                    <ul>
                                    <li>The log file is detected automatically from the configuration of the server</li>
                                    <li>Only the end of file is read - no memory overflow issues, safe for large logs</li>
                                    <li>Optimized to work well even with very large log files</li>    
                                    </ul>
								</div>
							</section>

						</div>
					</div>
					<!-- end: page -->
				</section>
<?php
footer();
?>