Announcement

Collapse
No announcement yet.

Logdatei darf Maximalgrösse nicht übersteigen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Logdatei darf Maximalgrösse nicht übersteigen

    Wie bringe ich es fertig, das meine Logdatei vor dem Anhängen einer Zeile prüft ob das Logfile grösser als eine maximale Grösse ist, und wenn nötig ältere Zeilen entfernt?<br>
    Helmut

  • #2
    Hallo,<p>
    ich habe es so realisiert:<br>
    Bevor die Zeile in die Logdatei geschrieben wird, habe ich die Dateigrösse ermittelt, die neue länge der Zeile errechnet und beide Werte addiert. Jetzt das ganze mit einem vogegeben Wert verglichen. Ist der Wert kleiner oder gleich, dann wurde die Zeile in die Datei eigefügt, ansonsten wurde die letzte (älteste) Zeile gelöscht. War nun die Logdatei immer noch zu gross, wurde die nächste Zeile gelöscht usw., bis die Datei + der Zeile die Maximalgrösse nicht überschreitet hat

    Comment


    • #3
      <pre>Hallo,
      wie wird den in die Datei geschrieben. Was ich vermeiden muß ist, die
      ganze Datei in den Arbeitsspeicher zu laden. Dazu würden diese immer noch zu groß werden 64 K.
      Die neuen Zeilen werden zur Zeit mit "writeln" unten angehängt. Also müsste oben gelöscht werden.
      Was aber noch besser ist, die neuen Zeilen würden oben angehängt und unten würde gelöscht. Aber wie könnte man das realisieren?

      Helmut ? </pre&gt

      Comment


      • #4
        Beides würde das selektive Umkopieren der kompletten Datei bedeuten.
        Im Falle von Textdateien machen wir es so das wir zwei Logdateien haben. Überschreitet die Größe der Log 1 einen Wert wird die Log 2 gelöscht und Log 1 als Log 2 gespeichert. Dann wird Log 1 neu erzeugt und der neue Datensatz ans Ende angehängt.<br>
        D.h. erst wird überprüft ob Log 1 die Größe überschritten hat. Wenn ja wird Log 2 gelöscht, Log 1 umbenannt in Log 2. Dann wird Log 1 geöffnet, bzw. neu erstellt, ans Ende positioniert und der Datensatz gespeichert.

        Gruß Hage

        Comment


        • #5
          <pre>Hallo Hagen,
          Ich habe bereits zwei Logdateien, eine für den aktuellen Lauf des Programms und eine alls summiertes Log. Nun sollen die Zeilen des ersten (aktuellen Log) in die Summenlogdatei so kopiert werden das diese neuen Zeilen oben landen. Wenn die Summenlogdaten zu groß wird sollen entsprechend unten Zeilen abgeschnitten werden.
          Ich habe dazu bereits einiges versucht.
          Zunächst habe ich die Summenlogdaten unter anderem Namen umkopiert.
          Dann alle drei Dateien mit einem FileStream geöffnet und zusammen in die entgültige Summenlogdatei geschrieben.
          Nur möchte ich noch ein Hinweis in die verbleibende Daten machen, was mir zur Zeit nicht gelingt.

          Helmut </pre&gt

          Comment


          • #6
            Hallo Helmut,<p>
            warum so umständlich? Ich meine, es ist OK, dass Du die Log-Datei auf einer konstanten Maximal-Größe halten willst. Aber die Frage ist, welchen Vorteil Du davon hast? Du nutzt den Platten-Platz effizient aus. Hagens Dateibegrenzung bracht effektiv maximal den doppelten Platz, nämlich kurz vor dem Umbenennen. Dafür braucht er aber die Log-Datei nicht groß anfassen sondern immer nur ganz Ressourcen-schonend anfügen (Append und Writeln).<p>
            Schöne Grüße, Mario Noac
            Schöne Grüße, Mario

            Comment


            • #7
              <pre>Hallo,
              mir gefällte das Umkopieren und so auch nicht so richtig!
              Nur müsste man wissen wie man es besser macht!
              Die Ereignisanzeige von Win-NT ist ein gutes Beispiel. Wie geht das
              da... Wer kennt sich mit diesen Mechanismen aus?
              Helmut </pre&gt

              Comment


              • #8
                &gt; mir gefällte das Umkopieren und so auch nicht so richtig!<p>
                Ein löschen der alten und umbenennen der aktuellen Datei reicht völlig.<p>
                Mario Noac
                Schöne Grüße, Mario

                Comment


                • #9
                  Ok, gut schau ma mal wie Windows Log's das machen.<br>
                  1. Windows Logs' sind binär kodiert, also nicht lesbar und diese Tatsache lässt vermuten das Windows da noch mehr speichert.<br>
                  2. Macht man Performancetest so sieht man das das Log System periodisch in die Knie geht. Das deutet darauf hin das Windows intern eine bestimmte Anzahl von Log's im Speicher verwaltet und gruppenweise in die Datei speichert.<br>
                  3. Die Performance ist ungleich schlechter als mein oben vorgeschlagener Weg.<br>Dies ist aber entscheidend, da sich die Frage stellt: Wie hoch soll der Prozentsatz der Log-Dateien-Proceduren am gesammten Program sein ? Es wäre doch schwachsinnig eine Anwendung mit einem hochkomplexen Logsystem auszustatten, was dazu noch extrem ineffizient ist.<br>

                  Alles deutet darauf hin das Windows in seinen Logfiles mit Index und festen Headern arbeitet. Dies vereinfacht erheblich das Umkopieren da nun Informationen zur Verfügung stehen wo welche zeitliche geordneten Logs in der Datei stehen. Ich vermute das die Windows-logdateien eben nicht physikalisch chronologisch geordnet sind, sondern ein Index benutzt wird. Dies wäre auch logisch da das Wegschreiben der Logs viel viel schneller gehen sollte als das Auslesen und wiederherstellen der korrekten Reihenfolge. Zudem muss das Logsystem in der Lage sein Filter auf die Logtypen setzen zu können.

                  Gruß Hage

                  Comment


                  • #10
                    <pre>Hallo,
                    das hört sich nicht gut an.
                    Nun deine Möglichkeit ist dann immer noch aktuell!
                    Ich habe es wie gesagt bisher so versucht,
                    kopieren altes gesamtlog;
                    einzellog öffnen;
                    altes gesamtlog öffnen;
                    neues gesamtlog öffnen;

                    einzellog in neues gesamtlog schreiben (mit stream.copyfrom);
                    altes gesamtlog in neues gesamtlog schreiben (stream.copyfrom);

                    nun kommte es: das neue gesamtlog soll eventuell abgeschnitten werden. Und einen Hinweis, das abgeschitten ist eintragen, natürlich
                    am Ende. Da brauchte ich mal deine Hilfe!

                    Zum Schluss dann altes Gesamtlog löschen.

                    Wie kann ich in den Stream einen Text schreiben?
                    Ich habe es mit TStringStream versucht, bekomme aber eine
                    Schutzverletzung? Ich so etwas schon öffter gemacht und geht normalerweise auch. Nur diesmal ist es in einem Thread, ist da bei TStringStream etwas zu beachten??

                    Helmut</pre&gt

                    Comment


                    • #11
                      <pre>

                      Stream.Write(PChar(Text)^, Length(Text));
                      Stream.Write(#13#10, 2);

                      </pre>

                      Im Falle des Abschneidens musst du im Stream von hinten nach vorne alle CR's = #13#10 suchen, solange bis die Größe stimmt.<br>
                      Aber ich empfehle Dir denoch meine Methode zu nutzen. Was passiert in deinem Beispiel wenn die Datei die Größe erreicht ? Jedesmal wenn eine Log hinzugefügt werden soll muß nun die komplette Datei kopiert werden, und immer das letzte CR gesucht werden. <br>
                      Ich halte dies für viel zu ineffizient für zu wenig echten Vorteil.
                      Dann lieber gleich die Windows-Log Funktionen benutzt.<br>
                      Leider gibt es im ASCII kein "unsichtbares" Füllzeichen. Denn dann könntest Du die Datei mit fester Größe mit diesem Zeichen auffüllen. Jedes Log würde dann diese Zeichen von hinten nach vorne überschreiben. Der ASCII Viewer würde aber die ersten "unsichtbaren" zeichen überspringen. Naja, leider gibts sowas aber nicht.
                      Ansonsten wäre da noch der Weg über eine Indexdatei zu jeder Logdatei. In diesem Index speicherst Du für jeden Logtext einen festen Record bestehend aus Datum + Offset in die Logdatei. Nun kann diese Logdatei entweder mit einem Standard-Viewer betrachtet werden und würde das selber Resultat liefern wie meine Lösung. Oder aber mit einem speziellen Viewer der die Indexdatei auslesen kann. Dieser Viwer lässt sich sehr einfach programmieren. Er lädt die Indexdatei, sortiert diese nach Datum, bzw. eigentlich ist sie schon aufsteigend sortiert. Nun stellt er die Logtexte in umgekehrter Reihenfolge wie sie in der Indexdatei stehen dar. Das hat alles sehr viele Vorteile. Z.b. könnte der Indexrecord zusätzlich zum Datum und Offset in die Indexdatei noch zusätzlich eine ID des Benutzers oder des Vorganges enthalten. Auch der Typ der meldung könnte so kodiert werden. Dadurch lassen sich Filter sehr einfach definieren, oder eben Sortierungen.<br>
                      Im Grunde würde es auf eine Datenbank hinauslaufen.<br>
                      Kleiner Tipp: schau dir mal TClientDataSet genauer an, und dessen Fähigkeit mit eigenen Tabellen umzugehen die per FileName geladen/gespeichert werden können. Diese Form der Datasets benötigt keinerlei BDE o.ä.<br>Die Defintion der Felder usw. kannste in der IDE vornehmen.<br>

                      Gruß Hage

                      Comment


                      • #12
                        <pre>
                        Hallo Hager,
                        ich glaube nun eine bessere Lösung gefunden zu haben.
                        Der Trick ist, zwei Streams werden auf die selbe Datei losgelassen.

                        wgesLogDatei := TFileStream.Create(gesLogDatei, fmOpenWrite or fmShareDenyWrite);
                        rgesLogDatei := TFileStream.Create(gesLogDatei, fmOpenRead or fmShareDenyRead);

                        zunächst wird im zu lesenden Stream die Grösse geprüft, dann
                        im Schreibstream die neue Grösse eingestellt.
                        Dann wird aus dem Lesestream der gewünschte Inhalt in den Schreibstream kopiert.
                        wgesLogDatei.CopyFrom(rgesLogDatei, rgesLogDatei.Size - i);
                        anschliessend wird die neue Grösse des Schreibstream gesetzt.
                        Der gewünschte Inhalt wird also lediglich im Stream verschoben!

                        Helmut</pre&gt

                        Comment

                        Working...
                        X