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

Вниз

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

 
123-ий ©   (2008-06-25 11:36) [0]

Как лучше организовать сабж? В том смысле, какими методами его лучше читать и писАть в него каку-либо инфу?


 
Palladin ©   (2008-06-25 11:38) [1]

какими тебе удобно


 
Ega23 ©   (2008-06-25 11:39) [2]

Ну вот некая заготовочка, в данный момент в процессе "затачивания"


unit uLogger;

interface
uses SysUtils;

function LogError(const Err : string) : Boolean;
function Log(const LogMess : string) : Boolean;
function LogTo(const Name : string; const LogMess : string) : Boolean;
function LogWithError(const Err : string) : Boolean;
function LogToFile(const FileName, LogMess : string;
                  const WriteTime : Boolean = False) : Boolean;

implementation

//*****************************************************************************

function LogWithError(const Err : string) : Boolean;
begin
 Result := LogError(Err) and Log(Err);
end;

//*****************************************************************************

function LogError(const Err : string) : Boolean;
begin
 Result := LogTo("SLErrLog", Err);
end;

//*****************************************************************************

function Log(const LogMess : string) : Boolean;
begin
 Result := LogTo("SLLog", LogMess);
end;

//*****************************************************************************

function LogTo(const Name : string; const LogMess : string) : Boolean;
var
 DirName, LogFileName : string;
 f : TextFile;
begin
 Result := True;
 DirName := ExtractFilePath(ParamStr(0)) + "Log\";
 LogFileName := DirName + Name + "_" + FormatdateTime("yyyy-mm-dd", Now) + ".log";
 if not DirectoryExists(DirName) then
 begin
   Result := CreateDir(DirName);
   if not Result then Exit;
 end;
 AssignFile(f, LogFileName);
 try
   try
     if not FileExists(LogFileName) then
       Rewrite(f)
     else
       Append(f);
     Writeln(f, FormatDateTime("dd.mm.yyyy hh:nn:ss", Now) + " : " + LogMess);
   except
     Result := False;
   end;
 finally
   CloseFile(f);
 end;
end;

//*****************************************************************************

function LogToFile(const FileName, LogMess : string; const WriteTime : Boolean) : Boolean;
var
 f : TextFile;
begin
 AssignFile(f, FileName);
 try
   try
     if not FileExists(FileName) then
       Rewrite(f)
     else
       Append(f);
     if WriteTime then
       Writeln(f, FormatDateTime("dd.mm.yyyy hh:nn:ss", Now) + " : " + LogMess)
     else
       Writeln(f, LogMess);
     Result := True;
   except
     begin
       Result := False;
       Exit;
     end;
   end;
 finally
   CloseFile(f);
 end;
end;

//*****************************************************************************
end.



 
clickmaker ©   (2008-06-25 11:39) [3]

CreateFile - WriteFile - CloseHandle
для ускорения можно открыть один раз и закрыть один раз, но если нужен постоянный монитор лога, то периодически делать FlushFileBuffers.
При записи из нескольких потоков оберни запись в критическую секцию


 
123-ий ©   (2008-06-25 11:47) [4]


> Ega23 ©   (25.06.08 11:39) [2]

Вот этот вариант - с помощью TextFile. Делал с помощью него, частенько вылезают глюки, типа файл занят другим приложением. Как вариант было - читать файл с помощью потоков TFileStream. Ещё не пробовал. А был вариант с помощью StringList.LoadFromFile. Работал. Так вот интересно, какой вариант наиболее оптимальный?


 
123-ий ©   (2008-06-25 11:49) [5]


> clickmaker ©   (25.06.08 11:39) [3]

постоянный монитор не нужен. ускорение тоже, ибо лог... ну у меня не совсем лог, скорее история работы с клиентом, там вряд ли будет дофига инфы.


 
stas ©   (2008-06-25 11:58) [6]

У меня такой работает на многопоточном сервере, еще не разу не глючил.
Только при запуске проги делаем CreateLogFile, по завершении CloseFile
лог пишем WriteLog

unit LogWriter;

interface
uses sysutils;
Procedure OpenFile (FileName:String);
Procedure CloseFile;
Procedure WriteText (Text:String);
Procedure CreateLogFile;
Procedure WriteLog (Text:String);
//Procedure SetWritedLog (Writed:Boolean);

Var F:TextFile; WritedLog:Boolean=True;

implementation

Procedure OpenFile (FileName:String);
begin
//  if not writedLog then exit;
 Assign (F,FileName);
 if FileExists (FileNAme) then
 Reset (F); {else} Rewrite (f);
end;

Procedure CloseFile;
begin
 Close (F);
end;

Procedure WriteText (Text:String);
begin
 if writedLog then
 Writeln (F,Text);
end;

Procedure CreateLogFile;
Var fp,FName,fn:String; I:Integer;
begin
  fp:=ExtractFilePath(ParamStr(0))+"logs\";
  if not DirectoryExists (fp) then MkDir (fp);
  FName:=fp+"gsLog_"+FormatDateTime ("ddmmyyyy",now);
  i:=0;
  fn:= FName;
  While FileExists (FName) do
  begin
   FName:=FN+IntToStr(i);
   inc(i);
  end;
  OpenFile (FName);
end;

Procedure WriteLog (Text:String);
Var S:String;
begin
S:=FormatDateTime ("ddmmyyyy hh:mm:ss",now)+": "+Text;
try
WriteText(S);
except
end;
end;

end.


 
123-ий ©   (2008-06-25 11:59) [7]

ну вот попробую варианты Ega32 и stas. Может чего и выйдет умного...


 
Ega23 ©   (2008-06-25 12:00) [8]


> работает на многопоточном сервере,


А где критическая секция?


 
Ega23 ©   (2008-06-25 12:01) [9]


> варианты Ega32


Эй! Ты смотри, это всего только заготовка...  :) Её ещё тщательно "напильником" обрабатывать надо...  :)


 
stas ©   (2008-06-25 12:03) [10]

Ega23 ©   (25.06.08 12:00) [8]
try except ?


 
Ega23 ©   (2008-06-25 12:05) [11]


> try except ?


На сколько я понимаю, для реально многопоточного лога этого недостаточно...


 
stas ©   (2008-06-25 12:07) [12]

Ega23 ©   (25.06.08 12:05) [11]
тогда что вы имеете ввиду?


 
Ega23 ©   (2008-06-25 12:12) [13]

EnterCriticalSection
try
 try
   ....
   WriteLog
 except
   ....
 end;
finally
 LeaveCriticalSection
end;


 
stas ©   (2008-06-25 12:19) [14]

Ega23 ©   (25.06.08 12:12) [13]

Не слышал. А это для чего.

Пока у меня не возникало никаких проблем слогом сервер работает в течении года.
Но если это чему-то поможет буду благодарен.


 
Ega23 ©   (2008-06-25 12:24) [15]


> А это для чего.


Ну как же. 2 потока разом пытаются в файл что-то записать...


 
123-ий ©   (2008-06-25 12:35) [16]


> Ega23 ©   (25.06.08 12:01) [9]

Ну вот. У тебя получилась хорошая защита от копипастинга. Конечно я постараюсь разобраться в смысле кода, а потом уже и напильником и шкуркой. По любому рахмет, ой это ж по казахски... спасибо :)


 
Ega23 ©   (2008-06-25 12:38) [17]


> У тебя получилась хорошая защита от копипастинга.


Не, можно конечно брать и пользоваться, но я это дело "под себя" точил. Тебе может всего и не нужно совсем.


 
123-ий ©   (2008-06-25 12:54) [18]

Панятно. будем разбираться :)


 
Loginov Dmitry ©   (2008-06-25 12:59) [19]


> Как лучше организовать сабж? В том смысле, какими методами
> его лучше читать и писАть в него каку-либо инфу?


Пример надежной записи в лог здесь:
http://matrix.kladovka.net.ru/download.php?getfilename=uploads/other/ldslogger.zip


 
stas ©   (2008-06-25 13:01) [20]

Ega23 ©   (25.06.08 12:24) [15]
пишут, ошибка не возникает. O_O.
Ок, попытаюсь разобраться.


 
stas ©   (2008-06-25 13:22) [21]

Ega23 ©   (25.06.08 12:24) [15]
возникала такая ошибка когда я вyenhb функции LogWrite, открывал потом закрывал файл, когда сделал f глобальной переменной и открываю файл один раз, эти проблемы ушли.


 
Игорь Шевченко ©   (2008-06-25 13:29) [22]


> Эй! Ты смотри, это всего только заготовка...  :) Её ещё
> тщательно "напильником" обрабатывать надо...  :)


точнее выкинуть


 
123-ий ©   (2008-06-26 07:54) [23]


> Игорь Шевченко ©   (25.06.08 13:29) [22]

а что так невесело?


 
123-ий ©   (2008-06-26 10:50) [24]


> Ega23 ©   (25.06.08 11:39) [2]
а чтение лога? у тебя ж только запись... или ты чтение вообще не делал
?


 
Ega23 ©   (2008-06-26 10:54) [25]


> или ты чтение вообще не делал


А нафига мне чтение??? Если чё, мне заказчик этот лог вышлет. А я уже там сам в блокноте разберусь...  :)))


 
Игорь Шевченко ©   (2008-06-26 21:01) [26]


> а что так невесело?


сам посмотри на код


 
Германн ©   (2008-06-26 21:34) [27]

4 года назад тут Панов выкладывал код для ведения лога на ~400 строк кода.
:-)


 
123-ий ©   (2008-06-27 08:29) [28]

фигасе. А мне чтение нужно шобы в программу содержимое выводить. Лана, буду сам додумывать. :)


 
Anatoly Podgoretsky ©   (2008-06-27 08:38) [29]


> 4 года назад тут Панов выкладывал код для ведения лога на
> ~400 строк кода.

Он схалтурил, ему лень было полный код писать.


 
@!!ex ©   (2008-06-27 09:28) [30]

Я один такой не модный, что у меня 10 строчек логирование? :\
Оно правда на С++, но ниче умного нет на дельфи переделать. Работает мгновенно, даже если сообщения валятся пачками.

static osal::cFile* s_Log;

void loger::Init(const std::string FileName)
{
s_Log = new osal::cFile(FileName,osal::WRITE);
};

void loger::Finish()
{
delete s_Log;
};

void loger::Add(const std::string Text)
{
osal::PrintInConsole(Text+"\n");
s_Log->WriteText(Text);
s_Log->Flush();
};


 
@!!ex ©   (2008-06-27 09:28) [31]

правда тут не многопоточное действо.


 
Поросенок Винни-Пух ©   (2008-06-27 09:36) [32]

unit LogUnit;

interface

procedure Log(const AMsg : string; const AParam : string = "");

implementation

uses Classes, SysUtils,SyncObjs;

var LogName:string;
   cs : TCriticalSection = nil;

procedure Log(const AMsg : string; const AParam : string = "");
var F:Text;
begin
cs.Enter;
Assign(F,LogName);
try
 if FileExists(LogName) then Append(F) else Rewrite(F);
 Writeln(F,FormatDateTime("dd.mm.yyyy hh:mm:ss",Now),#9,AMsg,#9,AParam);
finally
 Close(F);
 cs.Leave;
end;
end;

initialization
cs := TCriticalSection.Create;
LogName:=ChangeFileExt(ParamStr(0),".log");
finalization
cs.Free;
end.


 
Тын-Дын ©   (2008-06-27 11:08) [33]

А во всех этих пример и реализациях нагрузочное многопоточное тестирование проводилось?


 
Поросенок Винни-Пух ©   (2008-06-27 11:09) [34]

не только тестирование, но и многолетняя эксплуатация


 
Тын-Дын ©   (2008-06-27 11:26) [35]


> Поросенок Винни-Пух ©   (27.06.08 11:09) [34]
> не только тестирование, но и многолетняя эксплуатация


Ну и как с нагрузкой?
Сколько записей в секунду выдерживает и время реакции(время начала/конца обращения к процедуре?).


 
Поросенок Винни-Пух ©   (2008-06-27 11:30) [36]

Сколько записей в секунду выдерживает

это важно, если стоит задача быстрого наполнения лога все равно чем.
у меня такой задачи нет, лог используется по прямому назначению.


 
Тын-Дын ©   (2008-06-27 11:32) [37]


> Поросенок Винни-Пух ©   (27.06.08 11:30) [36]
> Сколько записей в секунду выдерживает
>
> это важно, если стоит задача быстрого наполнения лога все
> равно чем.


Неверно.
Есть задачи с большим потоком обработки данных, и операции нужно протоколировать, не мешая основной задаче.
Это и есть прямое назначение.


 
Поросенок Винни-Пух ©   (2008-06-27 11:33) [38]

в одном из фрагментов сегодняшнего лога нашел 21 запись в течении одной секунды. наверное было бы больше, если бы логируемая операция содержала больше шагов.


 
Поросенок Винни-Пух ©   (2008-06-27 11:34) [39]

У меня не мешает.


 
Поросенок Винни-Пух ©   (2008-06-27 11:36) [40]

Есть задачи с большим потоком обработки данных, и операции нужно протоколировать, не мешая основной задаче.
Это и есть прямое назначение.


И каким образом спрошенное у меня количество записей в секунду может что-то сказать про это?


 
Игорь Шевченко ©   (2008-06-27 11:42) [41]


> И каким образом спрошенное у меня количество записей в секунду
> может что-то сказать про это?


повод померяться...


 
Игорь Шевченко ©   (2008-06-27 11:47) [42]


> А во всех этих пример и реализациях нагрузочное многопоточное
> тестирование проводилось?


На свете существуют разные задачи.


 
Anatoly Podgoretsky ©   (2008-06-27 11:48) [43]

> Поросенок Винни-Пух  (27.06.2008 11:33:38)  [38]

for I := 1 to N do Log(IntToStr(I));


 
Тын-Дын ©   (2008-06-27 12:07) [44]


> Поросенок Винни-Пух ©   (27.06.08 11:36) [40]
> Есть задачи с большим потоком обработки данных, и операции
> нужно протоколировать, не мешая основной задаче.
> Это и есть прямое назначение.
>
> И каким образом спрошенное у меня количество записей в секунду
> может что-то сказать про это?


Отвеченное количество может помочь оценить эффективность реализации.
Странно, что такой простой вопрос в тупик ставит.


> Игорь Шевченко ©   (27.06.08 11:47) [42]
>
> > А во всех этих пример и реализациях нагрузочное многопоточное
>
> > тестирование проводилось?
>
>
> На свете существуют разные задачи


Совершенно верно.


> Поросенок Винни-Пух ©   (27.06.08 11:34) [39]
> У меня не мешает.


см. [42]

Нет, так нет.
Значит, не возникали подобные задачи.


 
Поросенок Винни-Пух ©   (2008-06-27 12:11) [45]

Отвеченное количество может помочь оценить эффективность реализации.
Странно, что такой простой вопрос в тупик ставит.


Ну давай, зацени.
Логируются не вычисления в памяти, а обращения к бд, криптографические операции и прочее, само по себе затратное по времени, все это прерывается ожиданиями сервера окончания интеракитвых фаз на клиенте.

Число записей в секунду - 21.
Оцени хоть что-нибудь.


 
Тын-Дын ©   (2008-06-27 12:27) [46]


> Поросенок Винни-Пух ©   (27.06.08 12:11) [45]
> Отвеченное количество может помочь оценить эффективность
> реализации.
> Странно, что такой простой вопрос в тупик ставит.
>
> Ну давай, зацени.
> Логируются не вычисления в памяти, а обращения к бд, криптографические
> операции и прочее, само по себе затратное по времени, все
> это прерывается ожиданиями сервера окончания интеракитвых
> фаз на клиенте.
>
> Число записей в секунду - 21.
> Оцени хоть что-нибудь.


Число обращений к функции протоколирования 21 ни о чем не говорит.
Вот если бы ты обращался 1000 раз в секунду к функции записи в журнал из нескольких потоков, тогда можно было бы оценить с замерами в каждом потоке количества обращений и замером количества строк, записанных в журнал за единицу времени.


 
Поросенок Винни-Пух ©   (2008-06-27 13:28) [47]

Удалено модератором


 
Поросенок Винни-Пух ©   (2008-06-27 13:30) [48]

Удалено модератором


 
Тын-Дын ©   (2008-06-27 13:45) [49]

Удалено модератором


 
Поросенок Винни-Пух ©   (2008-06-27 13:45) [50]

Удалено модератором


 
Тын-Дын ©   (2008-06-27 13:46) [51]

Удалено модератором


 
Поросенок Винни-Пух ©   (2008-06-27 13:46) [52]

Удалено модератором


 
Тын-Дын ©   (2008-06-27 13:48) [53]

Удалено модератором


 
Тын-Дын ©   (2008-06-27 13:49) [54]

Удалено модератором


 
Поросенок Винни-Пух ©   (2008-06-27 13:53) [55]

Ну что же еще остается, если твоей крутой реализации лога мы все равно здесь не увидим.

Спорим, что не увидим?
А если увидим, то ничего сколько нибудь отличного по производительности и надежности там не будет.

спорим?!


 
Тын-Дын ©   (2008-06-27 14:06) [56]

Удалено модератором


 
Поросенок Винни-Пух ©   (2008-06-27 14:07) [57]

Удалено модератором


 
@!!ex ©   (2008-06-27 14:13) [58]

> [35] Тын-Дын ©   (27.06.08 11:26)
>
> > Поросенок Винни-Пух ©   (27.06.08 11:09) [34]
> > не только тестирование, но и многолетняя эксплуатация
>
>
> Ну и как с нагрузкой?
> Сколько записей в секунду выдерживает и время реакции(время
> начала/конца обращения к процедуре?).

за 30 секунд 80 мегабайт лога, без видимого падения ФПС.


 
@!!ex ©   (2008-06-27 14:15) [59]

Правда в один поток.


 
Игорь Шевченко ©   (2008-06-27 14:15) [60]

Поросенок Винни-Пух ©   (27.06.08 13:53) [55]


> спорим?!


people may not see the difference


 
Поросенок Винни-Пух ©   (2008-06-27 14:22) [61]

people may not see the difference

Не, ну объясните мотивы персонажа.
Кто-то просто привет модуль без коментариев.
Рисуется перец, который ехидно страшивает, типа ну и скока там у вас?
Ему в ответ: а зачем тебе и что ты по ответу можешь сказать?
Он: - мне это поможет оценить всякую хрень.
Я - на, оценивай.
Он: мне количество обращений нифига не говорит, а ты не понтуйся.

Каково, а?


 
Игорь Шевченко ©   (2008-06-27 14:37) [62]

завязываем с оффтопиком. можно вполне предметно побеседовать в чате - для чего-то его тут сделали ?


 
Тын-Дын ©   (2008-06-28 01:40) [63]


> Поросенок Винни-Пух ©   (27.06.08 14:22) [61]
> people may not see the differenceНе, ну объясните мотивы
> персонажа.Кто-то просто привет модуль без коментариев.Рисуется
> перец, который ехидно страшивает, типа ну и скока там у
> вас?Ему в ответ: а зачем тебе и что ты по ответу можешь
> сказать?Он: - мне это поможет оценить всякую хрень.Я - на,
>  оценивай.Он: мне количество обращений нифига не говорит,
>  а ты не понтуйся.Каково, а?


Для крутых перцев:
Вот реализация ведения протокола: http://89.223.39.99/files/threadlog.zip

Тестовый пример:

uses
 uThreadLog;

type
TThrPing=class(TThread)
private
 FHost: String;
 FLog: TThreadLog;
protected
 procedure Execute; override;
public
 constructor Create(Host: String; Log: TThreadLog);
end;

implementation

{ TThrPing }

constructor TThrPing.Create(Host: String; Log: TThreadLog);
begin
 inherited Create(True);
 FreeOnTerminate := True;
 FHost := Host;
 FLog := Log;
 Resume;
end;

procedure TThrPing.Execute;
var
 s: String;
 i: Integer;
 dt: Cardinal;
begin
 dt := GetTickCount;
 for i := 0 to 100000 do
 begin
   s := FormatDateTime("hh:nn:ss  ",now)+ IntToStr(ThreadId)+"("+IntToStr(i)+"):"+StringOfChar("a",50);
   FLog.Add(s);
   if (i>0) and ((i mod 10000)=0) then
   begin
     MessageBox(0,PChar(IntTOStr(GetTickCount-dt)),"",MB_OK);
     Exit;
   end;
 end;
end;

//Тест1
procedure TForm1.Button1Click(Sender: TObject);
var
 Log1: TThreadLog;
begin
Log1 := TThreadLog.Create("c:\Log1","c:\ArchLog",100);
Log1.Start;
          TThrPing.Create("127.0.0.1",Log1);
          TThrPing.Create("127.0.0.2",Log1);
          TThrPing.Create("127.0.0.3",Log1);
end;

//Тест2
procedure TForm1.Button2Click(Sender: TObject);
var
 s: String;
 i: Integer;
 dt: Cardinal;
begin
 dt := GEtTickCount;
 for i := 0 to 100000 do
 begin
   s := FormatDateTime("hh:nn:ss  ",now)+ "qqqq"+"("+IntToStr(i)+"):"+StringOfChar("a",31);
   Log(s);
   if (i>0) and ((i mod 10000)=0) then
   begin
     MEssageBox(0,PChar(IntTOStr(GetTickCount-dt)),"",MB_OK);
     Exit;
   end;
 end;
end;

//Тест3
procedure TForm1.Button3Click(Sender: TObject);
var
 ld: TLDSLogger;
 s: String;
 i: Integer;
 dt: Cardinal;
begin
 ld := TLDSLogger.Create("c:\lds.log");
 dt := GEtTickCount;
 for i := 0 to 100000 do
 begin
   s := FormatDateTime("hh:nn:ss  ",now)+ "qqqq"+"("+IntToStr(i)+"):"+StringOfChar("a",31);
   ld.LogStr(s);
   if (i>0) and ((i mod 10000)=0) then
   begin
     MEssageBox(0,PChar(IntTOStr(GetTickCount-dt)),"",MB_OK);
     Exit;
   end;
 end;
 ld.Free;
end;

Время выполнения:
Тест1(Запись из 3х потоков) ~ 328-400мс
Тест2(Запись из 1 потока)    ~ 1203-1359мс
Тест3(Запись из 1 потока)    ~ 1172-1395мс


В LDS хорошая функциональность. При обычных требованиях к ведению журнала - отлично сделанная вещь.


 
Тын-Дын ©   (2008-06-28 01:42) [64]

PS.
Тест1 - Тын-Дын
Тест2 - Поросенок Винни-Пух
Тест3 - Loginov Dmitry



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

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

Наверх




Память: 0.65 MB
Время: 0.018 c
2-1214387731
Aggressor
2008-06-25 13:55
2008.07.27
WinXP rus, WinXP eng и кириллица


2-1214278389
АндрейК
2008-06-24 07:33
2008.07.27
работа с ecxel: ошибка Lock file has grown too large


6-1190980794
HaJik
2007-09-28 15:59
2008.07.27
IndyTCPClien Заменить сообщение об ошибке.


2-1214288805
Sergey2
2008-06-24 10:26
2008.07.27
Нажатие кнопки мыши.


2-1214480489
lewka-serdceed
2008-06-26 15:41
2008.07.27
Поиск слова в строке