The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"именованные каналы(FIFO), проблема чтения"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"именованные каналы(FIFO), проблема чтения"  
Сообщение от cricket (ok) on 22-Мрт-08, 21:48 
Привет всем! Столкнулся с такой проблемой:
Имеется syslog-ng, который ловит логи от виндовой машины на udp порт. Затем я пытаюсь перенаправить их пайпом в perl скрипт, через обьект FIFO, предварительно созданный с помощью mkfifo(). Права на FIFO - rw у рута. syslog-ng и скрипт запускаются под rootом.

destination { pipe(/scripts/syslog-ng.pipe); };

На стороне скрипта, открываю FIFO на чтение функцией open.

open($hLog, '<', '/scripts/syslog-ng.pipe');

Затем пытаюсь парсить полученые строки и запихивать в базу. Примерно так...
while(<$hLog>)
{
  #обработка текущей строки $_
  #Запись в базу...
}
Скрипт ругается на не верный SQL запрос!
После того как я перед обработкой строки, вывожу ее в STDOUT, все начинает работать без проблем. Строки базы успешно добавляются.
while(<$hLog>)
{
  print $_; #!!!!
  #обработка текущей строки $_
  #Запись в базу...
}
Не могу понять в чем проблема, может в блокировке FIFO? Обьясните пожалуйста!
ЗЫ:Заранее благодарен.

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


2. "именованные каналы(FIFO), проблема чтения"  
Сообщение от angra (??) on 23-Мрт-08, 14:00 
Краткое содержание вашего поста: "у меня есть некая херня, она не работает, херню я вам не покажу, но ошибку пожалуйста найдите".
Вы ошиблись, уважаемый, форум телепатов не здесь.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "именованные каналы(FIFO), проблема чтения"  
Сообщение от cricket (ok) on 23-Мрт-08, 16:04 
конфиг syslog-ng:

options {
        sync (0);
        time_reopen (10);
        log_fifo_size (1000);
        long_hostnames (off);
        use_dns (no);
        use_fqdn (no);
        create_dirs (no);
        keep_hostname (yes);
};

source ext_logger {
        unix-stream ("/dev/log");
        udp( ip(xxx.xxx.xxx.xxx) port(xxxx));
        internal();
};

destination my_wks { fifo("/logs/scripts/syslog-ng.pipe"); };


log { source(ext_logger); destination(my_wks); flags(final); };

;---------------------------------------------------------------------
скрипт:

#!/usr/bin/perl

my $Pipe='/logs/scripts/syslog-ng.pipe';

use DBI;

my $hLog; #Log file handle
my $dbTable='xxxx'; #Name of dBase Table
my $date=''; #Event date
my $time=''; #Event time
my $user=''; #User
my $code=''; #Event code
my $addr=''; #host ip
%month = ('Jan'=>'01', 'Feb'=>'02', 'Mar'=>'03', 'Apr'=>'04', 'May'=>'05', 'Jun'=>'06', 'Jul'=>'07', 'Aug'=>'08', 'Sep'=>'09', 'Oct'=>'10'
, 'Nov'=>'11', 'Dec'=>'12'); #Month hash

#----------------------------------------------------------------
my $dBase=DBI->connect("dbi:mysql:dbname=xxxxx;host=xxxxx","xxxxxx","xxxxx");

open($hLog, '<', $Pipe) or die("Open Error");

while(<$hLog>)
{
  if($_=~/(\S{3})\s?(\d{2})\s?(\d{2}\:?\d{2}\:?\d{2})\s?(\d{4})\s+(\d{3})\s+\S+\s+(\S+)/)
    {
     # $1=month $2=day $3=time $4=year $5=code $6=user_name
     $date=$4.'-'.$month{$1}.'-'.$2;
     $time=$3;
     $user=$6;
     $code=$5;
    }
  if(substr($user,-1,1) eq '$')
   {
    $addr=$user;
    chop($addr);
   }
  elsif($_=~/(\d+\.{1}){3}\d+/)  # $& - ip addr
   {
    $addr=$&;
   }

  $dBase->do("insert into ".$dbTable." (date,time,user,ip,code) values ('".$date."','".$time."','".$user."','".$addr."',".$code.");");
  $date, $time, $user, $code, $addr='';
}

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "именованные каналы(FIFO), проблема чтения"  
Сообщение от angra (??) on 24-Мрт-08, 02:13 
Попросите кого-нибудь переписать этот скрипт. Вы делаете одну из самых грубых ошибок в программировании - инициализация переменных внутри блока условия и использование их за пределами этого блока. Как следствие всегда есть шанс, что часть переменных придет пустыми(это в перле, в С, например, они будут иметь произвольные значения) и значит запрос будет некорректным. Вторая ошибка чуть более высокого уровня - всегда надежней использовать параметризованные запросы через prepare+execute, чем самому загонять переменные в строку, это избавит от целого ряда проблем. Также есть неточности в регексах и корявый синтаксис, но это мелочи.  
По поводу изменения поведения при print, могу лишь предположить что почему-то нарушается считывание по границе \n и print это как то исправляет, может из-за задержки с выводом, надо нормально поотлаживать, чтобы сказать наверняка. Однако в любом случае проблема в неправильном коде, он исключительно неустойчив.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "именованные каналы(FIFO), проблема чтения"  
Сообщение от cricket (ok) on 24-Мрт-08, 10:12 
>[оверквотинг удален]
>переменных придет пустыми(это в перле, в С, например, они будут иметь
>произвольные значения) и значит запрос будет некорректным. Вторая ошибка чуть более
>высокого уровня - всегда надежней использовать параметризованные запросы через prepare+execute, чем
>самому загонять переменные в строку, это избавит от целого ряда проблем.
>Также есть неточности в регексах и корявый синтаксис, но это мелочи.
>
>По поводу изменения поведения при print, могу лишь предположить что почему-то нарушается
>считывание по границе \n и print это как то исправляет, может
>из-за задержки с выводом, надо нормально поотлаживать, чтобы сказать наверняка. Однако
>в любом случае проблема в неправильном коде, он исключительно неустойчив.

Прошу прощения, а где Вы нашли обьявление переменных внутри блока условия и использование их за пределами блока? Все переменные обьявляются и инициализируются вверху по тексту программы. Дело в том что когда я скармливаю скрипту файл, все прекрасно работает. Не каких пустых значений там нет.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "именованные каналы(FIFO), проблема чтения"  
Сообщение от angra (??) on 24-Мрт-08, 18:37 
Если вы не можете разобрать свой же код, то и не знаю чем помочь. Могу только предложить попробовать:
1. Попробуйте в консольном клиенте мускула запрос insert into some_table (date,code) values ('',)
2. perl -e '$a=1,$b=2; print "$a $b\n"; $a,$b="";print "$a $b\n";'

>Дело в том что когда я скармливаю скрипту файл, все прекрасно работает

Ваш код по своей сути неустойчив, он не способен адекватно реагировать на некорректные данные, что мы и наблюдаем. Если вы не хотите об этом задумываться и предпочитаете "быдлокодить", то это ваше право. Способ как решить проблему в лоб вы и сами нашли, разбираться в причинах вам неохота, так что же вы хотите?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "именованные каналы(FIFO), проблема чтения"  
Сообщение от bosschifra (??) on 26-Июн-08, 17:38 
а какой прогой вы загоняете логи винды на syslog ?????
неподелитесь?


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "именованные каналы(FIFO), проблема чтения"  
Сообщение от stas (??) on 24-Мрт-08, 10:47 
>[оверквотинг удален]
>    chop($addr);
>   }
>  elsif($_=~/(\d+\.{1}){3}\d+/)  # $& - ip addr
>   {
>    $addr=$&;
>   }
>
>  $dBase->do("insert into ".$dbTable." (date,time,user,ip,code) values ('".$date."','".$time."','".$user."','".$addr."',".$code.");");
>  $date, $time, $user, $code, $addr='';
> }

Вставьте перед строчкой
$dBase->do("insert into ".$dbTable." (date,time,user,ip,code) values ('".$date."','".$time."','".$user."','".$addr."',".$code.");");
оператор print, который будет выводит строку вашего запроса
print "insert into ".$dbTable." (date,time,user,ip,code) values ('".$date."','".$time."','".$user."','".$addr."',".$code.");";
И посмотрите, что с ней не так.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "именованные каналы(FIFO), проблема чтения"  
Сообщение от NuINu (??) on 28-Июн-08, 19:32 
добавлю к замечаниям

>while(<$hLog>)
> {
>  if($_=~/(\S{3})\s?(\d{2})\s?(\d{2}\:?\d{2}\:?\d{2})\s?(\d{4})\s+(\d{3})\s+\S+\s+(\S+)/)

вот это вот конструкция очень подозрительна
if($_ =~ /***/)

замените ее на:
while($in = <$hLog>) {
{
а вот здесь надо выствить значения переменных по умолчанию, иначе, в случае невыполнения if они у вас будут использоваться со значениями последного успешного предыдущего шага


if($in =~ m/***/)
и далее по тексту замените $_ на $in, либо посто уберите '$_ =~'

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Спонсоры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2022 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру