Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как правильно вести лог событий работы программы?


Ezorcist ©   (2007-04-15 01:07:00) 

Можно в начале работы программы обращаться к текстовому файлу
assignfile(f,'log.txt);
а потом при каждом событии, которое необходимо записать в лог делать соотв. запись в файл:
writeln(f,str);
А в коне программы закрывать файл closefile(f);

Но если программы будет завершена неверно (т.е. как следствие не будет выполнено closefile(f); ), то часть данных, как я понял может потеряться.

Как предотвратить потерю этих данных или же можно вести лог другим более правильным способом?


Ezorcist   (2007-04-15 11:15:00) [1]


> лохиш ©   (15.04.07 04:20) [3]
>
>
> > Ezorcist   (15.04.07 01:07)  
>
> Нннаа, ик... дарю...ик


Мамма-мия )) СПАСИБО!)


Плохиш   (2007-04-15 04:20:00) [2]


> Ezorcist   (15.04.07 01:07)  

Нннаа, ик... дарю...ик

type
 TLogFile = class
   FFileName:  String;
   FLogBuf:    TStrings;

   public
     constructor Create(AFileName: String = '');
     destructor  Destroy; override;
     procedure   Add(AStrLog: String); virtual;
     procedure   AddStr(AStrLog: String); virtual;
     procedure   AddValue(AName: String; AValue: Variant; AOhneTime: Boolean = false); virtual;
     procedure   AddDynArr(AName: String; AValue: TByteDynArray; AOhneTime: Boolean = false); overload;
     procedure   AddDynArr(AName: String; AValue: TShortIntDynArray; AOhneTime: Boolean = false); overload;
     procedure   Save; virtual;
     property    LogBuf: TStrings read FLogBuf;
 end;
....
{ TLogFile }

procedure TLogFile.Add(AStrLog: String);
begin
 FLogBuf.Add(FormatDateTime('"["dd/mm/yyyy" - "hh:nn:ss"] "', now) + AStrLog);
end;

procedure TLogFile.AddStr(AStrLog: String);
begin
 FLogBuf.Add(AStrLog);
end;

procedure TLogFile.AddValue(AName: String; AValue: Variant; AOhneTime: Boolean);
var
   sValue: String;
begin
 sValue := VarToStr(AValue);
 sValue := AName + ' = ' + sValue;
 if AOhneTime then AddStr(sValue) else Add(sValue);
end;

procedure TLogFile.AddDynArr(AName: String; AValue: TByteDynArray;
 AOhneTime: Boolean);
var
   sValue: String;
   lIndex: Integer;
begin
 sValue := '';
 for lIndex := Low(AValue) to High(AValue) do
   sValue := sValue + chr(AValue[lIndex]);
 sValue := AName + ' = ' + sValue;
 if AOhneTime then AddStr(sValue) else Add(sValue);
end;

procedure TLogFile.AddDynArr(AName: String; AValue: TShortIntDynArray;
 AOhneTime: Boolean);
var
   sValue: String;
   lIndex: Integer;
begin
 sValue := '';
 for lIndex := Low(AValue) to High(AValue) do
   sValue := sValue + chr(byte(AValue[lIndex]));
 sValue := AName + ' = ' + sValue;
 if AOhneTime then AddStr(sValue) else Add(sValue);
end;

constructor TLogFile.Create(AFileName: String);
begin
 inherited Create;
 if AFileName = '' then  FFileName := cLogFile
 else if ExtractFilePath(AFileName) <> '' then FFileName := AFileName
 else
{$IFDEF MSWINDOWS}
   FFileName := IncludeTrailingPathDelimiter(GetEnvironmentVariable('temp')) + AFileName;
{$ENDIF}
{$IFDEF LINUX}
   FFileName := '/tmp/' + AFileName;
{$ENDIF}
 FLogBuf := TStringList.Create;
 TStringList(FLogBuf).Sorted := false;
end;

destructor TLogFile.Destroy;
begin
 if FLogBuf.Count > 0 then Save;
 FLogBuf.Free;
 inherited;
end;

procedure TLogFile.Save;
var
   FOut:     TStream;
   bCreated: Boolean;
begin
 bCreated := false;
 FOut := nil;
 if not FileExists(FFileName) then
   FOut := TFileStream.Create(FFileName, fmCreate)
 else
   repeat
     try
       FOut := TFileStream.Create(FFileName, fmOpenReadWrite + fmShareExclusive);
       bCreated := true;
     except
       on EFOpenError do Sleep(500)
       else raise;
     end;
   until bCreated;
 try
   FOut.Seek(0, soFromEnd);
   FLogBuf.SaveToStream(FOut);
   FLogBuf.Clear;
 finally
   Fout.Free;
 end;
end;


Джо   (2007-04-15 03:39:00) [3]

> [0] Ezorcist   (15.04.07 01:07)
> Как предотвратить потерю этих данных или же можно вести
> лог другим более правильным способом?

Можно, например, закрывать файл после каждой записи и открывать снова, когда нужно. Можно, например, делать принудительный Flush. Да мало ли чего еще можно, например.


Германн   (2007-04-15 01:15:00) [4]


> Ezorcist   (15.04.07 01:07)
>
> Можно в начале работы программы обращаться к текстовому
> файлу
> assignfile(f,'log.txt);
> а потом при каждом событии, которое необходимо записать
> в лог делать соотв. запись в файл:
> writeln(f,str);
> А в коне программы закрывать файл closefile(f);
>
> Но если программы будет завершена неверно (т.е. как следствие
> не будет выполнено closefile(f); ), то часть данных, как
> я понял может потеряться.
>
> Как предотвратить потерю этих данных или же можно вести
> лог другим более правильным способом?
>

AssignFile тут вообще ни при чём. Имеют значение только Reset, Rewrite, Append & CloseFile.


Наверх

Титульная страница Поиск, карта сайта Написать письмо