![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Многопоточное логирование
Человек © (2011-11-16 01:13:00)Одновременно работает 20-30 потоков, переодически генерирующих события. Нужно записывать эти события в лог. Вариант, когда один поток ждет, пока файл освободится устроит, если это не приведет к зависанию всей системы.
Какими средствами лучше всего решить задачу? Есть ли простое решение, без копания в недрах WinAPI?
Может, подскажете готовые компоненты/классы? Задача же типичная, я уверен, много раз решалась.
Человек (2011-11-27 06:30:00) [1]Всем спасибо за дискуссию. DVM особенно. Библиотека Log4Delphi подошла идеально.
DVM (2011-11-22 22:22:00) [2]
> Loginov Dmitry © (22.11.11 21:00) [25]
> Но не смотря на это, ситуация, когда каждая строка в лог-
> файл пишется по 50мс - не приемлема.
Ну не по 20 допустим. А вообще то буферизацию надо использовать, сбрасывать на диск порциями и никакие потоки доп не нужны. Хотя кому нравится может и использовать, только как я уже сказал, если мы не успеваем сбрасывать лог на диск (или это сильно тормозит работу) без потока, то и поток тут не поможет, т.к он точно также не будет успевать и его буфер в памяти переполнится.
Я бы гораздо больше внимания уделял не сбросу на диск в самопальных логгерах, а механизму ротации, который иногда реализован ну не в красную армию. При каждой записи дергается куча функций, проверяющих дату, время, списки файлов, подлежащих ротации и т.д. Это отнимает ресурсов больше, чем запись.
Или вот еще распространенная ошибка. Пусть допустим есть логгер с уровнями логгирования. И допустим есть метод Log(Level: TLevel; s: string). Многие пишут так: Log(Debug, Format(sMessage, [param....paramN]). Если уровень логгирования выше, чем Debug, то функция формат все равно будет вызываться и тормозить работу. А всего лишь, надо было в методе Log делать проверку на уровень и лишь потом вызывать Format уже внутри метода, в который передавать строку форматирования и параметры. И таких косяков в самопальных логгерах навалом. А вы тут заботитесь о микросекундах для сброса данных на диск.
> Всему должен быть предел
И занимаемой оперативной памяти тоже.
Loginov Dmitry (2011-11-22 21:00:00) [3]
> Важно помнить: Windows is not a real-time operating system.
> Остальное приложится.
Да, это не система реального времени. Но не смотря на это, ситуация, когда каждая строка в лог-файл пишется по 50мс - не приемлема. Всему должен быть предел, даже при "not a real-time".
Если пользователь кликает на кнопку, а программа при этом минуту виснет, вычисляя "2+2", не будем же мы ему объяснять, что это не мы виноваты, это все ваш "not a real-time operating system".
Дмитрий Белькевич (2011-11-18 08:33:00) [4]
> Попадаются задачи, в которых неприемлемо ожидать, пока диск,
> заваленный кашперским, вновь раскрутиться до нужных оборотов.
>
Важно помнить: Windows is not a real-time operating system. Остальное приложится.
DVM (2011-11-17 17:34:00) [5]
> Romkin © (17.11.11 17:14) [22]
У журнала есть только один недостаток. Чтобы туда вывести осмысленное сообщение, по хорошему надо линковать к исполняемому файлу или в свою dll строковые ресурсы сообщений в особом формате (готовится спец программой от MS), и регистрировать ее в реестре, что несколько неудобно.
Romkin (2011-11-17 17:14:00) [6]А вот и в Delphi, это несложно
http://www.codenet.ru/progr/delphi/stat/Event-Log.php
Romkin (2011-11-17 17:12:00) [7]В Windows есть журналы, и ими довольно легко пользоваться.
ReportEvent и тд
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363654(v=VS.85).aspx
Eraser (2011-11-17 05:28:00) [8]> [18] Германн © (17.11.11 01:32)
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365683(v=vs.85).aspx
Eraser (2011-11-17 05:26:00) [9]> [12] DVM © (16.11.11 22:28)
> Тут дело такое, что если поток не будет успевать сбрасывть
> данные на диск
это ж сколько надо данных логировать )
Германн (2011-11-17 01:32:00) [10]
> Вообще то файловые операции могут быть и неблокирующими.
А как их "заставить" быть либо блокирующими, либо неблокирующими?
DVM (2011-11-17 00:16:00) [11]
> Loginov Dmitry © (16.11.11 23:15) [16]
> Попадаются задачи, в которых неприемлемо ожидать, пока диск,
> заваленный кашперским, вновь раскрутиться до нужных оборотов.
> С кашперским запись всего одной строки в лог порой занимает
> до 50мс.
Вообще то файловые операции могут быть и неблокирующими. Буфер создаст система. Но можно и свой, я уже писал.
Loginov Dmitry (2011-11-16 23:15:00) [12]
> > обращение к буферу не дожно блокироваться файловой опирацией.
>
>
> Ну, скажем так, в подавляющем большинстве случаев это незаметно.
> Для высоконагруженных серверов сброс данных в файл надо
> делать буферизованным и сбрасывать по мере заполнения буфера.
> Буферизация иногда в десятки раз снижает нагрузку на процессор.
>
>
>
> > нужен доп. поток
>
> Тут дело такое, что если поток не будет успевать сбрасывть
> данные на диск, то буфер переполнится, а если он успевает,
> то и поток не нужен. Не так ли?
Попадаются задачи, в которых неприемлемо ожидать, пока диск, заваленный кашперским, вновь раскрутиться до нужных оборотов. С кашперским запись всего одной строки в лог порой занимает до 50мс. А интенсивность записи в логи, возможно, не имеет значения, пусть даже 10 строк в минуту. Даже в этом случае отдельный поток - самое то. Ну и какой-то буфер должен быть, сохраняться на диск он может как при накоплении определенного объема, так и по прошествии заданного количества времени.
DVM (2011-11-16 22:43:00) [13]
> Дмитрий Белькевич (16.11.11 20:00) [10]
> Сам пользую критическую секцию и пишу в локальный файл.
> Еще ни разу не подводила. Просто, дешево и надежно. Унутре
> секции - можно писать в файл или слать в порт, или еще что-
> то придумать.
Раньше поступал аналогично. Был свой велосипед. Как говорится не программист тот, кто среди прочего не написал свою систему логгирования.
Вот и у меня был. Его постоянно приходилось подкручивать. Тут понадобилась ротация логов по дате, там по размеру, сям по по размеру и дате, где то лог надо было выволить в консоль, где то писать в базу, где то еще что. Потом я прочитал про Log4J и перешел на подобное.
DVM (2011-11-16 22:37:00) [14]
> Sergey Masloff (16.11.11 18:48) [9]
> и не могу понять чего может не хватать в OutputDebugString
OutputDebugString это не система логгирования. Это просто функция, отсылающая строку куда то там. Это функция для отладки, для програмиста. Но не для построения полноценной системы логгирования.
В сложных, многокомпонентных системах, особенно серверных, взаимодействующих с другими различными системами логи - это обязательная вещь. Не отладочные логи. А логи работы. Эти логи в первую очередь нужны поддержке, чтобы понимать, что не так в конфигурации системы или ее работе.
Такие логи должны быть гибкими. Ротация логов, вывод логов в разные места (файл, сеть, консоль, систеный лог, SysLog и т.д), уровни логгирования, фильтры и т.д. Все это позволяет быстро и своевременно локализовать проблему. Без участия программиста. На тему логгирования написана куча статей, нет смысла здесь все это повторять.
DVM (2011-11-16 22:30:00) [15]
> KilkennyCat © (16.11.11 18:37) [8]
> все, хорошо, все очень просто, надо только понять...
Ну любую технологию надо понять, прежде чем использовать. Даже OutputDebugString.
DVM (2011-11-16 22:28:00) [16]
> Eraser © (16.11.11 21:43) [11]
> обращение к буферу не дожно блокироваться файловой опирацией.
Ну, скажем так, в подавляющем большинстве случаев это незаметно. Для высоконагруженных серверов сброс данных в файл надо делать буферизованным и сбрасывать по мере заполнения буфера. Буферизация иногда в десятки раз снижает нагрузку на процессор.
> нужен доп. поток
Тут дело такое, что если поток не будет успевать сбрасывть данные на диск, то буфер переполнится, а если он успевает, то и поток не нужен. Не так ли?
Eraser (2011-11-16 21:43:00) [17]> [10] Дмитрий Белькевич (16.11.11 20:00)
одной крит. секции мало, нужен доп. поток, который будет писать в файл. обращение к буферу не дожно блокироваться файловой опирацией.
Дмитрий Белькевич (2011-11-16 20:00:00) [18]
> я испытываю "вау-эффект"
Нормально. У нас в программах бывает 50-60 в пике.
>если это не приведет к зависанию всей системы.
Системы - не приведет. А если приведет программы - значит написана криво и нужно править.
Сам пользую критическую секцию и пишу в локальный файл. Еще ни разу не подводила. Просто, дешево и надежно. Унутре секции - можно писать в файл или слать в порт, или еще что-то придумать.
Sergey Masloff (2011-11-16 18:48:00) [19]
> меня всегда такие заключения пугают и настораживают. все,
> хорошо, все очень просто, надо только понять...
+1
и не могу понять чего может не хватать в OutputDebugString
KilkennyCat (2011-11-16 18:37:00) [20]
> Надо только понять его.
меня всегда такие заключения пугают и настораживают. все, хорошо, все очень просто, надо только понять...