PHP получает счетчик в соответствии с флагами из текстового файла

Я делаю файл журнала, который регистрируется следующим образом:

[08-12-2016 22:59:38.000000] [Error] Testing
[08-12-2016 22:59:45.000000] [Error] Testing
[08-12-2016 23:03:37.000000] [warning] Testing

Я пытаюсь сделать функцию, которая может прочитать общее предупреждение и общее количество ошибок в файле журнала. Следующий код работает нормально. Вопрос: есть ли лучший способ сделать это?

$file = file( $complete_filename );

$totalErrors = 0;
$totalWarnings = 0;

foreach($file as $rows) {

if(strpos( $rows,  "[warning]")) $totalWarnings ++;
if(strpos( $rows,  "[Error]"))   $totalErrors ++;

}

echo "$totalWarnings/$totalErrors";

0

Решение

Файлы журнала могут быть довольно большими. file Функция читает весь файл в память. Если файл очень большой, тогда PHP может не хватить памяти, и вы получите ошибку.

Чтобы избежать нехватки памяти, вы можете использовать fopen чтобы получить дескриптор файла, а затем читать одну строку за раз, используя fgets:

$totalErrors = 0;
$totalWarnings = 0;

$fh = fopen($complete_filename, 'rb');

if ($fh) {
while (($line = fgets($fh, 4096)) !== false) {
if (strpos($line, "[Error]") !== false) {
$totalErrors++;
}
if (strpos($line, "[warning]") !== false) {
$totalWarnings++;
}
}
}
fclose($fh);
2

Другие решения

В зависимости от того, что вы можете разрешить в сообщении об ошибке, ваш подход может дать или не дать больше ошибок / предупреждений, чем фактических строк журнала, потому что вы ищете только совпадение подстроки в каждой строке. Такой что бревно [08-12-2016 22:59:38.000000] [Error] Testing [warning] выдает 1 ошибку и 1 предупреждение для одной строки.

Вместо этого вы можете попробовать использовать регулярное выражение, чтобы быть более прилежным.

$logResults = array_map(function($line) {
if (preg_match('/\[.*\]\s\[(Error|warning)\]/', $line, $match)) {
return $match[1];
}
}, file($logFileName));

$errors = array_filter($logResults, function($l) { return $l === 'Error'; });
$warnings = array_filter($logResults, function($l) { return $l === 'warning'; });

echo "Number of errors: $errors\n";
echo "Number of warnings: $warnings\n";
2

Вы можете использовать вызов функции PHP substr_count() чтобы посчитать количество совпадений строк внутри строки.

$logs = file( $complete_filename );

$totalErrors = substr_count($logs, '[Error]');
$totalWarnings = substr_count($logs, '[warning]');

echo $totalWarnings . ' warnings and ' . $totalErrors . ' errors';
0
По вопросам рекламы [email protected]