Я не уверен, как это слово, так что я ввожу его, а затем редактировать и отвечать на любые вопросы, которые приходят ..Tailing Log File и запись результатов в новый файл
В настоящее время на моем локальном устройстве сети (Основанный на PHP4) Я использую это для того, чтобы зажать текущий файл журнала системы: http://commavee.com/2007/04/13/ajax-logfile-tailer-viewer/
Это работает хорошо и каждые 1 секунду он загружает внешнюю страницу (logfile.php), которая выполняет tail -n 100 logfile.log
. Скрипт не делает буферизация, так что результаты, отображаемые на экране, - это последние 100 строк из файла журнала.
logfile.php содержит:
<? // logtail.php $cmd = "tail -10 /path/to/your/logs/some.log"; exec("$cmd 2>&1", $output);
foreach($output as $outputline) {
echo ("$outputline\n");
}
?>
Эта часть работает хорошо.
Я приспособил страницу logfile.php написать $ outputline в новый текстовый файл, просто используя fwrite($fp,$outputline."\n");
Хотя это работает у меня возникли проблемы с дублированием в новый файл, который создается.
Очевидно, что каждый раз, когда tail -n 100 запускает результаты, при следующем запуске он может создавать некоторые из тех же строк, что и повторяется, я могу в итоге получить несколько строк дублирования в новом текстовом файле.
Я не могу напрямую сравнить строку, которую я собираюсь написать предыдущим строкам, так как могут быть одинаковые совпадения.
Есть ли способ сравнить этот текущий блок из 100 строк с предыдущим блоком, а затем написать строки, которые не совпадают. Опять возможная проблема, что блок A & B будет содержать идентичные строки, которые необходимы .. .
Возможно ли обновить logfile.php, чтобы отметить позицию, в которой он последний раз принимался в моем файле журнала, а затем читать только следующие 100 строк и записать их в новый файл?
Файл журнала может быть до 500 МБ, так что я не хочу, чтобы прочитать все это в каждый раз ..
Любые советы или предложения приветствуются ..
Благодаря
UPDATE @ 16 : 30
я вроде получил эту работу, используя:
$file = "/logs/syst.log";
$handle = fopen($file, "r");
if(isset($_SESSION['ftell'])) {
clearstatcache();
fseek($handle, $_SESSION['ftell']);
while ($buffer = fgets($handle)) {
echo $buffer."<br/>";
@ob_flush(); @flush();
}
fclose($handle);
@$_SESSION['ftell'] = ftell($handle);
} else {
fseek($handle, -1024, SEEK_END);
fclose($handle);
@$_SESSION['ftell'] = ftell($handle);
}
Это похоже на работу, но сначала загружает весь файл, а затем только обновления.
Как я могу начать с последних 50 строк, а затем только обновлений?
Спасибо :)
UPDATE 04/06/2013 Хотя это работает он очень медленно с большими файлами.
Я пробовал этот код, и он кажется быстрее, но он не просто читает, откуда он остановился.
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);
}
// 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);
}
Любой способ, которым это может быть изменено, поэтому он будет читать из последнего известного положения ..?
Благодаря
Моего первым было бы предложение обновить PHP. http://php.net/eol.php – vascowhite
К сожалению, это невозможно.Он встроен в устройство :( – MacMan
Может ли устройство работать perl? Это может быть эпический однострочный в perl .. –