Форум: "Основная";
Текущий архив: 2014.02.16;
Скачать: [xml.tar.bz2];
ВнизМногопоточное логирование Найти похожие ветки
← →
Человек (2011-11-16 01:13) [0]Одновременно работает 20-30 потоков, переодически генерирующих события. Нужно записывать эти события в лог. Вариант, когда один поток ждет, пока файл освободится устроит, если это не приведет к зависанию всей системы.
Какими средствами лучше всего решить задачу? Есть ли простое решение, без копания в недрах WinAPI?
Может, подскажете готовые компоненты/классы? Задача же типичная, я уверен, много раз решалась.
← →
sniknik © (2011-11-16 01:22) [1]добавь еще один поток, на логирование, и все записывай из него. а с остальных данные на запись шли событиями (posttreadmessage).
и никаких синхронизаций не нужно будет, и последовательность лога "сама собой" делается.
← →
Германн © (2011-11-16 01:45) [2]Когда-то Саша Панов разрабатывал компонент для логгирования. Тут где-то даже его исходники лежат. Не знаю только доработал ли он свой компонент.
← →
Anatoly Podgoretsky © (2011-11-16 08:39) [3]> Германн (16.11.2011 01:45:02) [2]
Лежат в статьях, но если
даже не окончил, это все
равно база продолжения.
"Германн" сообщил/сообщила
в новостях следующее:
news:1321391616.2@delphimaster.ru...
Германн © (16.11.2011 01:45) [2]
Когда-то Саша Панов
разрабатывал компонент
для логгирования. Тут
где-то даже его исходники
лежат. Не знаю только
доработал ли он свой
компонент.
← →
Германн © (2011-11-16 08:45) [4]
> "Германн" сообщил/сообщила
> в новостях следующее:
:)))))
← →
Сергей М. © (2011-11-16 09:18) [5]
> Есть ли простое решение, без копания в недрах WinAPI?
Windows.OutputDebugString[A|W] - проще уже некуда
А вот и популярная приблуда для просмотра отладочного протокола, выводимого средствами OutputDebugString:
http://www.softpedia.com/progDownload/DebugView-Download-41081.html
← →
QAZ (2011-11-16 14:15) [6]Удалено модератором
← →
DVM © (2011-11-16 15:49) [7]
> Какими средствами лучше всего решить задачу? Есть ли простое
> решение, без копания в недрах WinAPI?
Критические секции
> Может, подскажете готовые компоненты/классы? Задача же типичная,
> я уверен, много раз решалась.
ИМХО самая правильная идеология логгирования - это Log4. Первоначально появилась в Java под названием Log4J потом была реализована и на других языках Log4Cxx, Log4Net. Есть и два варианта реализации для Delphi: Log4D и Log4Delphi. Оба проекта есть на Sourceforge и оба несколько заброшенные, что странно. Я доработал Log4D, сделал несколько доп модулей (ConsoleAppender, ColoredConsoleAppender, DailyRollingFileAppender и много других). Давно использую, нареканий нет.
Лучше использовать этот подход чем вечно изобретать свои велосипеды. Данный подход к логгированию максимально гибок. Надо только понять его.
← →
KilkennyCat © (2011-11-16 18:37) [8]
> Надо только понять его.
меня всегда такие заключения пугают и настораживают. все, хорошо, все очень просто, надо только понять...
← →
Sergey Masloff (2011-11-16 18:48) [9]
> меня всегда такие заключения пугают и настораживают. все,
> хорошо, все очень просто, надо только понять...
+1
и не могу понять чего может не хватать в OutputDebugString
← →
Дмитрий Белькевич (2011-11-16 20:00) [10]
> я испытываю "вау-эффект"
Нормально. У нас в программах бывает 50-60 в пике.
>если это не приведет к зависанию всей системы.
Системы - не приведет. А если приведет программы - значит написана криво и нужно править.
Сам пользую критическую секцию и пишу в локальный файл. Еще ни разу не подводила. Просто, дешево и надежно. Унутре секции - можно писать в файл или слать в порт, или еще что-то придумать.
← →
Eraser © (2011-11-16 21:43) [11]> [10] Дмитрий Белькевич (16.11.11 20:00)
одной крит. секции мало, нужен доп. поток, который будет писать в файл. обращение к буферу не дожно блокироваться файловой опирацией.
← →
DVM © (2011-11-16 22:28) [12]
> Eraser © (16.11.11 21:43) [11]
> обращение к буферу не дожно блокироваться файловой опирацией.
Ну, скажем так, в подавляющем большинстве случаев это незаметно. Для высоконагруженных серверов сброс данных в файл надо делать буферизованным и сбрасывать по мере заполнения буфера. Буферизация иногда в десятки раз снижает нагрузку на процессор.
> нужен доп. поток
Тут дело такое, что если поток не будет успевать сбрасывть данные на диск, то буфер переполнится, а если он успевает, то и поток не нужен. Не так ли?
← →
DVM © (2011-11-16 22:30) [13]
> KilkennyCat © (16.11.11 18:37) [8]
> все, хорошо, все очень просто, надо только понять...
Ну любую технологию надо понять, прежде чем использовать. Даже OutputDebugString.
← →
DVM © (2011-11-16 22:37) [14]
> Sergey Masloff (16.11.11 18:48) [9]
> и не могу понять чего может не хватать в OutputDebugString
OutputDebugString это не система логгирования. Это просто функция, отсылающая строку куда то там. Это функция для отладки, для програмиста. Но не для построения полноценной системы логгирования.
В сложных, многокомпонентных системах, особенно серверных, взаимодействующих с другими различными системами логи - это обязательная вещь. Не отладочные логи. А логи работы. Эти логи в первую очередь нужны поддержке, чтобы понимать, что не так в конфигурации системы или ее работе.
Такие логи должны быть гибкими. Ротация логов, вывод логов в разные места (файл, сеть, консоль, систеный лог, SysLog и т.д), уровни логгирования, фильтры и т.д. Все это позволяет быстро и своевременно локализовать проблему. Без участия программиста. На тему логгирования написана куча статей, нет смысла здесь все это повторять.
← →
DVM © (2011-11-16 22:43) [15]
> Дмитрий Белькевич (16.11.11 20:00) [10]
> Сам пользую критическую секцию и пишу в локальный файл.
> Еще ни разу не подводила. Просто, дешево и надежно. Унутре
> секции - можно писать в файл или слать в порт, или еще что-
> то придумать.
Раньше поступал аналогично. Был свой велосипед. Как говорится не программист тот, кто среди прочего не написал свою систему логгирования.
Вот и у меня был. Его постоянно приходилось подкручивать. Тут понадобилась ротация логов по дате, там по размеру, сям по по размеру и дате, где то лог надо было выволить в консоль, где то писать в базу, где то еще что. Потом я прочитал про Log4J и перешел на подобное.
← →
Loginov Dmitry © (2011-11-16 23:15) [16]
> > обращение к буферу не дожно блокироваться файловой опирацией.
>
>
> Ну, скажем так, в подавляющем большинстве случаев это незаметно.
> Для высоконагруженных серверов сброс данных в файл надо
> делать буферизованным и сбрасывать по мере заполнения буфера.
> Буферизация иногда в десятки раз снижает нагрузку на процессор.
>
>
>
> > нужен доп. поток
>
> Тут дело такое, что если поток не будет успевать сбрасывть
> данные на диск, то буфер переполнится, а если он успевает,
> то и поток не нужен. Не так ли?
Попадаются задачи, в которых неприемлемо ожидать, пока диск, заваленный кашперским, вновь раскрутиться до нужных оборотов. С кашперским запись всего одной строки в лог порой занимает до 50мс. А интенсивность записи в логи, возможно, не имеет значения, пусть даже 10 строк в минуту. Даже в этом случае отдельный поток - самое то. Ну и какой-то буфер должен быть, сохраняться на диск он может как при накоплении определенного объема, так и по прошествии заданного количества времени.
← →
DVM © (2011-11-17 00:16) [17]
> Loginov Dmitry © (16.11.11 23:15) [16]
> Попадаются задачи, в которых неприемлемо ожидать, пока диск,
> заваленный кашперским, вновь раскрутиться до нужных оборотов.
> С кашперским запись всего одной строки в лог порой занимает
> до 50мс.
Вообще то файловые операции могут быть и неблокирующими. Буфер создаст система. Но можно и свой, я уже писал.
← →
Германн © (2011-11-17 01:32) [18]
> Вообще то файловые операции могут быть и неблокирующими.
А как их "заставить" быть либо блокирующими, либо неблокирующими?
← →
Eraser © (2011-11-17 05:26) [19]> [12] DVM © (16.11.11 22:28)
> Тут дело такое, что если поток не будет успевать сбрасывть
> данные на диск
это ж сколько надо данных логировать )
← →
Eraser © (2011-11-17 05:28) [20]> [18] Германн © (17.11.11 01:32)
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365683(v=vs.85).aspx
← →
Romkin © (2011-11-17 17:12) [21]В Windows есть журналы, и ими довольно легко пользоваться.
ReportEvent и тд
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363654(v=VS.85).aspx
← →
Romkin © (2011-11-17 17:14) [22]А вот и в Delphi, это несложно
http://www.codenet.ru/progr/delphi/stat/Event-Log.php
← →
DVM © (2011-11-17 17:34) [23]
> Romkin © (17.11.11 17:14) [22]
У журнала есть только один недостаток. Чтобы туда вывести осмысленное сообщение, по хорошему надо линковать к исполняемому файлу или в свою dll строковые ресурсы сообщений в особом формате (готовится спец программой от MS), и регистрировать ее в реестре, что несколько неудобно.
← →
Дмитрий Белькевич (2011-11-18 08:33) [24]
> Попадаются задачи, в которых неприемлемо ожидать, пока диск,
> заваленный кашперским, вновь раскрутиться до нужных оборотов.
>
Важно помнить: Windows is not a real-time operating system. Остальное приложится.
← →
Loginov Dmitry © (2011-11-22 21:00) [25]
> Важно помнить: Windows is not a real-time operating system.
> Остальное приложится.
Да, это не система реального времени. Но не смотря на это, ситуация, когда каждая строка в лог-файл пишется по 50мс - не приемлема. Всему должен быть предел, даже при "not a real-time".
Если пользователь кликает на кнопку, а программа при этом минуту виснет, вычисляя "2+2", не будем же мы ему объяснять, что это не мы виноваты, это все ваш "not a real-time operating system".
← →
DVM © (2011-11-22 22:22) [26]
> Loginov Dmitry © (22.11.11 21:00) [25]
> Но не смотря на это, ситуация, когда каждая строка в лог-
> файл пишется по 50мс - не приемлема.
Ну не по 20 допустим. А вообще то буферизацию надо использовать, сбрасывать на диск порциями и никакие потоки доп не нужны. Хотя кому нравится может и использовать, только как я уже сказал, если мы не успеваем сбрасывать лог на диск (или это сильно тормозит работу) без потока, то и поток тут не поможет, т.к он точно также не будет успевать и его буфер в памяти переполнится.
Я бы гораздо больше внимания уделял не сбросу на диск в самопальных логгерах, а механизму ротации, который иногда реализован ну не в красную армию. При каждой записи дергается куча функций, проверяющих дату, время, списки файлов, подлежащих ротации и т.д. Это отнимает ресурсов больше, чем запись.
Или вот еще распространенная ошибка. Пусть допустим есть логгер с уровнями логгирования. И допустим есть метод Log(Level: TLevel; s: string). Многие пишут так: Log(Debug, Format(sMessage, [param....paramN]). Если уровень логгирования выше, чем Debug, то функция формат все равно будет вызываться и тормозить работу. А всего лишь, надо было в методе Log делать проверку на уровень и лишь потом вызывать Format уже внутри метода, в который передавать строку форматирования и параметры. И таких косяков в самопальных логгерах навалом. А вы тут заботитесь о микросекундах для сброса данных на диск.
> Всему должен быть предел
И занимаемой оперативной памяти тоже.
← →
Человек (2011-11-27 06:30) [27]Всем спасибо за дискуссию. DVM особенно. Библиотека Log4Delphi подошла идеально.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2014.02.16;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.004 c