Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.22;
Скачать: CL | DM;

Вниз

логер работы программы   Найти похожие ветки 

 
jao   (2004-08-03 10:55) [0]

Логи работы программы записываются в Memo1:TMemo, приблизительно раз в сто строк (в зависимости от количества строк на экане) логи
скидываются в файл на диск (если файла лога нет - он создается, если есть - дописывается в конец). Программа работает круглосуточно и несколько раз в сутки вылетает сообщение о том, что файл лога не доступен или заблокирован другой программой, хотя никто кроме этой проги его не юзает.

Как можно обойти данную траблу или как можно сделать логер по-другому? кто нает :(

-----------------------------------------------------------
procedure TFormMD.Memo1Change(Sender: TObject);
var
 CountSaveLines:integer;
 fs:TFileStream;
 LogName:string;
 i:integer;
 m:word;
 TempStrings:TStringList;
 WasOpenError:boolean;

begin
   WasOpenError:=false;

   if memo1.Lines.Count>100 then
   begin
     LogName:=extractfilepath(application.ExeName)+"Logs\"+formatdatetime("dd_mm_yyyy", now)+"_"+inttostr(LogIndex)+".log";

     if fileExists(LogName)
     then
     begin
       m:=fmOpenReadWrite
     end
     else
     begin
       m:=fmCreate;
     end;

     fs:=TFileStream.Create(LogName,m);

     fs.Seek(0, soFromEnd);

     TempStrings:=TStringList.Create;
     TempStrings.BeginUpdate;

     memo1.Lines.BeginUpdate;
     CountSaveLines:=memo1.Height div (memo1.Font.Height - 3);

     for i:=0 to 100+(CountSaveLines) do
     begin
       TempStrings.Add(memo1.Lines.Strings[0]);
       memo1.Lines.Delete(0);
     end;

     TempStrings.SaveToStream(fs);

     memo1.Lines.EndUpdate;
     TempStrings.EndUpdate;
     TempStrings.Free;

     fs.Free;
   end;
end;
------------------------------------------------


 
TUser ©   (2004-08-03 11:04) [1]

TempStrings.BeginUpdate;

    memo1.Lines.BeginUpdate;
    CountSaveLines:=memo1.Height div (memo1.Font.Height - 3);

Вот этот участок кода точно нуждается в переписывании. И Memo1.Lines.Delete[0] - не самая быстрая операция, лучше потом сделать ему Clear. Переписать здесь надо много.
А вообще может статься, например, что где-то происходит ошибка, FileStream не уничтожается, поэтому файл оказывается занятым. Это первое, что в голову пришло. Вообще, всегда лучше писать try ... finally, если надо, чтобы объект гарантированно уничтожался.


 
Кириешки ©   (2004-08-03 11:25) [2]

А не проще писать сразу в файл? Для этого есть функция Append, она записывает "что-то" в конец файла. Я так делал, когда уезжал в Крым, а за моим компом оставались люди. Она тоже "круглосуточно" работала. А потом приехал и почитав файл узнал что они делали на компе в мое отсутствие. Правда файл - большой-большой был 20 мегов. Его доже Ворд грузить отказался (сказав что стек переполнен). Пришлось частями грузить.


 
TUser ©   (2004-08-03 11:30) [3]

Не всегда это проще. У меня сейчас вот работает прога, которая логи ведет, записывается в файл и мему. Очень удобно сразу видеть чего она пишет. Делал примерно так
procedure AddToLog(S:string);
begin
  Memo1.Lines.Add;
  if assigned(FLog) then
     {пишем S В FLog}  
end;

procedure NewLog;
begin
  if assigned(FLog);
  then Freeandnil(FLog);
  FLog:=TFileSteream.Create;
end;
Правда у меня лог организован в виде большого кол-ва файлов, после открытия каждый закрывается минут через 30-40.


 
Кириешки ©   (2004-08-03 11:38) [4]

>TUser ©   (03.08.04 11:30) [3]

А для чего большое кол-во файлов надо, в которых лог пишется?
Обычно лог делается суточный или несколькочасовой, а зетем новый файл делается.


 
jao   (2004-08-03 11:39) [5]

>TUser

Если делать Clear, то юзверь не увидит последних записей, а это есь плохо, попробую try ... finally, хотя вроде там нет опасных участков, где может быть эксепшн...вот бы научиться разблокировать заблокированный файл :)))


 
TUser ©   (2004-08-03 11:40) [6]

Программа просматривает фалы на ftp сервере. Файлы организованы в большое кол-во папок. Для каждой папки - свой лог.


 
jao   (2004-08-03 11:45) [7]

>Кириешки
Приведи, плз, пример того каким способом ты пишешь сразу в файл

ЗЫ: А не будет ли это сильно тормозить систему и постоянно грузить диск?


 
Erik1   (2004-08-03 11:47) [8]

Однозначно лучше писать сразу в фаил. TFileSteream можно неиспользовать, тогда и уничтожать ненадо. А паралельно можно выводить в лог.
procedure TRealEvent.Close;
begin
 FileActive := False;
 {$I-}
 Flush(F);
 CloseFile(F);
 {$I+}
end;

procedure TRealEvent.Log;
Var Buf: String;
Const LogFile =  "C:\UDPLog.txt";
begin
 Buf := Format("%d;%d;%d;%d;",[DecNoToInt(Params.Decoder),Params.Cmd,
   fConf.Code, fConf.Content]);

 if not FileActive then begin
   AssignFile(F,LogFile);
   {$I-}
   Reset(F);
   {$I+}
   IOResult;
   if Not FileExists(LogFile) then
     Rewrite(F);

   FileActive := True;
 end;

 Append(F);
 Writeln(F,Buf);
end;


 
TUser ©   (2004-08-03 11:53) [9]

Сразу в файл можно записыватьчерез FileStream методом Write. Строки записываются посимвольно, перед каждой строкой - Integer значение (дляна строки). См. статьи А.Подгорецкого на Королевстве, + любая другая литература по Delphi.


 
panov ©   (2004-08-03 12:12) [10]

http://home.ural.ru/~panov/dll_src/new/readme.txt
Тут есть реализованный журнал в DLL и отдельном потоке.


 
panov ©   (2004-08-03 12:13) [11]

Журнал можно просматривать во время работы программы...


 
Кириешки ©   (2004-08-03 12:35) [12]

Сори, Меня долго небыло - вызывали.

>TUser ©   (03.08.04 11:53) [9]
Стирм зато грузит долго очень большие файлы!

Лично я делал примерно так :


procedure SomethingHappened(MyString:Pchar);
var
f : TextFile;
SappPath : string;
begin
SappPath := Extractfilepath(application.exename);

if FileExists(SappPath+"MyFilename.ext") then
begin
 AssignFile(f,SappPath+"MyFilename.ext");
 Reset(f);
 Append(f);
 Writeln(f,Mystring);
 closefile(f);
end else
begin
 AssignFile(f,SappPath+"MyFilename.ext");
 Rewrite(f);
 Append(f);
 Writeln(f,Mystring);
 closefile(f);
end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
SomethingHappened(pchar(memo1.Lines.Text)); //Вызываем процедуру
Application.ProcessMessages();

if memo1.Lines.Count = 100 then
Memo1.Clear;
end;


 
Кириешки ©   (2004-08-03 12:38) [13]

ЗЫ. ... и данные в файл пишет и мемо показывает (если нужно)


 
TUser ©   (2004-08-03 12:39) [14]

> Стирм зато грузит долго очень большие файлы!
Это не так. Стрим работает в дцать раз быстрее, чем ваш assignfile/rewrite/writeln. Например, попробуйте выполнять такие коды

while not eof(f) do begin
  readln(f,s);
  StrList.Add(s);
  and;

и

StrList.LoadFromFile();

Второе - гораздо быстрее, потому что через стрим.


 
jao   (2004-08-03 12:41) [15]

Спасибо всем!!! попробую теперь всё это разгрести


 
Кириешки ©   (2004-08-03 12:45) [16]

Удачи в разгребании.


 
TUser ©   (2004-08-03 12:47) [17]

Ну вот, самая важная наука для программера - археология :)


 
Кириешки ©   (2004-08-03 12:58) [18]

>TUser ©   (03.08.04 12:47) [17]

;))


 
jao   (2004-08-03 13:29) [19]

Memo1.Lines.Delete[0] и правда жуууутттко тормозной оказался по замерам...


 
raidan ©   (2004-08-03 13:45) [20]

TUser ©   (03.08.04 12:39) [14]
Ну вы и привели пример :-/
В посимвольно считывать еще не пробовали?
Будет еще медленнее...
З.Ы. Достаточно один раз открыть файл и не закрывать его во время работы программы (если не боиться зависания и нужна быстрая скорость). Т.е. просто дописывать writeln"ом, по таймеру flush"ить изредка или даже не flush"ить :)


 
paa   (2004-08-05 06:32) [21]

Вот еще вариант для небольшего лога по суткам!

// записываем в файл
procedure TForm1.log(log_message:string);
var logfile :string;
         F1:textfile;
begin
   logfile:=datetostr(date)+".log";
   CreateFile(pChar(logfile),0,0,0,1,0,0);
   AssignFile(F1,logfile);
   Append(f1);
   writeln(f1,log_message);
   closefile(f1);
end;

// читаем из файла в memo
procedure TForm1.Timer1Timer(Sender: TObject);
begin
memo1.Lines.LoadFromFile(datetostr(date)+".log");
end;


 
Кириешки ©   (2004-08-05 07:17) [22]

>paa   (05.08.04 06:32) [21]

Файлы по названию дыты?
А если ведется лог с 23:00 до допустим 02:00, то
1) Программа вылетает в том месте где написано append, потому что
  эта функция добавляет в конец файла какую-то запись, а у  
  только-что созданного файла нет ни начала ни конца.
  Если исправить эту ошибку, то
2) (как сказано из условия) будут созданы два файла. А это не очень удобно для последующего их изучения.


 
DeMoN_Astra   (2004-08-08 19:09) [23]

Хитро .. мдя..
а как держать файл событий постоянной длины?


 
panov ©   (2004-08-08 19:13) [24]

>DeMoN_Astra   (08.08.04 19:09) [23]
см. panov ©   (03.08.04 12:12) [10]
В реализованном классе обрабатывается условие максимальной длины журнала. При превышении текущий лог архивируется и начинается новый.


 
DeMoN_Astra   (2004-08-08 19:16) [25]

Хочу сам реализовать :)
Более того - мне не нужно архивировать, мне нужно скользящее окно.. то бишь удаляем старые, пишем новые


 
panov ©   (2004-08-08 21:33) [26]

>DeMoN_Astra   (08.08.04 19:16) [25]
Более того - мне не нужно архивировать, мне нужно скользящее окно.. то бишь удаляем старые, пишем новые

Тогда используй TStringList, а о технологиях обрезания файла с начала я пока не слышал...


 
Sha ©   (2004-08-08 22:16) [27]

Технология обрезания простая. Работаем с двумя файлами. В каждый пишем не более N записей. По мере надобности переключаемся на другой для перезаписи. Отображаем в окне последние N записей (из обоих файлов, рассматривая их как один непрерывный). При старте программы определяем текущий по дате изменения.


 
DeMoN_Astra   (2004-08-09 00:08) [28]

Ничего не понял о двух файлах :)
поясню - нужно точь в точь, как в the bat файл событий организован..


 
Sha ©   (2004-08-09 01:22) [29]

Сначала пишешь в один файл. Как он заполнится (наберет N записей) - переключаешься на другой. Когда заполнится второй - снова пишешь в первый, и т.д. Получается, что в двух файлах ты всегда имеешь не менее N записей и не более 2N запмсей. Показываешь пользователю последние N.


 
DeMoN_Astra   (2004-08-10 09:22) [30]

Но ведь это не окно :)
нужно один файл, фиксированного размера


 
Sha ©   (2004-08-10 10:55) [31]

DeMoN_Astra   (10.08.04 09:22) [30]

Это неплохая эмуляция окна :)
Главное достоинство - простота.

Если тебе
> нужно один файл, фиксированного размера
- используй завернутый через нулевую запись типизированный файл. Места на диске этим сильно не сэкономишь, т.к. надо рассчитывать на запись максимальной длины. При изменении требований на длину или количество записей могут возникнуть проблемы.



Страницы: 1 вся ветка

Текущий архив: 2004.08.22;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.027 c
14-1091561847
DeadMeat
2004-08-03 23:37
2004.08.22
1C


3-1090693299
Вовчик
2004-07-24 22:21
2004.08.22
Выборочные поля


14-1091367330
Кириешки
2004-08-01 17:35
2004.08.22
А что такое LOL ?


1-1091729194
Hyperspeed
2004-08-05 22:06
2004.08.22
Как сделать поиск и данных и файле типа параметр:значение...


14-1091638104
sasha_n
2004-08-04 20:48
2004.08.22
Структура файла SecEvent.Evt





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский