HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

Adattábla eseményeit naplózó komponens készítése


Példaprogram letöltése

12081 bájt

Ebben a cikkben egy olyan komponenst mutatunk be, amely képes egy TDataSet osztályból származó komponens (TTable, TQuery, stb.) szinte összes eseményét naplózni, vagyis egy tetszőlegesen megadható log fájlba menteni. Ez nagyszerűen használható az adatbázis műveletek nyomon követésére, vagy hiba esetén a hiba okának felderítésére. Nekünk nincs más dolgunk, mint feltenni a komponenst a Form-ra, beállítani az adatbázist, bejelölni a naplózni kívánt eseményeket, és megadni a log fájl nevét. Ezután a többit csak rá kell bíznunk a komponensre.
A mellékelt példaprogram megnyitása előtt a DBLog.pas-ban lévő komponenst telepítenie kell a Delphi alá.

A LogFileName property-ben kell megadni a log fájl nevét. A LogEvents property-ben állíthatjuk be a naplózni kívánt eseményeket. Ezek a következők lehetnek:
  • BeforeCancel
  • BeforeClose
  • BeforeDelete
  • BeforeEdit
  • BeforeInsert
  • BeforeOpen
  • AfterPost
  • BeforePost
  • OnCalcFields
  • OnDeleteError
  • OnEditError
  • OnNewRecord
  • OnPostError
A komponens működési elve az, hogy a Dataset property-ben megadott adatbázis eseményeihez hozzárendel egy-egy belső eljárást. Ezekben az eljárásokban a szükséges információkat kiírjuk a LogFileName property-ben megadott fájlba.

A log fájl megnyitását vagy létrehozását a StartLog eljárás végzi. Ebben először megnézzük, hogy van-e már log fájl megnyitva, és ha igen, akkor lezárjuk azt a CloseLog metódus meghívásával. Ha az Enabled property True, akkor megnézzük, hogy a megadott fájl már létezik-e. Ha létezik, akkor megnyitjuk, ellenkező esetben létrehozzuk. A log fájlt egyébként a TFileStream osztályon keresztül kezeljük. Miután megnyitottuk a fájlt, a végére pozícionálunk, majd kiírjuk a fejlécet. A log fájlba a WriteLog eljárással tudunk szöveget kiírni.
procedure TDBLog.StartLog;
var fmode:word;
begin
  if NOT (csDesigning in ComponentState) then
  begin
    if Assigned(FLogFile) then CloseLog;

    if FEnabled then begin  
      try
        fmode:=fmCreate;
        if FileExists(FLogFileName) then fmode:=fmOpenReadWrite;
        FLogFile:=TFileStream.Create(FLogFileName, fmode);
        FLogFile.Seek(0, soFromEnd);
        WriteLog('******************************************');
        WriteLog('* Log started: '+DateTimeToStr(Now));
        WriteLog('*'+CRLF);
      except
        Application.MessageBox(PChar(
          'A "'+FLogFileName+'" fájlt nem sikerült megnyitni!'),
          'Hiba!',
          MB_OK+MB_ICONSTOP);
        FEnabled:=False;
      end;
    end;
  end;
end;
A CloseLog belső eljárással zárhatjuk le a log fájlt.
procedure TDBLog.CloseLog;
begin
  if Assigned(FLogFile) then begin
    WriteLog('');
    WriteLog('*');
    WriteLog('* Log finished: '+DateTimeToStr(Now));
    WriteLog('******************************************');
    WriteLog(CRLF);
    FLogFile.Free;
    FLogFIle:=NIL;
  end;
end;
A WriteLog eljárással írhatunk a log fájlba. Ha a fájl meg van nyitva, és az Enabled property értéke true, akkor a paraméterként megkapott sztringet kiírja a log fájlba.
procedure TDBLog.WriteLog;
var buff:array[0..511] of char;
begin
  if Assigned(FLogFile) and (FEnabled) then begin
    msg:=msg+CRLF;
    StrPCopy(buff, msg);
    FLogFile.Write(buff, Length(msg));
  end;
end;
Néhány eseménynél azt is jó lenne látni, hogy az aktuális rekord milyen adatokat tartalmaz. Éppen ezért létrehoztunk egy belső eljárást, ami a rekord tartalmát kiírja a log fájlba.
procedure TDBLog.WriteCurrentRecord;
var i, ml:integer;
    v, fn, ms:string;
begin
Készítünk egy szóközökből álló sztringet, ami 1 karakterrel hosszabb lesz, mint a leghosszabb mezőnév. Erre azért van szükség, hogy a mezők értékeit egymás alá tudjuk igazítani.
  ml:=0;
  for i:=0 to Dataset.FieldCount-1 do begin
    fn:=Dataset.Fields[i].FieldName;
    if Length(fn)>ml then ml:=Length(fn);
  end;
  ms:=StringOfChar(' ', ml+1);
Végighaladunk a Dataset mezőin, és kiírjuk a nevüket, valamint az aktuális értéküket a log fájlba.
  for i:=0 to Dataset.FieldCount-1 do begin
    fn:=Dataset.Fields[i].FieldName;
    if Dataset.Fields[i].IsNull then v:='<NULL>' else
    if Dataset.Fields[i].IsBlob then v:='<BLOB>' else v:='"'+Dataset.Fields[i].AsString+'"';
    WriteLog('    '+Copy(fn+ms, 1, Length(ms))+v);
  end;
end;
Most nézzük meg egy-egy eseményt kiemelve, hogy hogyan történik a tárolásuk a log fájlba. Először az AfterPost eseményt vizsgáljuk meg, mivel itt az aktuális rekord tartalmát is kiírjuk a fájlba.

Első lépésben ellenőrizzük, hogy az esemény naplózása engedélyezve van-e. Ezt a LogEvents property-ből tudhatjuk meg. Az Enabled property értékét itt nem kell figyelnünk, mert azt a WriteLog eljárásban úgyis ellenőrizzük. Ha az eseményt naplózni kell, akkor kiírjuk az esemény azonosítóját, és az aktuális dátumot és időpontot. Az események azonosítója mindig "#" karakterrel kezdődik. Ha kiírtuk az azonosítót, akkor utána meghívjuk a WriteCurrentRecord eljárást, ami az aktuális rekordot másolja a log fájlba. Ezután még kiírunk egy "# END OF …" azonosítót, hogy tudjuk, az eseményhez tartozó adatok eddig tartottak. Ezt csak abban az esetben tesszük meg, ha az esemény azonosítóján kívül további adatokat is tárolunk. Ha a kiírással végeztünk, akkor meghívjuk az eredeti eseménykezelő eljárást, ha volt ilyen.
procedure TDBLog.DoAfterPost;
begin
  if (leAfterPost in FLogEvents) then begin
    WriteLog('# AFTER POST '+DateTimeToStr(Now));
    WriteCurrentRecord;
    WriteLog('# END OF AFTER POST '+DateTimeToStr(Now));
  end;
  if Assigned(FOldAfterPost) then FOldAfterPost(DataSet);
end;
Egy másik esemény típus, amikor hibaüzenetet is kapunk. Ilyen például az OnPostError esemény is. Ez annyiban különbözik az előzőtől, hogy itt az aktuális rekordon kívül az E paraméter Message mezőjét is eltároljuk, mivel ez tartalmazza a hibaüzenetet.
procedure TDBLog.DoOnPostError;
begin
  if (lePostError in FLogEvents) then begin
    WriteLog('# POST ERROR '+DateTimeToStr(Now));
    WriteLog(E.Message);
    WriteCurrentRecord;
    WriteLog('# END OF POST ERROR '+DateTimeToStr(Now));
  end;
  if Assigned(FOldOnPostError) then FOldOnPostError(DataSet, E, Action);
end;

Cikksorozat

#IDKategóriaCikk címeSorozat
3333WindowsNet Shell parancsok1. rész
3367WindowsNet Shell parancsok2. rész
3396WindowsNet Shell parancsok3. rész


Könyv
Ez a cikk megtalálható ebben a könyvben: Delphi Software Offline 2001 évkönyv 295. oldal

Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |