Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Парсер log файла


Автор: Krivoy 11.2.2008, 13:13
Уважаемые гуру JAVA!
Решив освоить JAVA попытался написать программу-парсер лога для своих админских нужд - структура проги проста до безобразия - в цикле читается лог файл, елочкой IFов выбирается нужные данные (если есть)regexpaми и заносятся в MySQL. Было вроде всё просто - пока не дошел до запуска программы в бесконечном цикле - вот кусок программы 
Код


try {

    in = new BufferedReader(new InputStreamReader(new FileInputStream("logfile")));
    boolean stopflag = true;
    while (stopflag) {
while (in.ready()) {
String s = in.readLine().toLowerCase();
и т.д.

И вроде бы всё хорошо - при появлении новых строк в файле они обрабатываются, но я заметил в top что программа есть 100% процвремени :(
  Или top показывает не правду (т.к. комп вроде даже и не тормозит (хотя 100 только на одном из ядер)), или есть какие то другие способы парсить новые строчки в файле, или в цикле добавить какой-нибудь wait(хотя тред у меня один), или все-таки запоминать последнюю прочитанную строку и через какое то время пытаться читать следующюю(тут программа заметно усложниться :( что не хотелось бы)???
Помогите кто чем может а? 

P.S. Сделайте скидку на начинающего - изучаю JAVA четвертую неделю только smile

Автор: LSD 11.2.2008, 13:28
Попробуй так:
Код

String s;
while((s = in.readLine()) != null)
{
....
}

Автор: Krivoy 11.2.2008, 15:16
Цитата(LSD @ 11.2.2008,  13:28)
Попробуй так:
Код

String s;
while((s = in.readLine()) != null)
{
....
}

Эээммм.... Может я что то не так обьяснил, но программа должна работать постоянно и при появлении новых строк в лог файле(они дописываются серваком в конец файла) проверять их и если что найдет заночить в базу, а сделав как рекомендовали она просто прошла файл и завершила работу :(

Можно ли ещё вариант а?

Автор: LSD 11.2.2008, 15:32
Ну тогда просто добавь внутрь цикла проверку, если прочитанная строка пустая или null, то:
Код

Thread.sleep(50);

Автор: Krivoy 11.2.2008, 16:01
Цитата(LSD @ 11.2.2008,  15:32)
Ну тогда просто добавь внутрь цикла проверку, если прочитанная строка пустая или null, то:
Код

Thread.sleep(50);

smile))
Спасибо за совет!
Просто я не обновил страницу - сам решил со sleepом попробовать - но поставил там от души - 1000 !
А что 50 хватит? А почему так разительно снизилась загрузка проца(буквально до 2%)? 

Автор: LSD 11.2.2008, 16:06
Там даже 1 хватило бы чтобы прилично снизить нагрузку, просто до этого твоя задача молотила пустой цикл не отдавая такты, а так она будет их отдавать. Большее значение конечно лучше (но до определённого предела, потом улучшения уже не будет), вопрос только в том, как часто надо проверять не добавились ли данные в лог.

Автор: Krivoy 11.2.2008, 16:40
Цитата(LSD @ 11.2.2008,  16:06)
Там даже 1 хватило бы чтобы прилично снизить нагрузку, просто до этого твоя задача молотила пустой цикл не отдавая такты, а так она будет их отдавать. Большее значение конечно лучше (но до определённого предела, потом улучшения уже не будет), вопрос только в том, как часто надо проверять не добавились ли данные в лог.

Упс - не написал - это лог почтового сервера - записи там добавляются ну штук 10 строк на одно письмо - загрузка моего сервера не большая - от силы по 2-3 сообщения в секунду в пике - 50 хватит?. Вот в связи с этим меня терзают смутные сомнения из-за не знания работы связки
Код

in = new BufferedReader(new InputStreamReader(new FileInputStream("/logfile")));
String s = in.readLine().toLowerCase();

Оно вроде как и Stream, но в свою очередь и Buffered и вот если гипотетически предположить ситуацию когда строки были добавлены, а тред находился в sleep что произойдёт? - не пропустит ли он эти строки? как добавляются они из stream в  buffered? Или когда обьект in создан система сама заботится о добавлении новых данных в буфер из потока? и при поступлении новой порции он(in) становится ready?
 
  Извините за такое количество вопросов, просто схема работы readLine больше походит на типа что то getLine (т.е. readLine а потом deleteLine) и в моем понимании строка в буфере должна остаться - просто увеличится счётчик читаемой строки, а она там по ходу удаляется из буфера, или я не прав?(поправьте пожалуйста).

Автор: LSD 11.2.2008, 17:03
Цитата(Krivoy @  11.2.2008,  16:40 Найти цитируемый пост)
Упс - не написал - это лог почтового сервера - записи там добавляются ну штук 10 строк на одно письмо - загрузка моего сервера не большая - от силы по 2-3 сообщения в секунду в пике - 50 хватит?

Если ты будешь засыпать только когда новых сообщений нет (т.е. s - null), то можно даже увеличить до 250. Думаю 4 раза в секунду проверять не поступили ли новые сообщения вполне нормально.


Цитата(Krivoy @  11.2.2008,  16:40 Найти цитируемый пост)
Оно вроде как и Stream, но в свою очередь и Buffered и вот если гипотетически предположить ситуацию когда строки были добавлены, а тред находился в sleep что произойдёт? - не пропустит ли он эти строки? как добавляются они из stream в  buffered? Или когда обьект in создан система сама заботится о добавлении новых данных в буфер из потока? и при поступлении новой порции он(in) становится ready?

Буферизация делается средствами самой Java. Т.е. когда ты читаешь данные из потока, независимо от того сколько ты хочешь/готов прочесть, один байт или 100, BufferedReader читает некое заранее оговоренное число символов (по умолчанию 8к). Далее все чтение будет происходить из этого кеша, пока он не опустошиться. Никто в него символы не пихает. Он просто позволяет сократить число обращений к нижележащему потоку, если чтение происходит малыми порциями. Если читать из него большими кусками (несколько К), то смысла в нем нет.

Автор: Krivoy 12.2.2008, 09:04
Спасибо - всё стало ясно.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)