![]() |
|
Модераторы: korob2001, ginnie |
![]()
|
|
| box |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 506 Регистрация: 27.2.2007 Репутация: нет Всего: 0 |
есть текстовый файл с логом и мне ничего не стоит распарсить его и закидать в базу на примере :
но проблема в том что скрипт вызавается каждую минуту а лог обновляется по мере поступления данных , как реализовать что б скрипт записывал в базу только новые данные что поступили с момента прошлого обновления лога . и еще , лог может периодически обнулятся , тоесть файл просто удаляется и создается новый , пустой . в таком случае по мере поступления данных в лог тоже должно происходить дописывание в базу . |
|||
|
||||
| Egik2 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 302 Регистрация: 29.7.2008 Где: Агудзера Репутация: 1 Всего: 11 |
Если у тебя в логе есть временная метка, а если нет то лучше сделать
То как вариант могу предложить писать в какой-нить отдельный файл, дату записи, которую ты последнюю вставил в базу, а потом начинать с этой даты. -------------------- Три великие добродетели программиста: лень, нетерпение и самомнение (Larry Wall) a-nav.com developer-blog.ru world-poetry.org |
|||
|
||||
| arto |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1495 Регистрация: 31.10.2004 Репутация: 38 Всего: 40 |
perldoc File::Tail
Добавлено через 31 секунду или просто tail |
|||
|
||||
| box |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 506 Регистрация: 27.2.2007 Репутация: нет Всего: 0 |
дело в том что я спецом убрал временную метку из логов дабы урезать размер лога , да и время выполнения скрипта возрастет если я буду парсить временную мерку и сравнивать ее с записью из базы. а если лог будет 1-5 гигов то сервер то и будет делать что все время парсить логи. нужно както по другому . |
|||
|
||||
| klem4 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 100 Регистрация: 27.7.2008 Репутация: 2 Всего: 2 |
Не использовать временные метки - странное решение, но можно и без них решить Вашу задачу. Хранить (где угодно) кол-во строк лог-файла, при запуске скрипта сравнивать хранимую цифру с реальным кол-вом строк в логе, и если она меньше, парсить строки, номера которых больше хранимого индекса. Затем пересохранять индекс.
|
|||
|
||||
| box |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 506 Регистрация: 27.2.2007 Репутация: нет Всего: 0 |
а как быть если файл логов обнулен , тогда счетчик не поможет
|
|||
|
||||
| klem4 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 100 Регистрация: 27.7.2008 Репутация: 2 Всего: 2 |
обнулен файл, обнуляй и счетчик, не вижу в чем проблема.
|
|||
|
||||
| ramus |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 53 Регистрация: 21.2.2008 Репутация: 1 Всего: 1 |
0) Лог не содержащий время - не лог
1) Если лог размером 1-5 гига, то предложение "при запуске скрипта сравнивать хранимую цифру с реальным кол-вом строк в логе" ОЧЕНЬ сильно нагрузит бессмысленной работой сервер (надо читать 1-5 гигов одного и того же файла при каждом запуске программы) 2) Вам рекомендовал уважаемый arto команду tail - это правильное решение. 3) если же хочется реализовать самому, то посмотрите команды seek и tell. Идея такова: Когда Ваша программа в первый раз дочитает лог до конца (с записью в БД распарсенных значений), надо в конце файла вывод команды tell сохранить для следующего запуска вашей программы(в БД или в файле). При следующем запуске вы зачитываете последнее сохраненное значение и встаете на эту позицию файла лога командой seek, пропустив уже отпарсенное. Команда seek работает почти мгновенно, почти не зависит от размера файла и практически не нагружает сервер. Опять читаете лог до конца файла с записью в БД распарсенных значений и записываете новое значение tell в БД или файл. Узнать, что файл лога отрезался можно сравнив размер зачитанный из БД и реальный размер файла лога. Если реальный размер меньше, то наверняка файл отрезался. При этом Ваша программа должна читать файл с начала. Правда могут быть нюансы если запуски программы реже чем отрезки файла лога. Если Ваша программа должна работать ТОЛЬКО на UNIX(Linux) я бы для этого кроме размера проверял бы еще i-node файла, так как имя лога обычно бывает одно и тоже, а меняется только сам файл, т.е. i-node. |
|||
|
||||
| klem4 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 100 Регистрация: 27.7.2008 Репутация: 2 Всего: 2 |
Никогда не слышали про замечательную команду wc ? На логе 300+mb, wc -l Отрабатывает менее чем за 1 секунду. |
|||
|
||||
| ramus |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 53 Регистрация: 21.2.2008 Репутация: 1 Всего: 1 |
Кстати, а что за БД используется Вами? Она поддерживает переменные привязки (bind)?
Я бы на месте админа БД убил бы эту сессию вместе с разработчиком такой проги ;) Если БД - ORACLE, то код while(<LOG>){ my ($ip_temp, $host_temp, $string_temp) = split(/\|/, $_); $query = "INSERT INTO log (ip, host, string) VALUES ('".$ip_temp."', '".$host_temp."', '".$string_temp."')"; $query_handle = $connect->prepare($query); $query_handle->execute(); } очень быстро забьет sql area сервера БД, понизив тем самым общую производительность сервера код должен быть таким (примерно, я не проверял): my $query = "INSERT INTO log (ip, host, string) VALUES (?, ?, ?)"; $query_handle = $connect->prepare($query); while(<LOG>){ my ($ip_temp, $host_temp, $string_temp) = split(/\|/, $_); $query_handle->execute($ip_temp, $host_temp, $string_temp); } |
|||
|
||||
| klem4 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 100 Регистрация: 27.7.2008 Репутация: 2 Всего: 2 |
К моему последнему сообщению: на логе 1.2G результат более плачевный. Так что если файлы большие то вариант мой действительно не проходит.
|
|||
|
||||
| ramus |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 53 Регистрация: 21.2.2008 Репутация: 1 Всего: 1 |
На логе 300+mb, wc -l Отрабатывает менее чем за 1 секунду.
Забавно А знаете что она (wc) реально делает? Это говорит, что либо файл уже в кеше, либо сервер ОЧЕНЬ мощный (например дисковая система на внешнем массиве по FC), так как чтение 300MB/секунду это хорошо (естественно если ВЕСЬ сервер не в вашем распоряжении и на нем еще идет полезная работа) Я против загрузки сервера тупой работой. |
|||
|
||||
| box |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 506 Регистрация: 27.2.2007 Репутация: нет Всего: 0 |
да нет , не то это все и сервер ложится при использовании базы , не вывозит нагрузки уже при 10 метровом логе.хоть проц 2 ядра и рама 4 гига .
не вариант юзать базу данных в моем случае , а так хотелось ! |
|||
|
||||
| shamber |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1422 Регистрация: 5.9.2006 Где: Россия Репутация: 17 Всего: 18 |
box, а ложиться скорее всего из-за, того что Вам ramus написал по поводу prepare и execute
|
|||
|
||||
| Egik2 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 302 Регистрация: 29.7.2008 Где: Агудзера Репутация: 1 Всего: 11 |
А почему она должна ложиться? Я всегда думал, что prepare statement наоборот помогает, позволяет держать базе в кэше объект SQL statement, что избавляет от необходимости каждый раз парсить запрос. -------------------- Три великие добродетели программиста: лень, нетерпение и самомнение (Larry Wall) a-nav.com developer-blog.ru world-poetry.org |
|||
|
||||
![]()
|
| Правила форума "Perl" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |