1

这是一个条目的样子:

Jan 26 20:53:31 hostname logger: System rebooted for hard disk upgrade

我正在编写一个小应用程序来解析这样的条目并将格式良好的消息通过电子邮件发送给管理员。我正在用 Perl 编写并找到了 split() 函数,这正是我正在寻找的:

my @tmp = split(/ /, $string, 4);
@tmp = {$date, $hostname, $facility, $message)

这就是我希望得到的。Split() 可以处理 $message 部分中的空格,因为我限制了要拆分的“单词”的数量。但是, $date 部分中的空格会将其丢弃。有没有一种干净的方法可以让这些变量代表它们应该表达的意思?

我知道我可以使用 substr() 来获取前 15 个字符(日期),然后使用 split() 并将其限制为 3 个单词而不是 4 个,然后从那里获取我所有的字符串。但是有没有更优雅的方法来做到这一点?

4

4 回答 4

4

如果单行对优雅很重要,请在后面不跟数字的空格上分割:

my ( $time, $hostname, $facility, $message ) = split /\s+(?=\D)/, $string, 4;

但是结合使用splitunpack解决需求更有意义:

my ( $timeStamp, $log ) = unpack 'A15 A*', $string;

my ( $host, $facility, $msg ) = split /\s+/, $log;
于 2011-08-08T13:39:56.067 回答
3

Parse::Syslog是否可以在没有 i-try-this-regexp-oh-it-does-not-work-ok-i-hcanged-and-it-works-oh-not-always-hmm-let 的情况下满足您的需求-me-try-that-better-better-yay-oh-no-it-broke-let-me-try-this-one-has-nobody-done-this-yet 感觉?

于 2012-12-03T12:53:22.913 回答
1

使用正则表达式。这是一个简单的例子:

$mystring = "Jan 26 20:53:31 hostname logger: System rebooted for hard disk upgrade";
if($mystring =~ m/(\w{3}\s+\d{1,2}\s\d{2}:\d{2}:\d{2})\s([^\s]*)\s([^\s:]*):\s(.*$)/) {
    $date=$1;
    $host=$2;
    $facility=$3;
    $mesg=$4;
    print "Date: $date\nHost: $host\nFacility: $facility\nMesg: $mesg";
}
于 2011-08-08T13:34:49.633 回答
1

老问题,但我遇到了类似的问题,并通过格式化我的系统日志消息进行了纠正(因此修改了 rsyslog.conf)

我创建了 rsyslog 模板如下

template(name="CustomisedTemplate" type="list") {
    property(name="timestamp")
    constant(value=" ")
    property(name="$year")
    constant(value=";")
    property(name="hostname")
    constant(value=";")
    property(name="programname")
    constant(value=";")
    property(name="msg" spifno1stsp="on")
    property(name="msg" droplastlf="on")
    constant(value="\n")
}

然后

我通过添加将我的自定义模板设置为默认模板

    $ActionFileDefaultTemplate CustomisedTemplate.

到 (r)syslog.conf

我还可以为我的程序(记录器)创建过滤器,它将使用程序(记录器)创建的模板和重定向消息来分隔文件。为此,我添加了

    if $programname contains "logger" then /var/logs/logger.err;CustomisedTemplate

到 (r)syslog.conf

所以最后我的系统日志条目看起来像

Jan 26 20:53:31 2016;hostname;logger:;System rebooted for hard disk upgrade

这很容易解析。

于 2017-07-24T11:36:51.357 回答