![]() |
Delphi-Version: XE2
Bei wachsendendem Logfile auf bestimme Zeile reagieren
Hallo DP !
Ein Programm loggt Ereignisse mit und schreibt es in ein logfile. Ich moechte nun dieses Logfile ueberwachen und bei einer bestimmte Zeile einen einfachen beep ausgeben. Auszug aus dem Logfile: 1) Tomaten sind meistens rot 2) Telefonieren ist teuer 3) Tanken auch ! 4) Delphi ist: [einfach toll] 5) Delphi ist: [total genial] 6) Wer mag Bananen? Ich interessiere mich fuer folgende Zeilen: "Delphi ist: [Text]" Ein Timer soll die Ueberwachung des Logfiles uebernehmen und einen beep ausgeben sobald die Zeile: "Delphi ist: [Text]" ins logfile geschrieben wird.
Delphi-Quellcode:
Somit
procedure TForm1.Timer1Timer(Sender: TObject);
var sl:TStringList; s :string; begin sl := TStringList.Create; sl.LoadFromFile(e_logpath.Text); //nach der Zeile suchen //wenn gefunden: beep sl.Free; end;
Delphi-Quellcode:
ist das ganze Logfile in der Stringlist. Ist aber nicht notwendig weil mich immer nur die neuen Zeilen interessieren, die nach dem aktivieren des Timers hinzukommen.
sl.LoadFromFile(e_logpath.Text);
Mit
Delphi-Quellcode:
kann ich das Vorkommen der Zeile sicherstellen.
TStringList.IndexOf('Delphi ist: ');
Eigentlich hab ich fast alle Bausteine die notwendig sind, aber ich schaff es damit nicht mein Problem damit zu loesen. Koennt ihr mir helfen? |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
IndexOf vergleicht immer den gesamten String. Damit findest du mit
Delphi-Quellcode:
die im Beispiel aufgeführten Zeilen nicht.
sl.IndexOf('Delphi ist: ');
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Delphi-Quellcode:
Damit finde ich das 1. Vorkommen meines Suchstrings. Aber um das neuste Vorkommen des Suchstrings zur Laufzeit zu ermitteln ist fuer mich noch nicht loesbar.
procedure TForm1.Button1Click(Sender: TObject);
const SearchString = 'Delphi ist: '; var MyTextFileContent : TStringList; i : Integer; tempStr : String; begin MyTextFileContent := TStringList.Create; try MyTextFileContent.LoadFromFile(e_logpath.Text); except Showmessage('Motz, kreisch'); MyTextFileContent.Free; exit; end; for i := 0 to MyTextFileContent.Count -1 do if pos(SearchString,MyTextFileContent[i]) <> 0 then begin tempStr := MyTextFileContent[i]; delete(tempStr,1,pos(SearchString,MyTextFileContent[i])+ length(SearchString)-1); showmessage('gefunden in Zeile ' + Inttostr(i +1)); MyTextFileContent.Free; exit; end; MyTextFileContent.Free; end; |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Zweiteilen? Ein Logfile und ein Logfile Archiv? Logfile protokolliert letzte Aktionen, Archiv enthällt alles.
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Theoretisch muesste mein Programm beim Start direkt zum EOF des Logfiles springen und ab da mit der Ueberwachung anfangen. Aber wie stellt man sowas an ?
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Wie wäre es mit Streams? Darin kann man doch prima navigieren.
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Zitat:
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Zitat:
Delphi-Quellcode:
so z.B. oder mit verschiedenen Kombinationen der notwendigen Streams.
lf:=tfiestream.create(mylogfile,...);
lf.seek(lf.size,sofrombeginning); ... lf.write(....); nicht empfehlenswert ist die Verwendung von Textfile und Append. Gruß K-H |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Zitat:
Delphi-Quellcode:
for i := MyTextFileContent.Count - 1 downto 0
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Schau dir doch mal Cromis.DirectoryWatch an, damit läßt sich sowas ohne Probleme lösen.
Du bekommst bei jeder Dateiänderung im vorgegebenen Pfad ein Event. [Delphi] procedure TMF.OnNotify(const Sender: TObject; const Action: TWatchAction; const FileName: string); .... If (FileName = 'LogFile.txt') and (Action = waModified) then Begin NewFileSize := getFileSize(CombatLog); If NewFileSize <> OldFileSize then Begin ... [/Delphi} |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Merk Dir die Größe der Datei seit dem letzten Prüfvorgang (=StartPos).
Zum periodischen Prüfen: 1. Gehe in der Datei an Die Stelle 'StartPos+1' 2. Suche ab da bis zum Ende der Datei. 3. Anschließend setzt Du StartPos auf <Größe der Datei> StartPos ist am Anfang 0. |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
@Furtbichler > #7
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Wobei man gelegentlich das Archivieren von Logfiles nicht vergessen sollte. Eine zeitlang klappt das Anhängen. Ich hab mal eine Log von knapp 2 GB gesehen. Kunde meinte, dass das Programm früher etwas schneller war. Also ab und zu vorne etwas abschneiden, archivieren und alles anpassen.
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Zitat:
Na ja, eigentlich ist es doch das Gleiche aber eben nicht ganz.:roll: |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Ich habe mir erstmal folgende Loesung gebastelt:
Delphi-Quellcode:
Mit diesem Code werden beim Programmstart nur die Zeilen in das Memo uebertragen, welche dem Suchstring entsprechen.
procedure TForm1.Button1Click(Sender: TObject);
var Inhalt: string; p:integer; begin Assignfile(Src,'C:\Users\tomatenmann\Documents\logoutput\Log.txt'); Reset(Src); memo1.Clear; while not EOF(Src) do begin ReadLn(Src, Inhalt); p := Pos('Suchtext', Inhalt); if p > 0 then begin //Reaktion auf gefundenen Suchstring memo1.Lines.Add(Inhalt); end; end; CloseFile(Src); end; Jeder weitere Eintrag in das Memo loest die gewuenschte Reaktion aus. Funktioniert. Das dumme ist: Wenn das Logfile mehrere Dutzend Megabytes gross wird kann es auf Dauer etwas unperformant werden, da ich bei jeder pruefung das gesamte logile zeilenweise neu einlese. Bloed ist auch dass mein Programm das File fuer andere Anwendungen "blockiert", deshalb muss ich bei jedem Vorgang das file wieder "closen" |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Der bereits mehrfach erwähnte FileStream ([fmopenRead,fmShareDenyNone]), lesen ab letztem bekannten Ende, sollte diese Probleme lösen.
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Fassen wir doch mal zusammen,
Du hast eine Program (prg1) das in eine Datei schreibt (lg1). in dieser Datei werden verschiedene vordefinierte strings geschrieben, es wird kein Datum und keine Uhrzeit geschrieben. Zu einem beliebigen Zeitpunkt wird ein weiteres Program (prg2) gestartet, das alle Einträge, die nach prg2.Start in das lg1 gemacht werden, auf bestimmte Inhalte überprüft und ggf. eine optische und/oder akustische Meldung absetzt. ist das soweit richtig? Gruß K-H |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Zitat:
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Ich würd' mir was von TStringList ableiten:
Delphi-Quellcode:
TLogFile = class(TStringList)
private FLoadCount: integer; FFileName: string; public procedure UpDate; procedure Refresh; function IndexOfSubString(const SubStr: string; var Index: integer): integer; function DeleteSubString(const SubStr: string): boolean; property LoadCount: integer read FLoadCount; property FileName: string read FFileName; constructor Create(const AFileName: string); end;
Delphi-Quellcode:
constructor TLogFile.Create(const AFileName: string);
begin inherited Create; FFileName:= AFileName; FLoadCount:= 0; Refresh; end; procedure TLogFile.Refresh; begin if FileExists(FFileName) then begin LoadFromFile(FFileName); FLoadCount := Count; end; end; procedure TLogFile.Update; begin if FileExists(FFileName) then LoadFromFile(FFileName); end; function TLogFile.IndexOfSubString(const SubStr: string; var Index: integer): integer; var I: integer; begin UpDate; Result := -1; Index := 0; for I:= FLoadCount to Count -1 do begin Index:= Pos(SubStr, Strings[I]); if Index > 0 then begin Result := I; Break; end; end; end; function TLogFile.DeleteSubString(const SubStr: string): boolean; var I, J: integer; S: string; begin Result:= false; I:= IndexOfSubString(SubStr, J); if I > -1 then begin Result:= true; S:= Strings[I]; System.Delete(S, J, Length(SubStr)); // ??? Strings[I]:= S; end; end; |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Hat eigentlich jemand
![]() |
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Ist die Datei so groß? Falls ja, dann ist das hier an mir vorbeigegangen. Sorry. Meine Easylösung würde ich nur für Dateien so bis 1 MB empfehlen, sonst ist das viel zu langsam. :oops:
|
AW: Bei wachsendendem Logfile auf bestimme Zeile reagieren
Wenn es nicht unbedingt per Delphi geloest werden muss, sondern bloss irgendwie, dann wuerde ich mal was mit sed probieren.
Sowas in die Richtung:
Code:
sed -rne 's/^.*fu.*$/'$(echo -e "\007")'/gp' test.log
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:26 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 by Thomas Breitkreuz