1

我对程序架构有疑问。假设您有 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(正则表达式、日志结构(某些变量)、sql(表和函数))

  3. 用于不同程序的 fork 或线程进程(不知道现在 Linux 上哪个更好)。

所以问题是,我对此的看法正确吗?我应该每个程序使用一个模块(web/MTA/iptablat)还是有更好的方法?我认为某些正则表达式是相同的,例如日期/时间/ip/url。那该怎么办?或者我错过了什么?


示例:mta exim4 主日志

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=no A=plain_server:spam S=763 id= 1303985784.4db93e788cb5c @mydomain.org.ua T= "test" from < exim@exim.mydomain。 org.ua > 用于 test@domain.ua

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

我的程序会做类似的事情tail -f /file 并逐行解析

灵活性:假设我想向 apache 服务器添加支持(只是时间戳 userip 和下载的文件)。我只需要知道要解析什么日志文件,应该是什么正则表达式以及应该是什么 sql 结构。所以我打算把它当作一个模块。只需使用参数(日志文件,文件类型)分叉或线程主进程。也许我会进一步添加一些不解析的选项(也许一些日志级别很低,你只是在那里看不到 mutch)

4

3 回答 3

0

我会这样做:

  1. 创建一个格式如下的配置文件:appname:logpath:logformatname
  2. 创建从基本解析器类继承的 Perl 类的集合。
  3. 编写一个脚本来加载配置文件,然后循环遍历其内容,将每次迭代传递给相应的处理程序对象。

如果您想要第 1 步和第 2 步的示例,我们的项目中有一个。请参阅此处的MT::FileMgr 和 MT::FileMgr::* 。

于 2011-05-05T14:57:28.227 回答
0

日志监控工具wots可以在这里为您完成很多繁重的工作。它作为守护进程运行,查看尽可能多的日志文件,在它们上运行任何 perl 正则表达式组合,并在找到匹配项时执行某些操作。

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

大部分艰苦的工作已经为您完成,您可以处理有趣的部分。

于 2011-05-06T01:19:29.227 回答
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)

于 2011-12-15T21:38:56.380 回答