Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Job-Börse: Angebote und Gesuche (https://www.delphipraxis.net/66-job-boerse-angebote-und-gesuche/)
-   -   Tail Komponente (https://www.delphipraxis.net/165567-tail-komponente.html)

nytaiceman 6. Jan 2012 08:18

Tail Komponente
 
Hallo zusammen,

Ich habe folgenden kleinen Auftrag zu vergeben:

Beschreibung:
Erstellung einer Delphi Komponente, welche eine einfache "tail" Funktionalität bereitstellt.
--> Permanente Darstellung einer Textdatei (z.B. Logfile eines laufenden Prozesses)

Features:
- Muss Unicode Textfile lesen können
- Muss damit umgehen können, das das Logfile zwischendurch truncated (älteste Einträge werden abgeschnitten) wird
- Muss das Resultat in einem Memo anzeigen
- Muss pausiert werden können
- Muss fortgesetzt werden können (Follow tail)
- Muss den tail Vorgang auch fortsetzen können, wenn die Datei kurzfristig nicht verfügbar ist (z.B. Netzwerkunterbruch oder wenn sie gelöscht wurde)
- Das übergebene Memo scrollt automatisch nach unten (letzte Zeile)
- Die Komponente sollte mit nativem Delphicode erstellt werden (Keine weiteren Fremdkomponenten voraussetzen!)
--> Als Vorbild dient baretail.exe (Nur die Funktion, nicht das Tool!) --> http://www.baremetalsoft.com/baretail/
--> Das Highlighting in der Memo habe ich bereits geschrieben, das betrifft diesen Auftrag nicht.

Spätere Handhabung in Delphi:
- Komponente auf Form ziehen
- Procedure pTailLogFile(sLogFile:String;oMemo:TMemo;bAutostar t:Boolean);
- Procedure pTailStart
- Procedure pTailPause
- Procedure pTailResume --> Entspricht eigentlich "pTailStart"

Auftragsinhalt:
Erstellung der Komponente
Der Sourcecode und die Rechte daran, gehen nach Auftragsende vollständig an mich.
Die Komponente werde ich vollständig (Inkl. Sourcecode) danach der Community von Delphi-Praxis.net kostenlos zur Verfügung stellen.
--> Welche Lizenz? Sie sollte für jeden (kommerziell wie auch privat) verwendet werden dürfen, Verbesserungen sollten aber rückgemeldet werden müssen.

Zeitrahmen:
Bis Ende Januar fertig gestellt.

Bitte meldet euch mit einer kurzen Kostenaufstellung bei mir, danke.
Gruss

mjustin 7. Jan 2012 10:29

AW: Tail Komponente
 
Einige Sourcecode-Links zu Scala- und Java-Implementierungen des Linux Tail Kommandos sind hier zu finden und können eventuell mit wenig Aufwand nach Delphi / Pascal portiert werden:

http://stackoverflow.com/questions/5...x-linux-tail-f

p.s. eventuell könnte noch spezifiziert werden welche Delphi Versionen unterstützt werden sollen.

nytaiceman 7. Jan 2012 10:53

AW: Tail Komponente
 
Hallo mJustin,

Wärst Du denn interessiert?


@all
Primär muss Delphi 2010 unterstützt werden. Alle weitere Versionen sind von mir nicht verlangt.

Danke für euer Interesse!

nytaiceman 11. Jan 2012 13:24

AW: Tail Komponente
 
Hallo zusammen,

hat niemand Lust, eine Mark oder zwei zu verdienen?

Keine Ahnung wie gross der Aufwand dazu ist, aber die ersten 100€ stehen auf jeden Fall bereit zur Auszahlung. Wenn es mehr wird, kann man ja darüber reden...
Danke bereits.

himitsu 11. Jan 2012 15:11

AW: Tail Komponente
 
Wenn es noch 1-2 Wochen Zeit hat, dann wäre da bestimmt was machbar.

Klaus01 12. Jan 2012 00:16

AW: Tail Komponente
 
Gute Nacht,

mit Komponentenentwicklung habe ich noch nichts gemacht - daher nur eine Klasse:

Nachteil an dieser Klasse, der FileStream bleibt die ganze Zeit erhalten,
daher wird es nicht möglich sein, die LogDatei zu löschen oder kürzen.

Habe auf die Schnelle keine Möglichkeit gefunden- die Filegröße auszulesen ohne die Datei zu öffnen.

edit: output ist auch noch nicht synchronisiert.

Grüße
Klaus

Delphi-Quellcode:
unit tail;

interface
uses
  classes;

type
  TTail = class(TThread)
    private
      FOutput: TStrings;
      FLastFilePos: LongWord;
      FLastFileSize: LongWord;
      FFileName: String;
      FThreadWait : Boolean;
      FThreadWaitingState: Boolean;
    protected
      procedure Execute; override;
    public
      procedure pTailLogFile(sLogFile: String;output:TStrings;bAutostart: Boolean = false);
      procedure pTailStart;
      procedure pTailStop;
      procedure pTailPause;
      procedure pTailResume;
      constructor create;
      destructor Destroy; override;

  end;

implementation
uses
  sysUtils;

constructor TTail.create;
begin
  inherited create(true);
end;

destructor TTail.Destroy;
begin
  FThreadWait := true;

  inherited destroy;
end;

procedure TTail.pTailLogFile(sLogFile: string;output: TStrings; bAutostart: Boolean = False);
begin
  FFileName := sLogFile;
  FOutput := output;
  if fileExists(FFileName) then
    begin
      if bAutostart then
        begin
          pTailStart;
        end;
    end
  else
    raise Exception.Create(format('%s not found',[FFileName]));
end;

procedure TTail.pTailStart;
begin
  if self.Suspended then
    begin
      FLastFileSize := 0;
      FLastFilePos := 0;
      FThreadWait := false;
      self.Start;
    end;
end;

procedure TTail.pTailStop;
begin
  self.Terminate;
end;

procedure TTail.pTailPause;
begin
   FThreadWait := true;
end;

procedure TTail.pTailResume;
begin
  FThreadWait := false;
end;

procedure TTail.Execute;
var
  fileStream : TFileStream;
  currentFileSize : LongWord;
  dataBuffer : TMemoryStream;
  s: String;
begin
  while not terminated do
    begin
      if FThreadWait then
        begin
          sleep(50);
          FThreadWaitingState := true;
        end
      else
        begin
          if fileExists(FFileName) then
            begin


              try
                fileStream := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyNone);
              except
                on E:Exception do
                  FOutput.Add(E.Message);
              end;

              try
                FThreadWaitingState := false;
                currentFileSize := fileStream.size;
                if currentFileSize > FLastFileSize then
                  begin

                    FLastFileSize := currentFileSize;
                    fileStream.Seek(FLastFilePos,soFromBeginning);

                    dataBuffer := TMemoryStream.Create;
                    try
                      dataBuffer.CopyFrom(fileStream,currentFileSize - FLastFilePos);
                      FLastFilePos := currentFileSize;
                      dataBuffer.seek(0,soFromBeginning);
                      setString(s,pChar(dataBuffer.memory),dataBuffer.Size div sizeOf(Char));
                      if s <> '' then
                        FOutput.Add(s);
                    finally
                      dataBuffer.Free;
                    end;

                  end
                else
                  if currentFileSize < FLastFileSize then
                    begin
                      FLastFileSize := 0;
                      FLastFilePos := 0;
                    end;
              finally
                fileStream.Free;
              end;
            end
          else
            sleep(100);

        end;
    end;
end;

end.
edit:
*logfile ist von tail nun nicht mehr permanent geöffnet.
*tail läuft weiter wenn die Datei gelöscht wird und anschließen mit gleichem Namen neu erstellt wird.
*tail setzt die Ausgabe der Datei fort, wenn die Datei temporär nicht erreichbar war
- wenn die Datei gekürzt wird - kommt tail mit den Dateipositionen durcheinander, darum wird die ganze Datei nochmals ausgelesen.

nytaiceman 12. Jan 2012 21:18

AW: Tail Komponente
 
Hallo und Danke für Deinen Vorschlag.

Das auszulesende Datei darf natürlich nicht permanent geöffnet sein, resp. die ursprüngliche Applikation muss diese nach Bedarf verändern können (Reinschreiben, Löschen, Kopieren etc.)

Aber ich denke Dein Input bringt uns trotzdem weiter.

Sobald ich weitere Infos dazu habe, werde ich diese ebenfalls wieder hier platzieren.

Gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:41 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz