PHPとAjaxによる簡易ログ解析を作ってみた

一般には公開しないような管理者専用の画面で、ログファイルをブラウザから表示、絞り込みができればいいなぁと思ったので作ってみた。
 

仕上がりイメージ

先に仕上がりイメージを見せるとこんな感じ。
CSSはほとんどいじっていないのでもっと見やすくはできると思う。


 

実装する機能

  1. ログを日付ごとにローテーションしている場合、プルダウンメニュー(select)を作り、ファイルを選択してその日の分だけ表示させる
  2. Fatal errorとParse errorだけ、Warningまで、等の絞り込みがチェックボックスで画面切り替えなしに可能(Ajax)
  3. Fatal error等のエラーレベルを色分け

色分けに関して、ひとまず目がチカチカしそうだったので、エラーレベルの文字列だけにstyleを適用するようにしているが、行全体に色をつけるのでもよい。
 

実装内容

冗長な感じがしないでもないが、ログの種類が変わっても書き換えやすいかと。
 

<form method="POST" id="logext" name="logext"
      class="logselect"
      action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
    <select id="logfile" name="logfile">
        <option value="">- Select -</option>
<?php
        // "php.log.20171120" のような形式でログが保存されていることとする
        foreach(glob('./php.log.*') as $file) {
            $splFileObject = new SplFileObject($file);
            $logPathname = $splFileObject->getPathname();
            $logFilename = $splFileObject->getFilename();
            preg_match('|\d{4}\\d{2}\\d{2}|', $logFilename, $logdate);
?>
            <option value="<?php echo $logPathname; ?>">
                <?php echo $logdate[0]; ?>
            </option>
<?php
         }
?>
    </select>

    <input type="checkbox" id="fatalcheck" checked>Fatal error
    <input type="checkbox" id="parsecheck" checked>Parse error
    <input type="checkbox" id="warningcheck" checked>Warning
    <input type="checkbox" id="deprecatedcheck" checked>Deprecated
    <input type="checkbox" id="noticecheck" checked>Notice
</form>

<!--ここにログを表示-->
<div id="dspLogfile"></div>

 

$(function() {
    $('select[name=logfile], #fatalcheck, #parsecheck, #warningcheck, #deprecatedcheck, #noticecheck').on('change', function(){
        var url = {request : $('#logfile').val()};
        var fatalcheck = $('#fatalcheck').prop('checked');
        if (fatalcheck) {
            var fatal = '1';
        } else {
            var fatal = '0';
        }
        var parsecheck = $('#parsecheck').prop('checked');
        if (parsecheck) {
            var parse = '1';
        } else {
            var parse = '0';
        }
        var warningcheck = $('#warningcheck').prop('checked');
        if (warningcheck) {
            var warning = '1';
        } else {
            var warning = '0';
        }
        var deprecatedcheck = $('#deprecatedcheck').prop('checked');
        if (deprecatedcheck) {
            var deprecated = '1';
        } else {
            var deprecated = '0';
        }
        var noticecheck = $('#noticecheck').prop('checked');
        if (noticecheck) {
            var notice = '1';
        } else {
            var notice = '0';
        }
        $.ajax({
            type: "POST",
            url: "dspLogfile.php",
            data: {
                url : url,
                fatal : fatal,
                parse : parse,
                warning : warning,
                deprecated : deprecated,
                notice : notice
            }
        }).done(function(data){
            $('#dspLogfile').html(data);
        });
    });
});

 

<?php
if (session_status() == PHP_SESSION_NONE) {
    header('Expires:-1');
    header('Cache-Control:');
    header('Pragma:');
    session_start();
}

$url = $_POST['url']['request'];
$fatal = $_POST['fatal'];
$parse = $_POST['parse'];
$warning = $_POST['warning'];
$deprecated = $_POST['deprecated'];
$notice = $_POST['notice'];

// 各エラーレベルごとにCSSで定義した色をつけるspanタグに置き換える
foreach(glob($url) as $file) {
    $splFileObject = new SplFileObject($file);
    foreach ( $splFileObject as $line ) {
        if (strpos($line, 'Fatal error') !== false && $fatal == '1') {
            $loglevel_col = "<span class='fatal_color'>Fatal error</span>";
            $line = str_replace('Fatal error', $loglevel_col, $line);
            echo $line . "<br>";
        } else if (strpos($line, 'Parse error') !== false && $parse == '1') {
            $loglevel_col = "<span class='parse_color'>Parse error</span>";
            $line = str_replace('Parse error', $loglevel_col, $line);
            echo $line . "<br>";
        } else if (strpos($line, 'Warning') !== false && $warning == '1') {
            $loglevel_col = "<span class='warning_color'>Warning</span>";
            $line = str_replace('Warning', $loglevel_col, $line);
            echo $line . "<br>";
        } else if (strpos($line, 'Deprecated') !== false && $deprecated == '1') {
            $loglevel_col = "<span class='deprecated_color'>Deprecated</span>";
            $line = str_replace('Deprecated', $loglevel_col, $line);
            echo $line . "<br>";
        } else if (strpos($line, 'Notice') !== false && $notice == '1') {
            $loglevel_col = "<span class='notice_color'>Notice</span>";
            $line = str_replace('Notice', $loglevel_col, $line);
            echo $line . "<br>";
        }
    }
}

 

/* log level color */
.fatal_color {
    color: #F44336;
}
.parse_color {
    color: #D84315;
}
.warning_color {
    color: #FFA000;
}
.deprecated_color {
    color: #673AB7;
}
.notice_color {
    color: #3F51B5;
}

 
 
緊急度の高いエラー順に対処する際、役立ちそう。