Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Performantes Auslesen einer Log-Datei

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Performantes Auslesen einer Log-Datei

    Hallo,

    ich möchte gerne eine Log-Datei performant auslesen und weitergeben - Datei oder DB. Da habe ich zur Zeit aber eine kleine Blockade wie ich das vernünftig umsetzen kann. Vielleicht hat ja jemand eine Idee.

    Die Log-Datei hat unterschiedliche Sequenzen:

    Bsp1:
    ----------------- OPERATION 0000XX ----------------
    Create Time :
    Start Time :
    End Time :
    ...
    Socket Mode :
    Abandoned :
    Result Code :

    Bsp2:
    ----------------- OPERATION 0000XX ----------------
    Create Time :
    Start Time :
    End Time :
    ...
    Abandoned :
    Result Code :
    Error Message :


    Zeilenweise auslesen:

    PHP-Code:
    $file=fopen($argv[1], "r");
    $line_num 0;
    while(
    $data fgets($file)){
        
    $line_num++;
        
    $data1[]=trim(substr($data,18,99));
        
    $data2[]=trim(substr($data,0,18));

    Wiedergabe:
    PHP-Code:
    foreach ($data1 as $value) {
            echo 
    $value.";";
        } 
    Problem bei dieser Variante ist, das erst die komplette Datei eingelesen wird und dann erst die Wiedergabe erfolgt. Ich würde es gerne so machen, dass er jede Zeile gleich abarbeitet und bei einer neuen Operation einen neue Zeile bzw. Datensatz anlegt. Hat jemand eine Idee?

    Die Variante mit 'explode' habe ich auch schon probiert. Problem ist hier nur, dass das Datum wie folgt aufgebaut ist:

    Create Time :Thu Jan 15 13:01:41.631530 2015

    PHP-Code:
    while($data fgets($file)){
        
    $line_num++;
        
    $data=explode(":",$data));

    Damit wird die Uhrzeit komplett zerschnitten.


  • #2
    Limit für explode setzen!
    Oder mit regulären Ausdrücken selektieren.
    PHP-Klassen auf github

    Kommentar


    • #3
      Du kannst bei explode ein Limit setzen.

      Kommentar


      • #4
        Okay, das habe ich dann versehentlich überlesen.

        Folgendes funktioniert erstmal:

        PHP-Code:
        while($data fgets($file)){
            
        $line_num++;
                
        $data1=explode(":",$data,2);
            
        $data2[]=trim($data1[1]);
            
        $data3=implode(";",$data2);

        Das Problem bei der Variante ist, das ich die Zuordnung zu dem ersten Block z.B. "Create Time: ...." verliere. Dies ist leider variable bei den unterschiedlichen Operationen (Bind, Search, unbind). Hat noch jemand eine Idee?

        Kommentar


        • #5
          http://de.wikipedia.org/wiki/Endlicher_Automat

          Kommentar


          • #6
            Habe jetzt einen Weg gefunden, wie ich nur benötigte Wert herausfiltern kann. Ist aber noch ein wenig uncharmant meiner Meinung. Beispiel Ausgabe in einer Datei:

            PHP-Code:
            while($data fgets($file)){
                
            $line_num++;
                
            $data4[]=trim($data);
            }
            foreach (
            $data4 as $value) {
                    
            $data5=explode(":"$value2);
                    if (
            $value == "") {
                        echo 
            "\n";
                    }elseif (
            trim($data5[0]) == "Create Time") {
                        
            # Funktioniert
                        
            echo $data5[1].";";
                    } ....

            Das Problem hier wiederum ist, wenn z.B. ein Wert nicht gesetzt ist, wird hier gar nichts eingetragen und somit würden dann die Spalten nicht stimmen. Jemand vielleicht noch eine andere Idee?

            Kommentar


            • #7
              Erklär mal genau was für Intormationen aus der Datei ausgelesen werden sollen. Der Code in deinem letzten Post sieht ziemlich für die Tonne aus.

              Kommentar


              • #8
                Das LOG hat unter einer Operation Werte wie User, IP, Anfragezeitpunkt usw. Und dies möchte ich gerne pro Operation heraufiltern, damit diese dann weiter verarbeitet werden. Diese stehen aber nicht wie in einer CSV-Datei in einer Zeile, sondern eine Operation kann ca. 10-15 Zeilen haben, wobei rechts immer der angefragte Wert stand und links der zurückgegebene Wert.

                Habe den Code auch nochmal verbessert (wenigstens ein wenig) Damit bekomme ich aber wenigstens die benötigten Werte immer zu einer Operation. Wenn auch erstmal nur in einer Datei ausgegeben.

                PHP-Code:
                $file=fopen($argv[1], "r");
                while(
                $data fgets($file)){
                    
                $line_num++;
                    
                $data4[]=trim($data);
                }

                foreach (
                $data4 as $value) {
                        
                $data5=explode(":"$value2);
                        if (
                $value == "") {
                            echo 
                "\n";
                        }elseif (
                preg_match("*OPERATION*"$data5[0])) {
                            
                # Funktioniert
                            
                $data6=explode(" ",$data5[0]);
                            echo 
                $data6[1]." ".$data6[2].";";
                        }elseif (
                preg_match("*Create Time*"$data5[0])) {
                            
                # Funktioniert
                            
                echo $value.";";
                        } ...

                Kommentar


                • #9
                  Warum liest du zuerst alle Zeilen in ein Array ein und gehst dann die eingelesenen Daten nochmals zur Verarbeitung durch? Dachte du willst etwas performantes? So verbrätst du ja total den Vorteil von fopen/fgets.. da könntest auch gleich alles mit file() in ein Array stopfen -> memory-Limit bei großen Logs.

                  Mach doch eine Hauptschleife - das Zeilenweise einlesen - und im Zuge dessen darin dann die Behandlung der Daten, was auch immer du dann mit den extrahierten Werten vorhast, das hast du uns ja nach wie vor nicht verraten. Und ein komplettes Beispiel von zwei Einträgen (wie #1) mit Daten (zumindest Dummys) wären auch nicht verkehrt.
                  Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                  PHP.de Wissenssammlung | Kein Support per PN

                  Kommentar


                  • #10
                    Okay korrekt, das hätte ich gleich sehen sollen. Es geht mir ersten Schritt erstmal nur um die Auswertung der LOGs, die relativ groß sein können.

                    Hier ein Beispiel für die Operation "unbind":
                    ----------------- OPERATION 000028 ----------------
                    Create Time :Mon Jan 19 01:35:23.XXXXXX 2015
                    Start Time :Mon Jan 19 01:35:23.XXXXXX 2015
                    End Time :Mon Jan 19 01:35:23.XXXXXX 2015
                    OpUUID :XXXXXXX
                    Concurrency :1
                    OpStackSize :1
                    OpFlow In/Out :0/0
                    Duration :0.000115 sec
                    User : user
                    IP+Port+Sd : IP
                    Op-Name : con
                    Operation :UNBIND
                    Version :2
                    MessageID :2
                    Bytes Received :7
                    Bytes Returned :0
                    Socket Mode : plain
                    Abandoned :no
                    Result Code :0 (success)

                    ----------------- OPERATION 002528 ----------------
                    ...

                    Habe den Code entsprechend geändert und läuft jetzt wirklich performanter!

                    PHP-Code:
                    while($data fgets($file)){
                        
                    $line_num++;
                        
                    $data1=explode(":",$data,2);
                    if (
                    trim($data1[0]) == "") {
                            echo 
                    "\n";
                        } elseif (
                    preg_match("*OPERATION*"$data1[0])) {
                            
                    $data2=explode(" ",$data);
                            echo 
                    $data2[1]." ".$data2[2].";";
                        }elseif (
                    preg_match("*Create Time*"$data1[0])) {
                            echo 
                    trim($data).";";
                        }elseif (
                    preg_match("*Start Time*"$data1[0])) {
                            echo 
                    trim($data).";";
                            }elseif (
                    preg_match("*End Time*"$data1[0])) {
                            echo 
                    trim($data).";";
                            } ....

                    Kommentar

                    Lädt...
                    X