0, 15 => 0, 60 => 0 ]; $dumpList = []; $lastChunk = ''; $peakDumped = false; try { if ( !is_readable($file) ) { throw new Exception($file . ' is not readable.'); } if ( !ENABLE_PEAK_DUMP ) { $peakDumped = TRUE; } $fileSize = filesize($file); $lastFileSize = $fileSize; $startUp = time(); while (true) { clearstatcache(true, $file); $fileSize = filesize($file); $current = time(); if ($lastFileSize != $fileSize) { if ($fileSize < $lastFileSize) { $lastFileSize = 0; } $fileContents = file_get_contents($file, false, null, $lastFileSize, $fileSize); parseLog($fileContents); $lastFileSize = $fileSize; } createLoad(); createPeak(); createSortedList(); refreshSortedTime(); clearTerminal(); // 上段 printHeader(); echo ' '; printLoad(); echo ' '; printPeak(); echo ' '; printFooter(); echo PHP_EOL; echo PHP_EOL; printSortedList(); echo PHP_EOL; printError(); if ( !$peakDumped ) { cleanDumpList(); if ( $peakList[5] >= PEAK_THRESHOLD ) { dumpProcess(); $peakDumped = TRUE; } } sleep(1); } } catch (Exception $e) { echo $e->getMessage() . PHP_EOL; } function parseLog($infile) { global $lastChunk, $begin, $finish, $chunk, $processList, $errorList, $timeList, $startUp, $current, $peakDumped, $dumpList; foreach ( explode("\n", $infile) as $inline ) { if ( $lastChunk !== '' ) { $inline = $lastChunk . $inline; $lastChunk = ''; //$chunk--; } if ( strpos($inline, "\r") !== FALSE ) { $lastChunk = $inline; $chunk++; continue; } $inline = trim($inline); if ($inline == '') { continue; } $cols = explode('] ', $inline); if ( !isset($cols[1]) ) { $errorList[] = 'invalid line: ' . trim($inline); continue; } if ( $cols[1] == PAPYRUS_USERLOG . ' log opened (PC)' ) { $startUp = $current; $begin = 0; $finish = 0; $errorList = []; $processList = []; $timeList = []; //$errorList[] = $cols[1]; continue; } $cols = explode(',', $cols[1]); if ( count($cols) != 4 ) { continue; } $value = $cols[0] . ',' . $cols[1] . ',' . $cols[2]; if ( $cols[3] == 'begin' ) { $begin++; $processList[] = $value; $timeList[] = $current; if ( !$peakDumped ) { $dumpList[] = [ $current, $value ]; } } else if ( $cols[3] == 'finish' ) { $key = array_search( $value, $processList ); if ( $key !== FALSE ) { unset($processList[$key]); $finish++; } else { if ($current - $startUp >= 10) { $errorList[] = 'process not found: ' . $value; } } } } } // 端末を消去 function clearTerminal() { pclose( popen('cls', 'w') ); } // ヘッダ部分を表示 function printHeader() { global $begin, $finish, $running, $chunk; $running = $begin - $finish; printf('Papyrus: %d begin, %d finish, %d running, %d chunk', $begin, $finish, $running, $chunk); } function createLoad() { global $timeList, $loadList, $current; $loadList = [ 5 => 0, 15 => 0, 60 => 0 ]; foreach ($timeList as $key => $timestamp) { if ($current - $timestamp <= 60) { $loadList[60]++; if ($current - $timestamp <= 5) { $loadList[5]++; } if ($current - $timestamp <= 15) { $loadList[15]++; } } else { unset( $timeList[$key] ); } } } function createPeak() { global $loadList, $peakList; foreach ($loadList as $key => $value) { if ( $peakList[$key] < $loadList[$key] ) { $peakList[$key] = $loadList[$key]; } } } function printLoad() { global $loadList; printf('Load: %d, %d, %d', $loadList[5], $loadList[15], $loadList[60]); } function printPeak() { global $peakList; printf('Peak: %d, %d, %d', $peakList[5], $peakList[15], $peakList[60]); } // プロセス一覧を作る function createSortedList() { global $sortedList, $processList, $sortTimeList, $current; $sortedList = []; foreach ($processList as $line) { if ( array_key_exists($line, $sortedList) ) { $sortedList[$line]++; } else { $sortedList[$line] = 1; if ( !array_key_exists($line, $sortTimeList) ) { $sortTimeList[$line] = $current; } } } ksort($sortedList); } // プロセス一覧を表示 function printSortedList() { global $sortedList, $sortTimeList, $current; echo 'Time Num State Function Script'; echo PHP_EOL; foreach ($sortedList as $line => $num) { $past = $current - $sortTimeList[$line]; $cols = explode(',', $line); printf('%04d %3d %-10s %-18s %s', $past, $num, $cols[1], $cols[2], $cols[0]); echo PHP_EOL; } } // プロセスの経過時間一覧を整理 function refreshSortedTime() { global $sortTimeList, $sortedList; foreach (array_keys($sortTimeList) as $line) { if ( !array_key_exists($line, $sortedList) ) { unset($sortTimeList[$line]); } } } // 概要部分を表示 function printFooter() { global $errorList; printf( 'Error: %d', count($errorList) ); /* global $sortedList, $sortTimeList, $errorList; printf('Sorted:%d Time:%d Error:%d', count($sortedList), count($sortTimeList), count($errorList)); */ } // エラーを表示 function printError() { global $errorList; foreach ($errorList as $line) { echo $line . PHP_EOL; } } function dumpProcess() { global $dumpList; $filename = DUMP_LOG_BASE . date('YmdHis') . '.log'; $fp = fopen($filename, 'w'); if (!$fp) { throw new Exception('could not open ' . $filename); } foreach ($dumpList as $data) { fputs($fp, date('Y/m/d H:i:s', $data[0]) . ' ' . $data[1] . PHP_EOL); } fclose($fp); } function cleanDumpList() { global $dumpList, $current; foreach ($dumpList as $key => $data) { if ( $current - $data[0] > 5 ) { unset($dumpList[$key]); } else { break; } } }