Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
15-1377900392
картман
2013-08-31 02:06
2014.02.16
широкий монитор...


15-1378130372
Кристина
2013-09-02 17:59
2014.02.16
Странности Delphi 2010


15-1378133550
Степан Потапов
2013-09-02 18:52
2014.02.16
Кто переименовывает, а кто нет? (опрос)


2-1365088308
Афонтий
2013-04-04 19:11
2014.02.16
Copy String to Char Array


15-1377698945
aka
2013-08-28 18:09
2014.02.16
вопрос знатокам JavaSccript





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский