Форум: "Начинающим";
Текущий архив: 2008.07.27;
Скачать: [xml.tar.bz2];
ВнизРабота с логами Найти похожие ветки
← →
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
лог пишем WriteLogunit 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;
Скачать: [xml.tar.bz2];
Память: 0.63 MB
Время: 0.008 c