用于解析的Perl程序结构

时间:2011-05-05 13:29:19

标签: linux perl parsing logging universal

我对程序架构有疑问。 假设您有100个不同格式的不同日志文件,您需要解析并将该信息放入SQL数据库。 我对此的看法如下:

  1. 使用通用配置文件,如:

    program1->name1("apache",/var/log/apache.log) (modulename,path to logfile1)
    program2->name2("exim",/var/log/exim.log) (modulename,path to logfile2)
    
    ....
    
    sqldb->configuration
    
  2. 使用类似模块的东西(每个程序1个文件)type1.module(regexp,logstructure(somevariables),sql(tables and functions))

  3. 不同程序的fork或thread进程(现在不知道Linux上哪些更好)。

  4. 所以问题是,我的观点是否正确?我应该为每个程序使用一个模块(web / MTA / iptablat) 还是有更好的方法?我认为一些正则表达式会是相同的,比如date / time / ip / url。怎么办?或者我错过了什么?


    示例:mta exim4 mainlog

      

    2011-04-28 13:16:24 1QFOGm-0005nQ-Ig   < = exim@mydomain.org.ua** H = localhost   (exim.mydomain.org.ua)   [127.0.0.1]:51127 I = [127.0.0.1]:465   P = esmtpsa   X = TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32   CV =否A = plain_server:垃圾邮件S = 763   id = 1303985784.4db93e788cb5c @ mydomain.org.ua T = “test”来自   <的 exim@exim.mydomain.org.ua >对于   的 test@domain.ua

    粗体的所有内容都已经过解析,并将被放入sqldb.incoming表中。现在我在perl中有结构来保存每个解析变量,如$exim->{timstamp} or $exim->{host}->{ip}

    我的程序将执行tail -f /file之类的操作并逐行解析

    灵活性:假设我想将supprot添加到apache服务器(只是时间戳userip和文件下载)。我需要知道要解析什么日志文件,什么是regexp应该是什么以及sql结构应该是什么。因此,我计划将此作为一个模块。只需使用参数(logfile,filetype)分叉或线程主进程。也许进一步我会添加一些不解析的选项(也许一些日志级别很低,你只是看不到mutch那里)

3 个答案:

答案 0 :(得分:0)

我会这样做:

  1. 创建一个格式如下的配置文件:appname:logpath:logformatname
  2. 创建一个从基础解析器类继承的Perl类的集合。
  3. 编写一个加载配置文件的脚本,然后遍历其内容,将每次迭代传递给相应的处理程序对象。
  4. 如果您想要步骤1和2的示例,我们有一个on our project。请参阅MT :: FileMgr和MT :: FileMgr :: * here

答案 1 :(得分:0)

日志监控工具wots可以为您做很多繁重的工作。它作为守护进程运行,观察尽可能多的日志文件,运行perl正则表达式的任意组合,并在找到匹配项时执行某些操作。

我倾向于修改wots本身(其许可证允许自由允许)以支持数据库写入方法 - 查看其现有的handle_*方法。

大部分艰苦工作已经为你完成,你可以解决有趣的问题。

答案 2 :(得分:0)

我认为File :: Tail非常适合。 您可以创建一个File :: Tail对象数组,并使用select这样调查它们:

   while (1) {
       ($nfound,$timeleft,@pending)=
         File::Tail::select(undef,undef,undef,$timeout,@files);
       unless ($nfound) {
              # timeout - do something else here, if you need to
       } else {
           foreach (@pending) {
                # here you can handle log messages depending on filename  
                print $_->{"input"}." (".localtime(time).") ".$_->read;
       }

(来自perl File :: Tail doc)