In Datei lesen und auf Veränderung prüfen

Thomas_Jung

Erfahrenes Mitglied
Hallo,
ich möchte die Datei (mysql_error.log) alle 5 Minuten auf Fehler überprüfen.
Das klapp so weit auch. (Wenn zum Beispiel ein [Warning] im Text vorkommt, soll die Zeile angezeigt werden)

Zu Problem:
Wenn sich die Datei nach 5 Minuten verändert haben soll (z.b. wenn ein Wort hinzukommt) möchte nur die Veränderungen angezeigt bekommen.

Kann mir jemand dabei helfen?


PHP:
$file = 'mysql_error.log';
$file_handle = fopen($file, 'r');
echo '<div style=" padding:5px; text-align:left">';
while (!feof($file_handle)) {
    $line = fgets($file_handle);

    if(strpos($line, '[Warning]') !== FALSE)
    {
      echo '<br />' . $line;
    }

}
echo '</div>';
fclose($file_handle);

Die Datei mysql_error.log habe ich in mysql_error.log.txt unbenannt um sie hochzuladen.
 

Anhänge

  • mysql_error.log.txt
    781 Bytes · Aufrufe: 4
Du kannst ja den Zeitstemepel am Anfang abrufen und auf "Jetzt - 5 Minuten" prüfen.

Oder den letzten angezeigten Zeitstempel in eine Textdatei speichern und damit filtern.
 
... und der Zeitstempel ist im ISO-Format, 19 Zeichen lang.
Parse das aus der Zeile raus, und dann wie Yaslaw gesagt hat:
Wenn GeparsterZeitstempel>=(Jetzt - 5 Minuten) UND enthält [Warning] DANN,.....

EDIT: Zum Ausparsen und umwandeln in ein DateTime-Format:
PHP: DateTimeImmutable::createFromFormat - Manual
PHP:
date_create_immutable_from_format('Y-m-d G:i:s', GeparsterZeitStempelAlsString)
 
Zuletzt bearbeitet:
PHP:
$file = 'mysql_error.log';

if (file_exists($file)) {
    $zeit = date ("F d Y H:i:s", filemtime($file));
    echo "$file wurde zuletzt modifiziert: " . date ("F d Y H:i:s.", filemtime($file));
}

$handle = fopen("zeit.txt","w");
fwrite($handle,$zeit);
fclose($handle);

//Nach 5 Minuten
$zeit_2 = date ("F d Y H:i:s", filemtime($file));
$handle = fopen("zeit_2.txt","w");
fwrite($handle,$zeit_2);
fclose($handle);
*/

$datei_1 = file('zeit.txt');
$datei_2 = file('zeit_2.txt');

$differenz  = array_diff($datei_2, $datei_1);

$fp = fopen("ergebnis.txt", "w");
foreach($differenz as $row){
    fputs($fp, $row);
}
fclose($fp);

Jetzt weiß ich, wenn die Datei ergebnis.txt nicht leer ist, hat sich die Datei verändert.
Jetzt muss ich noch alles in eine extra Datei speicher, was sich verändert hat.
 
Und wieso
PHP:
$datei_1 = file('zeit.txt');
$datei_2 = file('zeit_2.txt');
Du hast doch die erforderlichen Daten schon.

Und das ist auch nicht tot zu kriegen:

zeit.txt
zeit_2.txt

Wo ist zeit_1.txt? :p:p:p:p
 
Die Idee, die Differenz aus alt und neu zu bilden, finde ich gar nicht schlecht, wenn sie auch möglicher Weise eine Menge Arbeitsspeicher brauchen könnte, je nach Dateigröße.
Könnte dann so aussehen:
Code:
<?php
$fileName = 'mysql_error.log';
$oldFileName = 'oldLogfile.log';
$fileNameWarning = 'logfileWarnings.log';
if (file_exists($oldFileName)) {
    $oldLog = file($oldFileName);
    $newLog = file($fileName);
    $diffs = array_diff($newLog, $oldLog);
    // Jetzt kannst Du die Warnungen heraus filtern
    // und das Ergebnis in die andere Datei schreiben
    foreach ($diffsFiltered as $line) {
        file_put_contents($fileNameWarning, $line . PHP_EOL, FILE_APPEND);
    }
    // und noch die neue Datei zur alten machen
}
Das Filtern habe dabei weg gelassen, kannst Du sicher problemlos selbst hinzu fügen. Ebenso das Umbenennen der neuen in die alte Datei.
Und ungetestet.
Das Ganze dann alle 5 Minuten ausführen.
 
PS: Nach weiterer Überlegung kann man das noch ein ganzes Stück vereinfachen, weil man die alten Warnings ja ohnehin schon zur Verfügung hat:
Code:
$fileName = 'mysql_error.log';
$fileNameWarnings = 'logfileWarnings.log';
if (file_exists($fileNameWarnings)) {
    $warnings = file($fileNameWarnings);
    $handle = fopen($fileName, 'r');
    while (!feof($handle)) {
        $line = fgets($handle);
        // Hier jetzt auf warning filtern
        // und das Ergebnis in $lineWarning ablegen
        if (!in_array($lineWarning, $warnings)) {
            file_put_contents($fileNameWarning, $line . PHP_EOL, FILE_APPEND);
        }
    }
}
(ebenfalls ungetestet)
 
Zuletzt bearbeitet:
wenn sie auch möglicher Weise eine Menge Arbeitsspeicher brauchen könnte
Und genau das kann man verhindern.

Ohne Kopieren und Einlesen der kompletten Log-Datei:
PHP:
<?php
   $fn = "mysql.log";
 
   $error_size = filesize($fn);
 
   $last_size = 0;
 
   if (file_exists("last_size.txt"))
       $last_size = trim(file_get_contents("last_size.txt"));
   else
       $last_size = $error_size;
 
   $new_lines = array();
 
   if ($error_size > $last_size)
   {
       $fp = fopen($fn, "r");
     
       $count = 0;
     
       if (fseek($fp, $last_size) == 0)
       {
          while (!feof($fp))
          {            
              if (($line = fgets($fp, 4096)) !== false)
              {            
                 $new_lines[] = $line;
                 $count++;
              }
          }
         
          echo "$count lines found<br>";
       }
       else
           die ("fseek error");
     
       fclose($fp);
     
       var_dump($new_lines);
   }
 
   file_put_contents("last_size.txt", $last_size);
?>
 

Neue Beiträge

Zurück