Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Log-Datei realisieren (https://www.delphipraxis.net/103023-log-datei-realisieren.html)

MatthiasR 8. Nov 2007 15:03


Log-Datei realisieren
 
Hallo allerseits,

ich möchte gerne eine Log-Datei realisieren, in die mehrere Programme (bzw. mehrere Instanzen desselben Programms) ihre Einträge machen. Wie realisiere ich so etwas am besten, ohne dass die Programme sich beim Hineinschreiben in die Datei in die Quere kommen?

Bisher hatte ich folgende Routine vorgesehen für das Anhängen von Log-Einträgen:
Delphi-Quellcode:
AssignFile(f, 'C:\Test.log');
try
  Append(f);
  Writeln(f, 'Ein Log-Eintrag');
finally
  CloseFile(f);
end;
Hier kann es aber theoretisch passieren, dass zwei Programme gleichzeitig die Datei öffnen wollen und dann kracht es bei dem Programm, das einen Tick später drangekommen ist.

Apollonius 8. Nov 2007 15:10

Re: Log-Datei realisieren
 
Da gibt es viele Möglichkeiten. Eine einfache wäre zum Beispiel, dass mit CreateMutex ein benannter Mutex erzeugt wird. Mit WaitForSingleObject wartet dann ein Programm darauf, dass es Zugriff auf den Mutex kriegt. Dann schreibt es in die Datei (wie du vorgeschlagen hast), und ermöglicht mit ReleaseMutex dem nächsten Programm den Zugriff.
Zum Mitschreiben:
Delphi-Quellcode:
//Irgendwo bei Programmstart
MutexHandle:=CreateMutex(nil, false, 'MeinEindeutigerName');

//Zum loggen:
WaitForSingleObject(MutexHandle, INFINITE); //warten, bis kein Programm mehr schreibt
try
  AssignFile(f, 'C:\Test.log');
  try
    Append(f);
    Writeln(f, 'Ein Log-Eintrag');
  finally
    CloseFile(f);
  end;
finally
  ReleaseMutex(MutexHandle); //jetzt dürfen wieder andere
end;

//am Ende
CloseHandle(MutexHandle);

MatthiasR 8. Nov 2007 15:36

Re: Log-Datei realisieren
 
Mit Mutexen hab ich bisher noch keinerlei Erfahrungen gemacht (wird daher höchste Zeit!), aber hört sich auf jeden Fall gut an! Vielen Dank schonmal.

Was hat denn der Parameter "MeinEindeutigerName" genau für eine Bewandnis?

EDIT: Achja: was ich vergaß zu erwähnen, die mehreren Instanzen einer Anwendung laufen in meinem Fall leider auf verschiedenen Rechnern über Netzlaufwerk und sollen auf diesem Wege auch auf die Log-Datei zugreifen. In dem Fall bringt einen ein Mutex ja nicht weiter, oder? Das würde ja nur für ein und derselben Maschine gelten.

Apollonius 8. Nov 2007 15:40

Re: Log-Datei realisieren
 
Nun, alle Programme brauchen ja ein Handle zum gleichen Mutex, denn sonst funktioniert die Synchronisation nur mit mehreren Threads im gleichen Prozess. Und Windows bietet eben die Möglichkeit, dass ein Programm den Mutex eines anderen Programms öffnet, sofern der Mutex einen Namen hat.
Wenn es andererseit ein anderes Programm gibt, dass unbeabsichtigt den gleichen Namen verwendet, führt das zu Problemen.

MatthiasR 8. Nov 2007 15:44

Re: Log-Datei realisieren
 
Wie in meinen oberen Post hineineditiert, lässt sich mein Problem wohl eher doch nicht über ein Mutex lösen, oder?

Jelly 8. Nov 2007 15:47

Re: Log-Datei realisieren
 
Kannst du nicht ins Eventlog von Windows deine Logs eintragen?

Apollonius 8. Nov 2007 15:51

Re: Log-Datei realisieren
 
Also im Netzwerk scheiden Mutexe schonmal aus. Das einzige, was mir noch einfällt, wäre ein Log-Server, mit dem über Named Pipes kommuniziert wird - die funktionieren nämlich im Netzwerk. Aber ein Server für Logs ist unelegant und unpraktisch.

MatthiasR 8. Nov 2007 15:54

Re: Log-Datei realisieren
 
Zitat:

Zitat von Jelly
Kannst du nicht ins Eventlog von Windows deine Logs eintragen?

Wie geht das und was ist das Windows-Eventlog? Wobei ich nicht glaube, dass mir das etwas bringt, da man die Log-Datei später auch auf einfachem Wege wegkopieren/per Mail verschicken/maschinell auswerten können soll.

shmia 8. Nov 2007 15:55

Re: Log-Datei realisieren
 
Am Einfachsten und Sichersten ist, wenn die Datei selbst das Mutex ist.
Wenn Process A die Datei exklusiv offen hat, müssen alle anderen Prozesse warten, bis die Resource (die Datei) wieder verfügbar wird.
Sobald A die Datei wieder schliest, gewinnt der schnellste Prozess, u.s.w.
Dazu gibt es in der Code-Library schon eine fertige Klasse:
http://www.delphipraxis.net/internal...ct.php?t=62072
Das funktioniert übrigens auch im Netzwerk.

juergen 8. Nov 2007 20:13

Re: Log-Datei realisieren
 
@ shmia,
mich hat deine Klasse sehr interssiert und ich habe es mir angeschaut.
Erst einmal mein Respekt für deine Arbeit hierzu und das zur Verfügung stellen des Sources. :thumb:

Leider bekomme ich das Testprojekt nicht kompiliert.
In dem Source-Abschnitt wo du das GetTickCount-Problem (wegen dem "neureseten") umgehst, erscheint bei mir eine Fehlermeldung:
[DCC Fehler] FileStreamUtils.pas(281): E2003 Undefinierter Bezeichner: 'SFOpenError'

Delphi-Quellcode:
      error := GetLastError;
      curtime := GetTickCount;
      if ((curtime - starttime) >= timeout) or
         ((error<>ERROR_SHARING_VIOLATION) and (error<>ERROR_LOCK_VIOLATION)) then
         raise EFOpenError.CreateFmt(SFOpenError+#13#10+    //<-- Fehlermeldung
            SysErrorMessage(error), [FileName]);
Ich verwende D2007 Prof unter Vista 32 Bit.

Ich kann die Fehlermeldung nun leider nicht auflösen...
Weißt du vllt. was hier schief läuft? Evtl. mit etwas Erläuterung zu genau dieser Zeile 281 (raise...)?
Denn genau diese Stelle kapier ich eben nicht...
(vermutlich kennt Vista das nicht mehr)

Danke!

//Edit: Habe die Lösung selbst gefunden. :-D Liegt an der Delphiversion (vor Delphi 6)
Ab den Delphi 6-Versionen wurden einige Konstanten von Borland in die RtlConsts Unit "verschoben". Man muss also unter der Uses-Klausel noch die "RtlConsts" mit aufnehmen.


@ shmia, evtl. den Hinweis mit in deinen Code aufnehmen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:31 Uhr.
Seite 1 von 5  1 23     Letzte »    

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