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

Вниз

Многопоточное логирование   Найти похожие ветки 

 
Человек   (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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.007 c
15-1377798356
Никонов Сергей
2013-08-29 21:45
2014.02.16
Глюки аппаратные проблемы или ошибки программистов?


1-1321391616
Человек
2011-11-16 01:13
2014.02.16
Многопоточное логирование


2-1365850104
Катерина
2013-04-13 14:48
2014.02.16
Чтение из файла в ComboBox


15-1377900392
картман
2013-08-31 02:06
2014.02.16
широкий монитор...


2-1365768017
__
2013-04-12 16:00
2014.02.16
Что может быть с системой если после int 3 спасает только Reset