Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »
Страницы: 1 2

Многопоточность. Запись логов


Игорь Шевченко ©   (31.10.17 10:35[20]

Eraser ©   (30.10.17 23:02) [19]


> могут появится огромные просадки в процедуре логирования,
>  сталкивался с таким


Я не сталкивался. Если кто протоколирует большой объем в файлах на диске, весьма разумно будет задать ему вопрос: а нафига ?

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

Что-то тут не так.


Eraser ©   (31.10.17 14:55[21]


> Игорь Шевченко ©   (31.10.17 10:35) [20]


> Если кто протоколирует большой объем в файлах на диске,
> весьма разумно будет задать ему вопрос: а нафига ?

Большой объем - понятие растяжимое. В моем случае это высоконагруженный сервер (около сотни тысяч одновременных соединений) на базе IOCP. Если в рабочем потоке использовать прямое логирование на диск, это дает серьезную деградацию производительности, если не подводит память, даже без антивируса. Собственно, это в любой статье по IOCP написано, что в рабочих потоках не должно быть блокирующих, на хоть сколько то заметное время вызовов, да и из здравого смысла это понятно. Даже если логировать исключительно только факт соединения. Представьте, когда одновременно нужно записать несколько десятков тысяч записей из 30 потоков, допустим, после перезапуска сервера.


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

не правильно заставлять юзеров что-то там настраивать. хотя, в моем случае, ПО не для сторонних юзеров.

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


Игорь Шевченко ©   (31.10.17 18:30[22]

Eraser ©   (31.10.17 14:55) [21]

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

Я в [18] говорил о некоем alert.log по образу и подобию Oracle, большое количество информации там может появится в случае какой-то отладочного вывода, но, тем не менее, все равно, тормозов я не наблюдал. Другие протоколы, штатные, пишутся отдельным процессом (а то и несколькими, в зависимости от нагрузки) в базу данных, в электронную почту и т.п., а не на диск. Но и там особо информации немного, потому что писать огромные логи лично я не вижу причины. Возможно, в каких-то задачах это и оправдано.
И еще раз - реализация зависит от задачи, нет тут серебряной пули.


Eraser ©   (31.10.17 22:25[23]


> Игорь Шевченко ©   (31.10.17 18:30) [22]

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

function InternalAppendLogToFile(const AMsg: string): Boolean;
var
 fText: TextFile;
 sFileName: string;
begin
 Result := False;

 try
   sFileName := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
   if not DirectoryExists(sFileName + 'Logs') then
     MkDir(sFileName + 'Logs');
   sFileName := sFileName + 'Logs\' + _sExeName + '_' + FormatDateTime('yyyy_mm', Now) +
     '_log.txt';
 except
   Exit;
 end;

 EnterCriticalSection(_csUniversalLog);
 try
   AssignFile(fText, sFileName);
   if FileExists(sFileName) then
     Append(fText)
   else
     Rewrite(fText);
   try
     Writeln(fText, AMsg);
   finally
     CloseFile(fText);
   end;

   Result := True;
 finally
   LeaveCriticalSection(_csUniversalLog);
 end;
end;

function AppendLog(const AMsg: string; AForceToFile: Boolean = False): Boolean;
var
 sText: string;
begin
 Result := False;

 sText := FormatDateTime('dd-mm-yyyy_hh:nn:ss:zzz', Now) + '#T:' + AMsg;
 OutputDebugString(PChar(sText));

 {$IFDEF USE_FILE}
 Result := InternalAppendLogToFile(sText);
 {$ENDIF}

 if (not Result) and AForceToFile then
   Result := InternalAppendLogToFile(sText);
end;


han_malign ©   (01.11.17 10:50[24]


> Собственно, это в любой статье по IOCP написано, что в рабочих
> потоках не должно быть блокирующих, на хоть сколько то заметное
> время вызовов

- в IOCP кстати есть неочевидный нюансик - зачем нужен параметр NumberOfConcurrentThreads, если можно просто не создавать лишних потоков:
- если количество активных потоков ассоциированных с одним портом уже NumberOfConcurrentThreads, но один из потоков переходит в режим ожидания не по причине GetQueuedCompletionStatus - например на ожидании другой I/O операции, то разблокируется еще один поток(в результате чего в некоторые моменты времени количество активных потоков может быть больше NumberOfConcurrentThreads)...

...
This is one reason to have your application create more threads in its thread pool than the concurrency value.


Alex Konshin ©   (03.12.17 21:27[25]

> Eraser ©   (31.10.17 14:55) [21]
Согласен, что такое иногда нужно и что неверное решение очень сильно (иногда на порядки) снижает производительность.
В таком случае логирование нужно делать в отдельном треде с входной очередью-буфером, которая либо синхронизирована, либо поддерживает асинхронное добавление без бликировки. Тред выбирает сообщения из очереди и пишет в выходной буфер. Буфер сбрасывается на диск при заполнении или после короткой задержки (чтоб не инициировалась запись слишком часто и мелкими порциями). Сама запись на диск может осуществляться либо ещё в одном отдельном треде или с помощью операций асинхроной записи.

Уже не помню, делал ли я так где-нибудь на Delphi, но на Java я точно такое реализовывал в нескольких проектах.


Дмитрий Белькевич ©   (03.12.17 23:04[26]


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


Антивирусы вообще редкие каки. Каких уж чудес я с ними не видел.

Немного в тему. У нас на одной из установок периодически установка атрибутов (FileSetAttr) вывешивает гуй, нашли с помощью эврики. Ладно бы еще запись в файл. Грешим, правда, скорее на виртуалку. Пришлось выносить в отдельный поток.


Игорь Шевченко ©   (04.12.17 10:31[27]

Alex Konshin ©   (03.12.17 21:27) [25]

Где-то я уже подобное читал...Ах да, в описании архитектуры Oracle :)
По-моему ценность протокола именно в актуальности информации на интересующий момент, поэтому отдельные очереди и прочие навороты - это для тех протоколов, которые никто не читает.

Дмитрий Белькевич ©   (03.12.17 23:04) [26]


> Антивирусы вообще редкие каки. Каких уж чудес я с ними не
> видел.


Чудеса - они с любыми программами возможны :) Начиная с Windows, которая, как известно, глючная по определению :)


Страницы: 1 2 версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо