解析系统日志条目

发布于 2024-11-28 11:21:49 字数 530 浏览 1 评论 0原文

这就是条目的样子:

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 个,然后从那里获取所有字符串。但有没有更优雅的方法来做到这一点?

This is what an entry looks like:

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

I'm writing a small application to parse entries like this and email a nicely formatted message to the admin. I'm writing in Perl and found the split() function which is exactly what I'm looking for:

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

That's what I'm hoping to get. Split() can handle the spaces in the $message part because I limit the amount of "words" to split off. However, the spaces in the $date part throw it off. Is there a clean way I can get these variables to represent what they're supposed to?

I know I could use substr() to grab the first 15 characters (the date), then use split() and limit it to 3 words instead of 4, then grab all my strings from there. But is there a more elegant way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

败给现实 2024-12-05 11:21:49

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

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

但使用 分割<代码>解压以满足需求:

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

my ( $host, $facility, $msg ) = split /\s+/, $log;

If one-lined-ness is important to elegance, split on spaces that are not followed by a digit:

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

But it makes more sense to use a combination of split and unpack to address the need:

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

my ( $host, $facility, $msg ) = split /\s+/, $log;
你是我的挚爱i 2024-12-05 11:21:49

Parse::Syslog 是否可以满足您的需要我-尝试-这个-正则表达式-哦-它-不工作-好的-我-hcanged-并且-它-工作-哦-不总是-嗯-让我-尝试-那-更好-是啊,哦,没有,它坏了,让我试试这个,还没有人做过这个,感觉吗?

Does Parse::Syslog do what you need without the i-try-this-regexp-oh-it-does-not-work-ok-i-hcanged-and-it-works-oh-not-always-hmm-let-me-try-that-much-better-yay-oh-no-it-broke-let-me-try-this-one-has-nobody-done-this-yet feeling?

自在安然 2024-12-05 11:21:49

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

$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";
}

Use a regex. Here is a simple example:

$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";
}
固执像三岁 2024-12-05 11:21:49

老问题,但我遇到了类似的问题,并通过格式化我的 syslog 消息(因此修改了 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

相当容易解析。

Old question, but I experienced similar problem and rectified by formatting of my syslog messages ( hence modified rsyslog.conf)

I created rsyslog template as follows

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")
}

then

I set my customised template as default by adding

    $ActionFileDefaultTemplate CustomisedTemplate.

to (r)syslog.conf

I could also create the filter for my program (logger), which will use template and redirect message created by program ( logger) to separate file. To achieve that, I added

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

to (r)syslog.conf

So at the end my syslog entry looks like

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

which is rather easy to parse.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文